Add MatrixClientPeg::safeGet and use it in tests (#10985)

This commit is contained in:
Michael Telatynski 2023-06-05 18:12:23 +01:00 committed by GitHub
parent c47b587225
commit 6b46d6e4f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
88 changed files with 290 additions and 226 deletions

View File

@ -38,7 +38,7 @@ import { crossSigningCallbacks, tryToUnlockSecretStorageWithDehydrationKey } fro
import SecurityCustomisations from "./customisations/Security";
import { SlidingSyncManager } from "./SlidingSyncManager";
import CryptoStoreTooNewDialog from "./components/views/dialogs/CryptoStoreTooNewDialog";
import { _t } from "./languageHandler";
import { _t, UserFriendlyError } from "./languageHandler";
import { SettingLevel } from "./settings/SettingLevel";
import MatrixClientBackedController from "./settings/controllers/MatrixClientBackedController";
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
@ -49,7 +49,7 @@ export interface IMatrixClientCreds {
identityServerUrl?: string;
userId: string;
deviceId?: string;
accessToken: string;
accessToken?: string;
guest?: boolean;
pickleKey?: string;
freshLogin?: boolean;
@ -71,9 +71,10 @@ export interface IMatrixClientPeg {
*
* @returns {string} The homeserver name, if present.
*/
getHomeserverName(): string;
getHomeserverName(): string | null;
get(): MatrixClient;
safeGet(): MatrixClient;
unset(): void;
assign(): Promise<any>;
start(): Promise<any>;
@ -134,7 +135,7 @@ class MatrixClientPegClass implements IMatrixClientPeg {
initialSyncLimit: 20,
};
private matrixClient: MatrixClient = null;
private matrixClient: MatrixClient | null = null;
private justRegisteredUserId: string | null = null;
// the credentials used to init the current client object.
@ -145,6 +146,13 @@ class MatrixClientPegClass implements IMatrixClientPeg {
return this.matrixClient;
}
public safeGet(): MatrixClient {
if (!this.matrixClient) {
throw new UserFriendlyError("User is not logged in");
}
return this.matrixClient;
}
public unset(): void {
this.matrixClient = null;
@ -215,6 +223,10 @@ class MatrixClientPegClass implements IMatrixClientPeg {
};
public async assign(): Promise<any> {
if (!this.matrixClient) {
throw new Error("createClient must be called first");
}
for (const dbType of ["indexeddb", "memory"]) {
try {
const promise = this.matrixClient.store.startup();
@ -275,6 +287,10 @@ class MatrixClientPegClass implements IMatrixClientPeg {
* Attempt to initialize the crypto layer on a newly-created MatrixClient
*/
private async initClientCrypto(): Promise<void> {
if (!this.matrixClient) {
throw new Error("createClient must be called first");
}
const useRustCrypto = SettingsStore.getValue("feature_rust_crypto");
// we want to make sure that the same crypto implementation is used throughout the lifetime of a device,
@ -317,11 +333,15 @@ class MatrixClientPegClass implements IMatrixClientPeg {
const opts = await this.assign();
logger.log(`MatrixClientPeg: really starting MatrixClient`);
await this.get().startClient(opts);
await this.matrixClient!.startClient(opts);
logger.log(`MatrixClientPeg: MatrixClient started`);
}
public getCredentials(): IMatrixClientCreds {
if (!this.matrixClient) {
throw new Error("createClient must be called first");
}
let copiedCredentials: IMatrixClientCreds | null = this.currentClientCreds;
if (this.currentClientCreds?.userId !== this.matrixClient?.credentials?.userId) {
// cached credentials belong to a different user - don't use them
@ -335,12 +355,14 @@ class MatrixClientPegClass implements IMatrixClientPeg {
identityServerUrl: this.matrixClient.idBaseUrl,
userId: this.matrixClient.getSafeUserId(),
deviceId: this.matrixClient.getDeviceId() ?? undefined,
accessToken: this.matrixClient.getAccessToken(),
accessToken: this.matrixClient.getAccessToken() ?? undefined,
guest: this.matrixClient.isGuest(),
};
}
public getHomeserverName(): string {
public getHomeserverName(): string | null {
if (!this.matrixClient) return null;
const matches = /^@[^:]+:(.+)$/.exec(this.matrixClient.getSafeUserId());
if (matches === null || matches.length < 1) {
throw new Error("Failed to derive homeserver name from user ID!");

View File

@ -91,7 +91,7 @@ const msgTypeHandlers: Record<string, (event: MatrixEvent) => string | null> = {
return null;
}
return TextForEvent.textForEvent(event);
return TextForEvent.textForEvent(event, MatrixClientPeg.get());
},
};
@ -111,7 +111,7 @@ class NotifierClass {
if (msgType && msgTypeHandlers.hasOwnProperty(msgType)) {
return msgTypeHandlers[msgType](ev);
}
return TextForEvent.textForEvent(ev);
return TextForEvent.textForEvent(ev, MatrixClientPeg.get());
}
// XXX: exported for tests

View File

@ -22,6 +22,7 @@ import { GuestAccess, HistoryVisibility, JoinRule } from "matrix-js-sdk/src/@typ
import { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
import { M_POLL_START, M_POLL_END } from "matrix-js-sdk/src/@types/polls";
import { PollStartEvent } from "matrix-js-sdk/src/extensible_events_v1/PollStartEvent";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { _t } from "./languageHandler";
import * as Roles from "./Roles";
@ -31,7 +32,6 @@ import { ALL_RULE_TYPES, ROOM_RULE_TYPES, SERVER_RULE_TYPES, USER_RULE_TYPES } f
import { WIDGET_LAYOUT_EVENT_TYPE } from "./stores/widgets/WidgetLayoutStore";
import { RightPanelPhases } from "./stores/right-panel/RightPanelStorePhases";
import defaultDispatcher from "./dispatcher/dispatcher";
import { MatrixClientPeg } from "./MatrixClientPeg";
import { RoomSettingsTab } from "./components/views/dialogs/RoomSettingsDialog";
import AccessibleButton, { ButtonEvent } from "./components/views/elements/AccessibleButton";
import RightPanelStore from "./stores/right-panel/RightPanelStore";
@ -40,16 +40,15 @@ import { ElementCall } from "./models/Call";
import { textForVoiceBroadcastStoppedEvent, VoiceBroadcastInfoEventType } from "./voice-broadcast";
import { getSenderName } from "./utils/event/getSenderName";
function getRoomMemberDisplayname(event: MatrixEvent, userId = event.getSender()): string {
const client = MatrixClientPeg.get();
function getRoomMemberDisplayname(client: MatrixClient, event: MatrixEvent, userId = event.getSender()): string {
const roomId = event.getRoomId();
const member = client.getRoom(roomId)?.getMember(userId!);
return member?.name || member?.rawDisplayName || userId || _t("Someone");
}
function textForCallEvent(event: MatrixEvent): () => string {
const roomName = MatrixClientPeg.get().getRoom(event.getRoomId()!)?.name;
const isSupported = MatrixClientPeg.get().supportsVoip();
function textForCallEvent(event: MatrixEvent, client: MatrixClient): () => string {
const roomName = client.getRoom(event.getRoomId()!)?.name;
const isSupported = client.supportsVoip();
return isSupported
? () => _t("Video call started in %(roomName)s.", { roomName })
@ -60,11 +59,11 @@ function textForCallEvent(event: MatrixEvent): () => string {
// any text to display at all. For this reason they return deferred values
// to avoid the expense of looking up translations when they're not needed.
function textForCallInviteEvent(event: MatrixEvent): (() => string) | null {
function textForCallInviteEvent(event: MatrixEvent, client: MatrixClient): (() => string) | null {
const senderName = getSenderName(event);
// FIXME: Find a better way to determine this from the event?
const isVoice = !event.getContent().offer?.sdp?.includes("m=video");
const isSupported = MatrixClientPeg.get().supportsVoip();
const isSupported = client.supportsVoip();
// This ladder could be reduced down to a couple string variables, however other languages
// can have a hard time translating those strings. In an effort to make translations easier
@ -103,10 +102,15 @@ function getModification(prev?: string, value?: string): Modification {
return Modification.None;
}
function textForMemberEvent(ev: MatrixEvent, allowJSX: boolean, showHiddenEvents?: boolean): (() => string) | null {
function textForMemberEvent(
ev: MatrixEvent,
client: MatrixClient,
allowJSX: boolean,
showHiddenEvents?: boolean,
): (() => string) | null {
// XXX: SYJS-16 "sender is sometimes null for join messages"
const senderName = ev.sender?.name || getRoomMemberDisplayname(ev);
const targetName = ev.target?.name || getRoomMemberDisplayname(ev, ev.getStateKey());
const senderName = ev.sender?.name || getRoomMemberDisplayname(client, ev);
const targetName = ev.target?.name || getRoomMemberDisplayname(client, ev, ev.getStateKey());
const prevContent = ev.getPrevContent();
const content = ev.getContent();
const reason = content.reason;
@ -269,7 +273,7 @@ const onViewJoinRuleSettingsClick = (): void => {
});
};
function textForJoinRulesEvent(ev: MatrixEvent, allowJSX: boolean): () => Renderable {
function textForJoinRulesEvent(ev: MatrixEvent, client: MatrixClient, allowJSX: boolean): () => Renderable {
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
switch (ev.getContent().join_rule) {
case JoinRule.Public:
@ -361,7 +365,7 @@ function textForServerACLEvent(ev: MatrixEvent): (() => string) | null {
return getText;
}
function textForMessageEvent(ev: MatrixEvent): (() => string) | null {
function textForMessageEvent(ev: MatrixEvent, client: MatrixClient): (() => string) | null {
if (isLocationEvent(ev)) {
return textForLocationEvent(ev);
}
@ -370,7 +374,7 @@ function textForMessageEvent(ev: MatrixEvent): (() => string) | null {
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
let message = ev.getContent().body;
if (ev.isRedacted()) {
message = textForRedactedPollAndMessageEvent(ev);
message = textForRedactedPollAndMessageEvent(ev, client);
}
if (ev.getContent().msgtype === MsgType.Emote) {
@ -496,7 +500,7 @@ function textForHistoryVisibilityEvent(event: MatrixEvent): (() => string) | nul
}
// Currently will only display a change if a user's power level is changed
function textForPowerEvent(event: MatrixEvent): (() => string) | null {
function textForPowerEvent(event: MatrixEvent, client: MatrixClient): (() => string) | null {
const senderName = getSenderName(event);
if (!event.getPrevContent()?.users || !event.getContent()?.users) {
return null;
@ -533,7 +537,7 @@ function textForPowerEvent(event: MatrixEvent): (() => string) | null {
return;
}
if (to !== from) {
const name = getRoomMemberDisplayname(event, userId);
const name = getRoomMemberDisplayname(client, event, userId);
diffs.push({ userId, name, from, to });
}
});
@ -561,7 +565,7 @@ const onPinnedMessagesClick = (): void => {
RightPanelStore.instance.setCard({ phase: RightPanelPhases.PinnedMessages }, false);
};
function textForPinnedEvent(event: MatrixEvent, allowJSX: boolean): (() => Renderable) | null {
function textForPinnedEvent(event: MatrixEvent, client: MatrixClient, allowJSX: boolean): (() => Renderable) | null {
if (!SettingsStore.getValue("feature_pinning")) return null;
const senderName = getSenderName(event);
const roomId = event.getRoomId()!;
@ -835,12 +839,12 @@ export function textForLocationEvent(event: MatrixEvent): () => string {
});
}
function textForRedactedPollAndMessageEvent(ev: MatrixEvent): string {
function textForRedactedPollAndMessageEvent(ev: MatrixEvent, client: MatrixClient): string {
let message = _t("Message deleted");
const unsigned = ev.getUnsigned();
const redactedBecauseUserId = unsigned?.redacted_because?.sender;
if (redactedBecauseUserId && redactedBecauseUserId !== ev.getSender()) {
const room = MatrixClientPeg.get().getRoom(ev.getRoomId());
const room = client.getRoom(ev.getRoomId());
const sender = room?.getMember(redactedBecauseUserId);
message = _t("Message deleted by %(name)s", {
name: sender?.name || redactedBecauseUserId,
@ -850,12 +854,12 @@ function textForRedactedPollAndMessageEvent(ev: MatrixEvent): string {
return message;
}
function textForPollStartEvent(event: MatrixEvent): (() => string) | null {
function textForPollStartEvent(event: MatrixEvent, client: MatrixClient): (() => string) | null {
return () => {
let message = "";
if (event.isRedacted()) {
message = textForRedactedPollAndMessageEvent(event);
message = textForRedactedPollAndMessageEvent(event, client);
const senderDisplayName = event.sender?.name ?? event.getSender();
message = senderDisplayName + ": " + message;
} else {
@ -879,7 +883,12 @@ function textForPollEndEvent(event: MatrixEvent): (() => string) | null {
type Renderable = string | React.ReactNode | null;
interface IHandlers {
[type: string]: (ev: MatrixEvent, allowJSX: boolean, showHiddenEvents?: boolean) => (() => Renderable) | null;
[type: string]: (
ev: MatrixEvent,
client: MatrixClient,
allowJSX: boolean,
showHiddenEvents?: boolean,
) => (() => Renderable) | null;
}
const handlers: IHandlers = {
@ -925,25 +934,39 @@ for (const evType of ElementCall.CALL_EVENT_TYPE.names) {
/**
* Determines whether the given event has text to display.
*
* @param client The Matrix Client instance for the logged-in user
* @param ev The event
* @param showHiddenEvents An optional cached setting value for showHiddenEventsInTimeline
* to avoid hitting the settings store
*/
export function hasText(ev: MatrixEvent, showHiddenEvents?: boolean): boolean {
export function hasText(ev: MatrixEvent, client: MatrixClient, showHiddenEvents?: boolean): boolean {
const handler = (ev.isState() ? stateHandlers : handlers)[ev.getType()];
return Boolean(handler?.(ev, false, showHiddenEvents));
return Boolean(handler?.(ev, client, false, showHiddenEvents));
}
/**
* Gets the textual content of the given event.
*
* @param ev The event
* @param client The Matrix Client instance for the logged-in user
* @param allowJSX Whether to output rich JSX content
* @param showHiddenEvents An optional cached setting value for showHiddenEventsInTimeline
* to avoid hitting the settings store
*/
export function textForEvent(ev: MatrixEvent): string;
export function textForEvent(ev: MatrixEvent, allowJSX: true, showHiddenEvents?: boolean): string | React.ReactNode;
export function textForEvent(ev: MatrixEvent, allowJSX = false, showHiddenEvents?: boolean): string | React.ReactNode {
export function textForEvent(ev: MatrixEvent, client: MatrixClient): string;
export function textForEvent(
ev: MatrixEvent,
client: MatrixClient,
allowJSX: true,
showHiddenEvents?: boolean,
): string | React.ReactNode;
export function textForEvent(
ev: MatrixEvent,
client: MatrixClient,
allowJSX = false,
showHiddenEvents?: boolean,
): string | React.ReactNode {
const handler = (ev.isState() ? stateHandlers : handlers)[ev.getType()];
return handler?.(ev, allowJSX, showHiddenEvents)?.() || "";
return handler?.(ev, client, allowJSX, showHiddenEvents)?.() || "";
}

View File

@ -1301,7 +1301,7 @@ class MainGrouper extends BaseGrouper {
public add({ event: ev, shouldShow }: EventAndShouldShow): void {
if (ev.getType() === EventType.RoomMember) {
// We can ignore any events that don't actually have a message to display
if (!hasText(ev, this.panel.showHiddenEvents)) return;
if (!hasText(ev, MatrixClientPeg.get(), this.panel.showHiddenEvents)) return;
}
this.readMarker = this.readMarker || this.panel.readMarkerForEvent(ev.getId()!, ev === this.lastShownEvent);
if (!this.panel.showHiddenEvents && !shouldShow) {

View File

@ -20,7 +20,7 @@ import { M_TEXT } from "matrix-js-sdk/src/@types/extensible_events";
import { logger } from "matrix-js-sdk/src/logger";
import { Icon as PollIcon } from "../../../../res/img/element-icons/room/composer/poll.svg";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import MatrixClientContext, { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
import { _t } from "../../../languageHandler";
import { textForEvent } from "../../../TextForEvent";
import { Caption } from "../typography/Caption";
@ -95,10 +95,11 @@ const usePollStartEvent = (event: MatrixEvent): { pollStartEvent?: MatrixEvent;
};
export const MPollEndBody = React.forwardRef<any, IBodyProps>(({ mxEvent, ...props }, ref) => {
const cli = useMatrixClientContext();
const { pollStartEvent, isLoadingPollStartEvent } = usePollStartEvent(mxEvent);
if (!pollStartEvent) {
const pollEndFallbackMessage = M_TEXT.findIn(mxEvent.getContent()) || textForEvent(mxEvent);
const pollEndFallbackMessage = M_TEXT.findIn(mxEvent.getContent()) || textForEvent(mxEvent, cli);
return (
<>
<PollIcon className="mx_MPollEndBody_icon" />

View File

@ -19,6 +19,7 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import RoomContext from "../../../contexts/RoomContext";
import * as TextForEvent from "../../../TextForEvent";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
interface IProps {
mxEvent: MatrixEvent;
@ -28,7 +29,12 @@ export default class TextualEvent extends React.Component<IProps> {
public static contextType = RoomContext;
public render(): React.ReactNode {
const text = TextForEvent.textForEvent(this.props.mxEvent, true, this.context?.showHiddenEvents);
const text = TextForEvent.textForEvent(
this.props.mxEvent,
MatrixClientPeg.get(),
true,
this.context?.showHiddenEvents,
);
if (!text) return null;
return <div className="mx_TextualEvent">{text}</div>;
}

View File

@ -255,7 +255,7 @@ export function pickFactory(
return noEventFactoryFactory(); // improper event type to render
}
if (STATE_EVENT_TILE_TYPES.get(evType) === TextualEventFactory && !hasText(mxEvent, showHiddenEvents)) {
if (STATE_EVENT_TILE_TYPES.get(evType) === TextualEventFactory && !hasText(mxEvent, cli, showHiddenEvents)) {
return noEventFactoryFactory();
}
@ -435,7 +435,7 @@ export function haveRendererForEvent(mxEvent: MatrixEvent, showHiddenEvents: boo
const handler = pickFactory(mxEvent, cli, showHiddenEvents);
if (!handler) return false;
if (handler === TextualEventFactory) {
return hasText(mxEvent, showHiddenEvents);
return hasText(mxEvent, cli, showHiddenEvents);
} else if (handler === STATE_EVENT_TILE_TYPES.get(EventType.RoomCreate)) {
const dynamicPredecessorsEnabled = SettingsStore.getValue("feature_dynamic_room_predecessors");
const predecessor = cli.getRoom(mxEvent.getRoomId())?.findPredecessor(dynamicPredecessorsEnabled);

View File

@ -104,6 +104,7 @@
"We couldn't log you in": "We couldn't log you in",
"We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.",
"Try again": "Try again",
"User is not logged in": "User is not logged in",
"Database unexpectedly closed": "Database unexpectedly closed",
"This may be caused by having the app open in multiple tabs or due to clearing browser data.": "This may be caused by having the app open in multiple tabs or due to clearing browser data.",
"Reload": "Reload",

View File

@ -402,7 +402,7 @@ export default class HTMLExporter extends Exporter {
// TODO: Handle callEvent errors
logger.error(e);
eventTile = await this.getEventTileMarkup(
this.createModifiedEvent(textForEvent(mxEv), mxEv, false),
this.createModifiedEvent(textForEvent(mxEv, this.room.client), mxEv, false),
joined,
);
}

View File

@ -104,7 +104,7 @@ export default class PlainTextExporter extends Exporter {
} else mediaText = ` (${this.mediaOmitText})`;
}
if (this.isReply(mxEv)) return senderDisplayName + ": " + this.textForReplyEvent(mxEv.getContent()) + mediaText;
else return textForEvent(mxEv) + mediaText;
else return textForEvent(mxEv, this.room.client) + mediaText;
};
protected async createOutput(events: MatrixEvent[]): Promise<string> {

View File

@ -15,7 +15,7 @@ limitations under the License.
*/
import React, { ReactNode } from "react";
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import AccessibleButton from "../../components/views/elements/AccessibleButton";
@ -23,7 +23,7 @@ import { highlightEvent } from "../../utils/EventUtils";
import { _t } from "../../languageHandler";
import { getSenderName } from "../../utils/event/getSenderName";
export const textForVoiceBroadcastStoppedEvent = (event: MatrixEvent): (() => ReactNode) => {
export const textForVoiceBroadcastStoppedEvent = (event: MatrixEvent, client: MatrixClient): (() => ReactNode) => {
return (): ReactNode => {
const ownUserId = MatrixClientPeg.get()?.getUserId();
const startEventId = event.getRelation()?.event_id;

View File

@ -95,7 +95,7 @@ const VIRTUAL_ROOM_BOB = "$virtual_bob_room:example.org";
const BOB_PHONE_NUMBER = "01818118181";
function mkStubDM(roomId: string, userId: string) {
const room = mkStubRoom(roomId, "room", MatrixClientPeg.get());
const room = mkStubRoom(roomId, "room", MatrixClientPeg.safeGet());
room.getJoinedMembers = jest.fn().mockReturnValue([
{
userId: "@me:example.org",
@ -169,16 +169,16 @@ describe("LegacyCallHandler", () => {
beforeEach(async () => {
stubClient();
fakeCall = null;
MatrixClientPeg.get().createCall = (roomId: string): MatrixCall | null => {
MatrixClientPeg.safeGet().createCall = (roomId: string): MatrixCall | null => {
if (fakeCall && fakeCall.roomId !== roomId) {
throw new Error("Only one call is supported!");
}
fakeCall = new FakeCall(roomId) as unknown as MatrixCall;
return fakeCall as unknown as MatrixCall;
};
MatrixClientPeg.get().deviceId = deviceId;
MatrixClientPeg.safeGet().deviceId = deviceId;
MatrixClientPeg.get().getThirdpartyProtocols = () => {
MatrixClientPeg.safeGet().getThirdpartyProtocols = () => {
return Promise.resolve({
"m.id.phone": {} as IProtocol,
"im.vector.protocol.sip_native": {} as IProtocol,
@ -196,7 +196,7 @@ describe("LegacyCallHandler", () => {
const nativeRoomCharie = mkStubDM(NATIVE_ROOM_CHARLIE, NATIVE_CHARLIE);
const virtualBobRoom = mkStubDM(VIRTUAL_ROOM_BOB, VIRTUAL_BOB);
MatrixClientPeg.get().getRoom = (roomId: string): Room | null => {
MatrixClientPeg.safeGet().getRoom = (roomId: string): Room | null => {
switch (roomId) {
case NATIVE_ROOM_ALICE:
return nativeRoomAlice;
@ -244,7 +244,7 @@ describe("LegacyCallHandler", () => {
pstnLookup = null;
nativeLookup = null;
MatrixClientPeg.get().getThirdpartyUser = (proto: string, params: any) => {
MatrixClientPeg.safeGet().getThirdpartyUser = (proto: string, params: any) => {
if ([PROTOCOL_PSTN, PROTOCOL_PSTN_PREFIXED].includes(proto)) {
pstnLookup = params["m.id.phone"];
return Promise.resolve([
@ -402,10 +402,10 @@ describe("LegacyCallHandler", () => {
mkVoiceBroadcastInfoStateEvent(
"!room:example.com",
VoiceBroadcastInfoState.Started,
MatrixClientPeg.get().getSafeUserId(),
MatrixClientPeg.safeGet().getSafeUserId(),
"d42",
),
MatrixClientPeg.get(),
MatrixClientPeg.safeGet(),
SdkContextClass.instance.voiceBroadcastRecordingsStore,
);
SdkContextClass.instance.voiceBroadcastPlaybacksStore.setCurrent(voiceBroadcastPlayback);
@ -427,10 +427,10 @@ describe("LegacyCallHandler", () => {
mkVoiceBroadcastInfoStateEvent(
"!room:example.com",
VoiceBroadcastInfoState.Started,
MatrixClientPeg.get().getSafeUserId(),
MatrixClientPeg.safeGet().getSafeUserId(),
"d42",
),
MatrixClientPeg.get(),
MatrixClientPeg.safeGet(),
),
);
});
@ -451,7 +451,7 @@ describe("LegacyCallHandler without third party protocols", () => {
beforeEach(() => {
stubClient();
fakeCall = null;
MatrixClientPeg.get().createCall = (roomId) => {
MatrixClientPeg.safeGet().createCall = (roomId) => {
if (fakeCall && fakeCall.roomId !== roomId) {
throw new Error("Only one call is supported!");
}
@ -459,7 +459,7 @@ describe("LegacyCallHandler without third party protocols", () => {
return fakeCall;
};
MatrixClientPeg.get().getThirdpartyProtocols = () => {
MatrixClientPeg.safeGet().getThirdpartyProtocols = () => {
throw new Error("Endpoint unsupported.");
};
@ -468,7 +468,7 @@ describe("LegacyCallHandler without third party protocols", () => {
const nativeRoomAlice = mkStubDM(NATIVE_ROOM_ALICE, NATIVE_ALICE);
MatrixClientPeg.get().getRoom = (roomId: string): Room | null => {
MatrixClientPeg.safeGet().getRoom = (roomId: string): Room | null => {
switch (roomId) {
case NATIVE_ROOM_ALICE:
return nativeRoomAlice;
@ -495,7 +495,7 @@ describe("LegacyCallHandler without third party protocols", () => {
} as DMRoomMap;
DMRoomMap.setShared(dmRoomMap);
MatrixClientPeg.get().getThirdpartyUser = (_proto, _params) => {
MatrixClientPeg.safeGet().getThirdpartyUser = (_proto, _params) => {
throw new Error("Endpoint unsupported.");
};
@ -547,12 +547,12 @@ describe("LegacyCallHandler without third party protocols", () => {
jest.clearAllMocks();
jest.spyOn(SettingsStore, "getValue").mockImplementation((setting) => setting === UIFeature.Voip);
jest.spyOn(MatrixClientPeg.get(), "supportsVoip").mockReturnValue(true);
jest.spyOn(MatrixClientPeg.safeGet(), "supportsVoip").mockReturnValue(true);
MatrixClientPeg.get().isFallbackICEServerAllowed = jest.fn();
MatrixClientPeg.get().prepareToEncrypt = jest.fn();
MatrixClientPeg.safeGet().isFallbackICEServerAllowed = jest.fn();
MatrixClientPeg.safeGet().prepareToEncrypt = jest.fn();
MatrixClientPeg.get().pushRules = {
MatrixClientPeg.safeGet().pushRules = {
global: {
[PushRuleKind.Override]: [
{
@ -573,7 +573,7 @@ describe("LegacyCallHandler without third party protocols", () => {
jest.spyOn(document, "getElementById").mockReturnValue(mockAudioElement);
// silence local notifications by default
jest.spyOn(MatrixClientPeg.get(), "getAccountData").mockImplementation((eventType) => {
jest.spyOn(MatrixClientPeg.safeGet(), "getAccountData").mockImplementation((eventType) => {
if (eventType.includes(LOCAL_NOTIFICATION_SETTINGS_PREFIX.name)) {
return new MatrixEvent({
type: eventType,
@ -600,10 +600,10 @@ describe("LegacyCallHandler without third party protocols", () => {
it("listens for incoming call events when voip is enabled", () => {
const call = new MatrixCall({
client: MatrixClientPeg.get(),
client: MatrixClientPeg.safeGet(),
roomId,
});
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
cli.emit(CallEventHandlerEvent.Incoming, call);
@ -613,12 +613,12 @@ describe("LegacyCallHandler without third party protocols", () => {
it("rings when incoming call state is ringing and notifications set to ring", () => {
// remove local notification silencing mock for this test
jest.spyOn(MatrixClientPeg.get(), "getAccountData").mockReturnValue(undefined);
jest.spyOn(MatrixClientPeg.safeGet(), "getAccountData").mockReturnValue(undefined);
const call = new MatrixCall({
client: MatrixClientPeg.get(),
client: MatrixClientPeg.safeGet(),
roomId,
});
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
cli.emit(CallEventHandlerEvent.Incoming, call);
@ -632,10 +632,10 @@ describe("LegacyCallHandler without third party protocols", () => {
it("does not ring when incoming call state is ringing but local notifications are silenced", () => {
const call = new MatrixCall({
client: MatrixClientPeg.get(),
client: MatrixClientPeg.safeGet(),
roomId,
});
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
cli.emit(CallEventHandlerEvent.Incoming, call);
@ -650,10 +650,10 @@ describe("LegacyCallHandler without third party protocols", () => {
it("should force calls to silent when local notifications are silenced", async () => {
const call = new MatrixCall({
client: MatrixClientPeg.get(),
client: MatrixClientPeg.safeGet(),
roomId,
});
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
cli.emit(CallEventHandlerEvent.Incoming, call);
@ -663,10 +663,10 @@ describe("LegacyCallHandler without third party protocols", () => {
it("does not unsilence calls when local notifications are silenced", async () => {
const call = new MatrixCall({
client: MatrixClientPeg.get(),
client: MatrixClientPeg.safeGet(),
roomId,
});
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
const callHandlerEmitSpy = jest.spyOn(callHandler, "emit");
cli.emit(CallEventHandlerEvent.Incoming, call);

View File

@ -44,7 +44,7 @@ describe("MatrixClientPeg", () => {
stubClient();
(peg as any).matrixClient = peg.get();
peg.setJustRegisteredUserId("@userId:matrix.org");
expect(peg.get().credentials.userId).toBe("@userId:matrix.org");
expect(peg.safeGet().credentials.userId).toBe("@userId:matrix.org");
expect(peg.currentUserIsJustRegistered()).toBe(true);
expect(peg.userRegisteredWithinLastHours(0)).toBe(false);
expect(peg.userRegisteredWithinLastHours(1)).toBe(true);
@ -89,11 +89,11 @@ describe("MatrixClientPeg", () => {
});
it("should initialise client crypto", async () => {
const mockInitCrypto = jest.spyOn(testPeg.get(), "initCrypto").mockResolvedValue(undefined);
const mockInitCrypto = jest.spyOn(testPeg.safeGet(), "initCrypto").mockResolvedValue(undefined);
const mockSetTrustCrossSignedDevices = jest
.spyOn(testPeg.get(), "setCryptoTrustCrossSignedDevices")
.spyOn(testPeg.safeGet(), "setCryptoTrustCrossSignedDevices")
.mockImplementation(() => {});
const mockStartClient = jest.spyOn(testPeg.get(), "startClient").mockResolvedValue(undefined);
const mockStartClient = jest.spyOn(testPeg.safeGet(), "startClient").mockResolvedValue(undefined);
await testPeg.start();
expect(mockInitCrypto).toHaveBeenCalledTimes(1);
@ -103,11 +103,11 @@ describe("MatrixClientPeg", () => {
it("should carry on regardless if there is an error initialising crypto", async () => {
const e2eError = new Error("nope nope nope");
const mockInitCrypto = jest.spyOn(testPeg.get(), "initCrypto").mockRejectedValue(e2eError);
const mockInitCrypto = jest.spyOn(testPeg.safeGet(), "initCrypto").mockRejectedValue(e2eError);
const mockSetTrustCrossSignedDevices = jest
.spyOn(testPeg.get(), "setCryptoTrustCrossSignedDevices")
.spyOn(testPeg.safeGet(), "setCryptoTrustCrossSignedDevices")
.mockImplementation(() => {});
const mockStartClient = jest.spyOn(testPeg.get(), "startClient").mockResolvedValue(undefined);
const mockStartClient = jest.spyOn(testPeg.safeGet(), "startClient").mockResolvedValue(undefined);
const mockWarning = jest.spyOn(logger, "warn").mockReturnValue(undefined);
await testPeg.start();
@ -130,8 +130,8 @@ describe("MatrixClientPeg", () => {
const mockSetValue = jest.spyOn(SettingsStore, "setValue").mockResolvedValue(undefined);
const mockInitCrypto = jest.spyOn(testPeg.get(), "initCrypto").mockResolvedValue(undefined);
const mockInitRustCrypto = jest.spyOn(testPeg.get(), "initRustCrypto").mockResolvedValue(undefined);
const mockInitCrypto = jest.spyOn(testPeg.safeGet(), "initCrypto").mockResolvedValue(undefined);
const mockInitRustCrypto = jest.spyOn(testPeg.safeGet(), "initRustCrypto").mockResolvedValue(undefined);
await testPeg.start();
expect(mockInitCrypto).not.toHaveBeenCalled();
@ -142,9 +142,9 @@ describe("MatrixClientPeg", () => {
});
it("should reload when store database closes for a guest user", async () => {
testPeg.get().isGuest = () => true;
testPeg.safeGet().isGuest = () => true;
const emitter = new EventEmitter();
testPeg.get().store.on = emitter.on.bind(emitter);
testPeg.safeGet().store.on = emitter.on.bind(emitter);
const platform: any = { reload: jest.fn() };
PlatformPeg.set(platform);
await testPeg.assign();
@ -153,9 +153,9 @@ describe("MatrixClientPeg", () => {
});
it("should show error modal when store database closes", async () => {
testPeg.get().isGuest = () => false;
testPeg.safeGet().isGuest = () => false;
const emitter = new EventEmitter();
testPeg.get().store.on = emitter.on.bind(emitter);
testPeg.safeGet().store.on = emitter.on.bind(emitter);
const spy = jest.spyOn(Modal, "createDialog");
await testPeg.assign();
emitter.emit("closed" as any);

View File

@ -54,7 +54,7 @@ describe("MediaDeviceHandler", () => {
expect(SettingsStoreMock.setValue).toHaveBeenCalledWith(key, null, SettingLevel.DEVICE, value);
});
expect(MatrixClientPeg.get().getMediaHandler().setAudioSettings).toHaveBeenCalledWith({
expect(MatrixClientPeg.safeGet().getMediaHandler().setAudioSettings).toHaveBeenCalledWith({
autoGainControl: false,
echoCancellation: true,
noiseSuppression: false,

View File

@ -47,6 +47,8 @@ function mockPinnedEvent(pinnedMessageIds?: string[], prevPinnedMessageIds?: str
}
describe("TextForEvent", () => {
const mockClient = createTestClient();
describe("getSenderName()", () => {
it("Prefers sender.name", () => {
expect(getSenderName({ sender: { name: "Alice" } } as MatrixEvent)).toBe("Alice");
@ -67,8 +69,8 @@ describe("TextForEvent", () => {
it("mentions message when a single message was pinned, with no previously pinned messages", () => {
const event = mockPinnedEvent(["message-1"]);
const plainText = textForEvent(event);
const component = render(textForEvent(event, true) as ReactElement);
const plainText = textForEvent(event, mockClient);
const component = render(textForEvent(event, mockClient, true) as ReactElement);
const expectedText = "@foo:example.com pinned a message to this room. See all pinned messages.";
expect(plainText).toBe(expectedText);
@ -77,8 +79,8 @@ describe("TextForEvent", () => {
it("mentions message when a single message was pinned, with multiple previously pinned messages", () => {
const event = mockPinnedEvent(["message-1", "message-2", "message-3"], ["message-1", "message-2"]);
const plainText = textForEvent(event);
const component = render(textForEvent(event, true) as ReactElement);
const plainText = textForEvent(event, mockClient);
const component = render(textForEvent(event, mockClient, true) as ReactElement);
const expectedText = "@foo:example.com pinned a message to this room. See all pinned messages.";
expect(plainText).toBe(expectedText);
@ -87,8 +89,8 @@ describe("TextForEvent", () => {
it("mentions message when a single message was unpinned, with a single message previously pinned", () => {
const event = mockPinnedEvent([], ["message-1"]);
const plainText = textForEvent(event);
const component = render(textForEvent(event, true) as ReactElement);
const plainText = textForEvent(event, mockClient);
const component = render(textForEvent(event, mockClient, true) as ReactElement);
const expectedText = "@foo:example.com unpinned a message from this room. See all pinned messages.";
expect(plainText).toBe(expectedText);
@ -97,8 +99,8 @@ describe("TextForEvent", () => {
it("mentions message when a single message was unpinned, with multiple previously pinned messages", () => {
const event = mockPinnedEvent(["message-2"], ["message-1", "message-2"]);
const plainText = textForEvent(event);
const component = render(textForEvent(event, true) as ReactElement);
const plainText = textForEvent(event, mockClient);
const component = render(textForEvent(event, mockClient, true) as ReactElement);
const expectedText = "@foo:example.com unpinned a message from this room. See all pinned messages.";
expect(plainText).toBe(expectedText);
@ -107,8 +109,8 @@ describe("TextForEvent", () => {
it("shows generic text when multiple messages were pinned", () => {
const event = mockPinnedEvent(["message-1", "message-2", "message-3"], ["message-1"]);
const plainText = textForEvent(event);
const component = render(textForEvent(event, true) as ReactElement);
const plainText = textForEvent(event, mockClient);
const component = render(textForEvent(event, mockClient, true) as ReactElement);
const expectedText = "@foo:example.com changed the pinned messages for the room.";
expect(plainText).toBe(expectedText);
@ -117,8 +119,8 @@ describe("TextForEvent", () => {
it("shows generic text when multiple messages were unpinned", () => {
const event = mockPinnedEvent(["message-3"], ["message-1", "message-2", "message-3"]);
const plainText = textForEvent(event);
const component = render(textForEvent(event, true) as ReactElement);
const plainText = textForEvent(event, mockClient);
const component = render(textForEvent(event, mockClient, true) as ReactElement);
const expectedText = "@foo:example.com changed the pinned messages for the room.";
expect(plainText).toBe(expectedText);
@ -127,8 +129,8 @@ describe("TextForEvent", () => {
it("shows generic text when one message was pinned, and another unpinned", () => {
const event = mockPinnedEvent(["message-2"], ["message-1"]);
const plainText = textForEvent(event);
const component = render(textForEvent(event, true) as ReactElement);
const plainText = textForEvent(event, mockClient);
const component = render(textForEvent(event, mockClient, true) as ReactElement);
const expectedText = "@foo:example.com changed the pinned messages for the room.";
expect(plainText).toBe(expectedText);
@ -184,6 +186,7 @@ describe("TextForEvent", () => {
beforeAll(() => {
mockClient = createTestClient() as Mocked<MatrixClient>;
MatrixClientPeg.get = () => mockClient;
MatrixClientPeg.safeGet = () => mockClient;
mockClient.getRoom.mockClear().mockReturnValue(mockRoom);
mockRoom.getMember
.mockClear()
@ -206,7 +209,7 @@ describe("TextForEvent", () => {
[userA.userId]: 100,
},
});
expect(textForEvent(event)).toBeFalsy();
expect(textForEvent(event, mockClient)).toBeFalsy();
});
it("returns false when users power levels have been changed by default settings", () => {
@ -220,7 +223,7 @@ describe("TextForEvent", () => {
[userA.userId]: 50,
},
});
expect(textForEvent(event)).toBeFalsy();
expect(textForEvent(event, mockClient)).toBeFalsy();
});
it("returns correct message for a single user with changed power level", () => {
@ -233,7 +236,7 @@ describe("TextForEvent", () => {
},
});
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Admin.";
expect(textForEvent(event)).toEqual(expectedText);
expect(textForEvent(event, mockClient)).toEqual(expectedText);
});
it("returns correct message for a single user with power level changed to the default", () => {
@ -248,7 +251,7 @@ describe("TextForEvent", () => {
},
});
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Default.";
expect(textForEvent(event)).toEqual(expectedText);
expect(textForEvent(event, mockClient)).toEqual(expectedText);
});
it("returns correct message for a single user with power level changed to a custom level", () => {
@ -261,7 +264,7 @@ describe("TextForEvent", () => {
},
});
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Custom (-1).";
expect(textForEvent(event)).toEqual(expectedText);
expect(textForEvent(event, mockClient)).toEqual(expectedText);
});
it("returns correct message for a multiple power level changes", () => {
@ -278,7 +281,7 @@ describe("TextForEvent", () => {
const expectedText =
"Alice changed the power level of Bob (@b) from Moderator to Admin," +
" Bob (@c) from Custom (101) to Moderator.";
expect(textForEvent(event)).toEqual(expectedText);
expect(textForEvent(event, mockClient)).toEqual(expectedText);
});
});
@ -382,7 +385,7 @@ describe("TextForEvent", () => {
it.each(testCases)("returns correct message when %s", (_d, { result, ...eventProps }) => {
const event = mockEvent(eventProps);
expect(textForEvent(event)).toEqual(result);
expect(textForEvent(event, mockClient)).toEqual(result);
});
});
@ -409,11 +412,11 @@ describe("TextForEvent", () => {
it("returns correct message for redacted poll start", () => {
pollEvent.makeRedacted(pollEvent);
expect(textForEvent(pollEvent)).toEqual("@a: Message deleted");
expect(textForEvent(pollEvent, mockClient)).toEqual("@a: Message deleted");
});
it("returns correct message for normal poll start", () => {
expect(textForEvent(pollEvent)).toEqual("@a has started a poll - ");
expect(textForEvent(pollEvent, mockClient)).toEqual("@a has started a poll - ");
});
});
@ -435,11 +438,11 @@ describe("TextForEvent", () => {
it("returns correct message for redacted message", () => {
messageEvent.makeRedacted(messageEvent);
expect(textForEvent(messageEvent)).toEqual("@a: Message deleted");
expect(textForEvent(messageEvent, mockClient)).toEqual("@a: Message deleted");
});
it("returns correct message for normal message", () => {
expect(textForEvent(messageEvent)).toEqual("@a: test message");
expect(textForEvent(messageEvent, mockClient)).toEqual("@a: test message");
});
});
@ -449,7 +452,7 @@ describe("TextForEvent", () => {
beforeEach(() => {
stubClient();
mockClient = MatrixClientPeg.get();
mockClient = MatrixClientPeg.safeGet();
mocked(mockClient.getRoom).mockReturnValue({
name: "Test room",
@ -468,13 +471,13 @@ describe("TextForEvent", () => {
});
it("returns correct message for call event when supported", () => {
expect(textForEvent(callEvent)).toEqual("Video call started in Test room.");
expect(textForEvent(callEvent, mockClient)).toEqual("Video call started in Test room.");
});
it("returns correct message for call event when not supported", () => {
mocked(mockClient).supportsVoip.mockReturnValue(false);
expect(textForEvent(callEvent)).toEqual(
expect(textForEvent(callEvent, mockClient)).toEqual(
"Video call started in Test room. (not supported by this browser)",
);
});
@ -504,6 +507,7 @@ describe("TextForEvent", () => {
},
state_key: "@a:foo",
}),
mockClient,
),
).toMatchInlineSnapshot(`"Andy changed their display name and profile picture"`);
});

View File

@ -33,7 +33,7 @@ describe("Unread", () => {
// A different user.
const aliceId = "@alice:server.org";
stubClient();
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
describe("eventTriggersUnreadCount()", () => {
// setup events

View File

@ -44,7 +44,7 @@ const TOO_SHORT_EMOJI_SHORTCODE = [{ emojiShortcode: ":o", expectedEmoji: "⭕
describe("EmojiProvider", function () {
const testRoom = mkStubRoom(undefined, undefined, undefined);
stubClient();
MatrixClientPeg.get();
MatrixClientPeg.safeGet();
it.each(EMOJI_SHORTCODES)("Returns consistent results after final colon %s", async function (emojiShortcode) {
const ep = new EmojiProvider(testRoom);

View File

@ -30,7 +30,7 @@ let client: MatrixClient;
describe("LegacyCallEventGrouper", () => {
beforeEach(() => {
stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
client.getUserId = () => {
return MY_USER_ID;
};

View File

@ -90,7 +90,7 @@ describe("PipContainer", () => {
user = userEvent.setup();
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
DMRoomMap.makeShared(client);
room = new Room("!1:example.org", client, "@alice:example.org", {

View File

@ -47,7 +47,7 @@ describe("RightPanel", () => {
let RightPanel: React.ComponentType<React.ComponentProps<typeof RightPanelBase>>;
beforeEach(() => {
stubClient();
cli = mocked(MatrixClientPeg.get());
cli = mocked(MatrixClientPeg.safeGet());
DMRoomMap.makeShared(cli);
context = new SdkContextClass();
context.client = cli;

View File

@ -45,7 +45,7 @@ describe("<RoomSearchView/>", () => {
beforeEach(async () => {
stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
client.supportsThreads = jest.fn().mockReturnValue(true);
room = new Room("!room:server", client, client.getSafeUserId());
mocked(client.getRoom).mockReturnValue(room);

View File

@ -37,7 +37,7 @@ describe("RoomStatusBar", () => {
jest.clearAllMocks();
stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
client.getSyncStateData = jest.fn().mockReturnValue({});
room = new Room(ROOM_ID, client, client.getUserId()!, {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -76,7 +76,7 @@ describe("RoomView", () => {
beforeEach(() => {
mockPlatformPeg({ reload: () => {} });
stubClient();
cli = mocked(MatrixClientPeg.get());
cli = mocked(MatrixClientPeg.safeGet());
room = new Room(`!${roomCount++}:example.org`, cli, "@alice:example.org");
jest.spyOn(room, "findPredecessor");

View File

@ -43,7 +43,7 @@ describe("SpaceHierarchy", () => {
let room: Room;
beforeEach(() => {
stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
room = new Room("room-id", client, "@alice:example.com");
hierarchy = new RoomHierarchy(room);
@ -82,7 +82,7 @@ describe("SpaceHierarchy", () => {
describe("toLocalRoom", () => {
stubClient();
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
const roomV1 = mkStubRoom("room-id-1", "Room V1", client);
const roomV2 = mkStubRoom("room-id-2", "Room V2", client);
const roomV3 = mkStubRoom("room-id-3", "Room V3", client);
@ -171,7 +171,7 @@ describe("SpaceHierarchy", () => {
});
stubClient();
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
const dmRoomMap = {
getUserIdForRoomId: jest.fn(),

View File

@ -120,7 +120,7 @@ describe("ThreadPanel", () => {
stubClient();
mockPlatformPeg();
mockClient = mocked(MatrixClientPeg.get());
mockClient = mocked(MatrixClientPeg.safeGet());
Thread.setServerSideSupport(FeatureSupport.Stable);
Thread.setServerSideListSupport(FeatureSupport.Stable);
Thread.setServerSideFwdPaginationSupport(FeatureSupport.Stable);

View File

@ -115,7 +115,7 @@ describe("ThreadView", () => {
stubClient();
mockPlatformPeg();
mockClient = mocked(MatrixClientPeg.get());
mockClient = mocked(MatrixClientPeg.safeGet());
jest.spyOn(mockClient, "supportsThreads").mockReturnValue(true);
room = new Room(ROOM_ID, mockClient, mockClient.getUserId() ?? "", {

View File

@ -106,7 +106,7 @@ const mockEvents = (room: Room, count = 2): MatrixEvent[] => {
};
const setupTestData = (): [MatrixClient, Room, MatrixEvent[]] => {
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
const room = mkRoom(client, "roomId");
const events = mockEvents(room);
return [client, room, events];
@ -377,7 +377,7 @@ describe("TimelinePanel", () => {
});
it("should scroll event into view when props.eventId changes", () => {
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
const room = mkRoom(client, "roomId");
const events = mockEvents(room);
@ -798,7 +798,7 @@ describe("TimelinePanel", () => {
let reply2: MatrixEvent;
beforeEach(() => {
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
Thread.hasServerSideSupport = FeatureSupport.Stable;
room = new Room("roomId", client, "userId");
@ -952,7 +952,7 @@ describe("TimelinePanel", () => {
});
it("renders when the last message is an undecryptable thread root", async () => {
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
client.isRoomEncrypted = () => true;
client.supportsThreads = () => true;
client.decryptEventIfNeeded = () => Promise.resolve();

View File

@ -47,7 +47,7 @@ describe("MemberAvatar", () => {
jest.clearAllMocks();
stubClient();
mockClient = mocked(MatrixClientPeg.get());
mockClient = mocked(MatrixClientPeg.safeGet());
room = new Room(ROOM_ID, mockClient, mockClient.getUserId() ?? "", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -41,7 +41,7 @@ describe("<RoomCallBanner />", () => {
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
room = new Room("!1:example.org", client, "@alice:example.org", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -159,7 +159,7 @@ describe("MessageContextMenu", () => {
room_id: roomId,
});
pinnableEvent.event.event_id = "!3";
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
const room = makeDefaultRoom();
// mock permission to allow adding pinned messages to room
@ -204,7 +204,7 @@ describe("MessageContextMenu", () => {
room_id: roomId,
});
pinnableEvent.event.event_id = "!3";
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
const room = makeDefaultRoom();
// make the event already pinned in the room
@ -543,7 +543,7 @@ function createMenuWithContent(
}
function makeDefaultRoom(): Room {
return new Room(roomId, MatrixClientPeg.get(), "@user:example.com", {
return new Room(roomId, MatrixClientPeg.safeGet(), "@user:example.com", {
pendingEventOrdering: PendingEventOrdering.Detached,
});
}
@ -555,7 +555,7 @@ function createMenu(
beacons: Map<BeaconIdentifier, Beacon> = new Map(),
room: Room = makeDefaultRoom(),
): RenderResult {
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
// @ts-ignore illegally set private prop
room.currentState.beacons = beacons;

View File

@ -46,7 +46,7 @@ describe("RoomContextMenu", () => {
jest.clearAllMocks();
stubClient();
mockClient = mocked(MatrixClientPeg.get());
mockClient = mocked(MatrixClientPeg.safeGet());
room = new Room(ROOM_ID, mockClient, mockClient.getUserId() ?? "", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -71,7 +71,7 @@ describe("RoomGeneralContextMenu", () => {
jest.clearAllMocks();
stubClient();
mockClient = mocked(MatrixClientPeg.get());
mockClient = mocked(MatrixClientPeg.safeGet());
room = new Room(ROOM_ID, mockClient, mockClient.getUserId() ?? "", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -45,7 +45,7 @@ describe("ThreadListContextMenu", () => {
jest.clearAllMocks();
stubClient();
mockClient = mocked(MatrixClientPeg.get());
mockClient = mocked(MatrixClientPeg.safeGet());
room = new Room(ROOM_ID, mockClient, mockClient.getUserId() ?? "", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -39,7 +39,7 @@ describe("DevtoolsDialog", () => {
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
room = new Room("!id", cli, "@alice:matrix.org");
jest.spyOn(cli, "getRoom").mockReturnValue(room);

View File

@ -70,7 +70,7 @@ function mockClient({
users = [],
}: MockClientOptions = {}): MatrixClient {
stubClient();
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
MatrixClientPeg.getHomeserverName = jest.fn(() => homeserver);
cli.getUserId = jest.fn(() => userId);
cli.getHomeserverUrl = jest.fn(() => homeserver);

View File

@ -31,7 +31,7 @@ describe("<RoomNotifications />", () => {
});
it("should render", () => {
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
const { asFragment } = render(
<MatrixClientContext.Provider value={cli}>
<DevtoolsContext.Provider

View File

@ -82,7 +82,7 @@ describe("AppTile", () => {
beforeAll(async () => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
cli.hasLazyLoadMembersEnabled = () => false;
// Init misc. startup deps

View File

@ -274,7 +274,7 @@ describe("PollCreateDialog", () => {
});
function createRoom(): Room {
return new Room("roomid", MatrixClientPeg.get(), "@name:example.com", {});
return new Room("roomid", MatrixClientPeg.safeGet(), "@name:example.com", {});
}
function changeValue(wrapper: RenderResult, labelText: string, value: string) {

View File

@ -58,7 +58,7 @@ describe("CallEvent", () => {
jest.setSystemTime(0);
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
client.getUserId.mockReturnValue("@alice:example.org");
room = new Room("!1:example.org", client, "@alice:example.org", {

View File

@ -38,7 +38,7 @@ describe("<RoomPredecessorTile />", () => {
const userId = "@alice:server.org";
const roomId = "!room:server.org";
stubClient();
const client = mocked(MatrixClientPeg.get());
const client = mocked(MatrixClientPeg.safeGet());
function makeRoom({
createEventHasPredecessor = false,
@ -165,7 +165,7 @@ describe("<RoomPredecessorTile />", () => {
filterConsole("Failed to find predecessor room with id old_room_id");
beforeEach(() => {
mocked(MatrixClientPeg.get().getRoom).mockReturnValue(null);
mocked(MatrixClientPeg.safeGet().getRoom).mockReturnValue(null);
});
it("Shows an error if there are no via servers", () => {
@ -219,7 +219,7 @@ describe("<RoomPredecessorTile />", () => {
filterConsole("Failed to find predecessor room with id old_room_id");
beforeEach(() => {
mocked(MatrixClientPeg.get().getRoom).mockReturnValue(null);
mocked(MatrixClientPeg.safeGet().getRoom).mockReturnValue(null);
});
it("Shows an error if there are no via servers", () => {

View File

@ -34,7 +34,7 @@ import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalink
describe("<PinnedMessagesCard />", () => {
stubClient();
const cli = mocked(MatrixClientPeg.get());
const cli = mocked(MatrixClientPeg.safeGet());
cli.getUserId.mockReturnValue("@alice:example.org");
cli.setRoomAccountData.mockResolvedValue({});
cli.relations.mockResolvedValue({ originalEvent: {} as unknown as MatrixEvent, events: [] });

View File

@ -35,7 +35,7 @@ describe("RoomHeaderButtons-test.tsx", function () {
jest.clearAllMocks();
stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
client.supportsThreads = () => true;
room = new Room(ROOM_ID, client, client.getUserId() ?? "", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -32,7 +32,7 @@ describe("BasicMessageComposer", () => {
TestUtils.stubClient();
const client: MatrixClient = MatrixClientPeg.get();
const client: MatrixClient = MatrixClientPeg.safeGet();
const roomId = "!1234567890:domain";
const userId = client.getSafeUserId();

View File

@ -73,7 +73,7 @@ describe("EventTile", () => {
jest.clearAllMocks();
stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
room = new Room(ROOM_ID, client, client.getSafeUserId(), {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -143,7 +143,7 @@ describe("MemberList", () => {
describe.each([false, true])("does order members correctly (presence %s)", (enablePresence) => {
beforeEach(function () {
TestUtils.stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
client.hasLazyLoadMembersEnabled = () => false;
// Make room

View File

@ -71,7 +71,7 @@ const startVoiceMessage = async (): Promise<void> => {
const setCurrentBroadcastRecording = (room: Room, state: VoiceBroadcastInfoState): void => {
const recording = new VoiceBroadcastRecording(
mkVoiceBroadcastInfoStateEvent(room.roomId, state, "@user:example.com", "ABC123"),
MatrixClientPeg.get(),
MatrixClientPeg.safeGet(),
state,
);
SdkContextClass.instance.voiceBroadcastRecordingsStore.setCurrent(recording);
@ -483,7 +483,7 @@ function wrapAndRender(
narrow = false,
tombstone?: MatrixEvent,
) {
const mockClient = MatrixClientPeg.get();
const mockClient = MatrixClientPeg.safeGet();
const roomId = "myroomid";
const room: any = props.room || {
currentState: undefined,

View File

@ -69,7 +69,7 @@ describe("RoomHeader", () => {
mockPlatformPeg({ supportsJitsiScreensharing: () => true });
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
client.getUserId.mockReturnValue("@alice:example.org");
room = new Room("!1:example.org", client, "@alice:example.org", {
@ -750,7 +750,7 @@ interface IRoomCreationInfo {
function createRoom(info: IRoomCreationInfo) {
stubClient();
const client: MatrixClient = MatrixClientPeg.get();
const client: MatrixClient = MatrixClientPeg.safeGet();
const roomId = "!1234567890:domain";
const userId = client.getUserId()!;

View File

@ -47,7 +47,7 @@ DMRoomMap.sharedInstance = { getUserIdForRoomId, getDMRoomsForUserId };
describe("RoomList", () => {
stubClient();
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
const store = SpaceStore.instance;
function getComponent(props: Partial<ComponentProps<typeof RoomList>> = {}): JSX.Element {

View File

@ -112,7 +112,7 @@ describe("RoomListHeader", () => {
} as unknown as DMRoomMap;
DMRoomMap.setShared(dmRoomMap);
stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
mocked(shouldShowComponent).mockReturnValue(true); // show all UIComponents
});

View File

@ -33,7 +33,7 @@ jest.mock("../../../../src/IdentityAuthClient", () => {
jest.useRealTimers();
const createRoom = (roomId: string, userId: string): Room => {
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
const newRoom = new Room(roomId, cli, userId, {});
DMRoomMap.makeShared(cli).start();
return newRoom;
@ -92,7 +92,7 @@ describe("<RoomPreviewBar />", () => {
beforeEach(() => {
stubClient();
MatrixClientPeg.get().getUserId = jest.fn().mockReturnValue(userId);
MatrixClientPeg.safeGet().getUserId = jest.fn().mockReturnValue(userId);
});
afterEach(() => {
@ -118,7 +118,7 @@ describe("<RoomPreviewBar />", () => {
});
it("renders not logged in message", () => {
MatrixClientPeg.get().isGuest = jest.fn().mockReturnValue(true);
MatrixClientPeg.safeGet().isGuest = jest.fn().mockReturnValue(true);
const component = getComponent({ loading: true });
expect(isSpinnerRendered(component)).toBeFalsy();
@ -126,7 +126,7 @@ describe("<RoomPreviewBar />", () => {
});
it("should send room oob data to start login", async () => {
MatrixClientPeg.get().isGuest = jest.fn().mockReturnValue(true);
MatrixClientPeg.safeGet().isGuest = jest.fn().mockReturnValue(true);
const component = getComponent({
oobData: {
name: "Room Name",
@ -339,7 +339,7 @@ describe("<RoomPreviewBar />", () => {
describe("when client fails to get 3PIDs", () => {
beforeEach(() => {
MatrixClientPeg.get().getThreePids = jest.fn().mockRejectedValue({ errCode: "TEST_ERROR" });
MatrixClientPeg.safeGet().getThreePids = jest.fn().mockRejectedValue({ errCode: "TEST_ERROR" });
});
it("renders error message", async () => {
@ -354,7 +354,7 @@ describe("<RoomPreviewBar />", () => {
describe("when invitedEmail is not associated with current account", () => {
beforeEach(() => {
MatrixClientPeg.get().getThreePids = jest
MatrixClientPeg.safeGet().getThreePids = jest
.fn()
.mockResolvedValue({ threepids: mockThreePids.slice(1) });
});
@ -371,8 +371,8 @@ describe("<RoomPreviewBar />", () => {
describe("when client has no identity server connected", () => {
beforeEach(() => {
MatrixClientPeg.get().getThreePids = jest.fn().mockResolvedValue({ threepids: mockThreePids });
MatrixClientPeg.get().getIdentityServerUrl = jest.fn().mockReturnValue(false);
MatrixClientPeg.safeGet().getThreePids = jest.fn().mockResolvedValue({ threepids: mockThreePids });
MatrixClientPeg.safeGet().getIdentityServerUrl = jest.fn().mockReturnValue(false);
});
it("renders invite message with invited email", async () => {
@ -387,18 +387,18 @@ describe("<RoomPreviewBar />", () => {
describe("when client has an identity server connected", () => {
beforeEach(() => {
MatrixClientPeg.get().getThreePids = jest.fn().mockResolvedValue({ threepids: mockThreePids });
MatrixClientPeg.get().getIdentityServerUrl = jest.fn().mockReturnValue("identity.test");
MatrixClientPeg.get().lookupThreePid = jest.fn().mockResolvedValue("identity.test");
MatrixClientPeg.safeGet().getThreePids = jest.fn().mockResolvedValue({ threepids: mockThreePids });
MatrixClientPeg.safeGet().getIdentityServerUrl = jest.fn().mockReturnValue("identity.test");
MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockResolvedValue("identity.test");
});
it("renders email mismatch message when invite email mxid doesnt match", async () => {
MatrixClientPeg.get().lookupThreePid = jest.fn().mockReturnValue("not userid");
MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockReturnValue("not userid");
const component = getComponent({ inviterName, invitedEmail });
await new Promise(setImmediate);
expect(getMessage(component)).toMatchSnapshot();
expect(MatrixClientPeg.get().lookupThreePid).toHaveBeenCalledWith(
expect(MatrixClientPeg.safeGet().lookupThreePid).toHaveBeenCalledWith(
"email",
invitedEmail,
"mock-token",
@ -407,7 +407,7 @@ describe("<RoomPreviewBar />", () => {
});
it("renders invite message when invite email mxid match", async () => {
MatrixClientPeg.get().lookupThreePid = jest.fn().mockReturnValue(userId);
MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockReturnValue(userId);
const component = getComponent({ inviterName, invitedEmail });
await new Promise(setImmediate);

View File

@ -40,7 +40,7 @@ describe("RoomPreviewCard", () => {
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
client.getUserId.mockReturnValue("@alice:example.org");
DMRoomMap.makeShared(client);

View File

@ -31,7 +31,7 @@ type Props = React.ComponentPropsWithoutRef<typeof SearchResultTile>;
describe("SearchResultTile", () => {
beforeAll(() => {
stubClient();
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
const room = new Room(ROOM_ID, cli, "@bob:example.org");
jest.spyOn(cli, "getRoom").mockReturnValue(room);

View File

@ -56,6 +56,7 @@ describe("<VoiceRecordComposerTile/>", () => {
sendMessage: jest.fn(),
} as unknown as MatrixClient;
MatrixClientPeg.get = () => mockClient;
MatrixClientPeg.safeGet = () => mockClient;
const room = {
roomId,

View File

@ -29,7 +29,7 @@ describe("CryptographyPanel", () => {
const sessionKeyFormatted = "<b>AbCD eFgh IJK7 L/m4 nOPq RSTU VW4x yzaB CDef 6gHI Jkl</b>";
TestUtils.stubClient();
const client: MatrixClient = MatrixClientPeg.get();
const client: MatrixClient = MatrixClientPeg.safeGet();
client.deviceId = sessionId;
client.getDeviceEd25519Key = () => sessionKey;

View File

@ -41,7 +41,7 @@ describe("AdvancedRoomSettingsTab", () => {
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
room = mkStubRoom(roomId, "test room", cli);
mocked(cli.getRoom).mockReturnValue(room);
mocked(dis.dispatch).mockReset();

View File

@ -38,7 +38,7 @@ describe("NotificatinSettingsTab", () => {
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
const room = mkStubRoom(roomId, "test room", cli);
roomProps = EchoChamber.forRoom(room);

View File

@ -50,7 +50,7 @@ describe("RolesRoomSettingsTab", () => {
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
room = mkStubRoom(roomId, "test room", cli);
});

View File

@ -38,7 +38,7 @@ describe("VoipRoomSettingsTab", () => {
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
room = mkStubRoom(roomId, "test room", cli);
jest.spyOn(cli, "sendStateEvent");

View File

@ -53,7 +53,7 @@ describe("PreferencesUserSettingsTab", () => {
const getToggle = () => renderTab().getByRole("switch", { name: "Send read receipts" });
const mockIsVersionSupported = (val: boolean) => {
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
jest.spyOn(client, "doesServerSupportUnstableFeature").mockResolvedValue(false);
jest.spyOn(client, "isVersionSupported").mockImplementation(async (version: string) => {
if (version === "v1.4") return val;

View File

@ -107,6 +107,7 @@ describe("<SpaceSettingsVisibilityTab />", () => {
(mockMatrixClient.sendStateEvent as jest.Mock).mockClear().mockResolvedValue({});
MatrixClientPeg.get = jest.fn().mockReturnValue(mockMatrixClient);
MatrixClientPeg.safeGet = jest.fn().mockReturnValue(mockMatrixClient);
});
afterEach(() => {

View File

@ -39,8 +39,8 @@ jest.mock("../../../../src/stores/spaces/SpaceStore", () => {
describe("SpaceButton", () => {
stubClient();
const space = mkRoom(MatrixClientPeg.get(), "!1:example.org");
DMRoomMap.makeShared(MatrixClientPeg.get());
const space = mkRoom(MatrixClientPeg.safeGet(), "!1:example.org");
DMRoomMap.makeShared(MatrixClientPeg.safeGet());
const dispatchSpy = jest.spyOn(defaultDispatcher, "dispatch");

View File

@ -54,7 +54,7 @@ describe("CallLobby", () => {
mocked(navigator.mediaDevices.enumerateDevices).mockResolvedValue([]);
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
room = new Room("!1:example.org", client, "@alice:example.org", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -32,7 +32,7 @@ describe("createRoom", () => {
let client: Mocked<MatrixClient>;
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
});
afterEach(() => jest.clearAllMocks());

View File

@ -31,7 +31,7 @@ describe("useProfileInfo", () => {
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
cli.getProfileInfo = (query) => {
return Promise.resolve({
avatar_url: undefined,

View File

@ -31,7 +31,7 @@ describe("usePublicRoomDirectory", () => {
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
MatrixClientPeg.getHomeserverName = () => "matrix.org";
cli.getThirdpartyProtocols = () => Promise.resolve({});

View File

@ -31,7 +31,7 @@ describe("useUserDirectory", () => {
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
MatrixClientPeg.getHomeserverName = () => "matrix.org";
cli.getThirdpartyProtocols = () => Promise.resolve({});

View File

@ -68,7 +68,7 @@ const setUpClientRoomAndStores = (): {
carol: RoomMember;
} => {
stubClient();
const client = mocked<MatrixClient>(MatrixClientPeg.get());
const client = mocked<MatrixClient>(MatrixClientPeg.safeGet());
const room = new Room("!1:example.org", client, "@alice:example.org", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -66,6 +66,7 @@ describe("DeviceSettingsHandler", () => {
afterEach(() => {
MatrixClientPeg.get = () => null;
MatrixClientPeg.safeGet = () => null;
});
it("Returns the value for a disabled feature", () => {

View File

@ -93,7 +93,7 @@ DMRoomMap.sharedInstance = { getUserIdForRoomId, getDMRoomsForUserId };
describe("SpaceStore", () => {
stubClient();
const store = SpaceStore.instance;
const client = MatrixClientPeg.get();
const client = MatrixClientPeg.safeGet();
const spyDispatcher = jest.spyOn(defaultDispatcher, "dispatch");

View File

@ -36,7 +36,7 @@ describe("RightPanelStore", () => {
let cli: MockedObject<MatrixClient>;
beforeEach(() => {
stubClient();
cli = mocked(MatrixClientPeg.get());
cli = mocked(MatrixClientPeg.safeGet());
DMRoomMap.makeShared(cli);
// Make sure we start with a clean store

View File

@ -49,7 +49,7 @@ const space2 = "!space2:server";
describe("SpaceWatcher", () => {
stubClient();
const store = SpaceStore.instance;
const client = mocked(MatrixClientPeg.get());
const client = mocked(MatrixClientPeg.safeGet());
let rooms: Room[] = [];
const mkSpaceForRooms = (spaceId: string, children: string[] = []) => mkSpace(client, spaceId, rooms, children);

View File

@ -40,7 +40,7 @@ describe("Algorithm", () => {
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
DMRoomMap.makeShared(client);
algorithm = new Algorithm();

View File

@ -31,7 +31,7 @@ describe("RecentAlgorithm", () => {
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
cli = MatrixClientPeg.safeGet();
algorithm = new RecentAlgorithm();
});

View File

@ -60,7 +60,7 @@ describe("ReactionEventPreview", () => {
});
it("should use 'You' for your own reactions", () => {
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
const room = new Room(roomId, cli, userId);
mocked(cli.getRoom).mockReturnValue(room);
@ -97,7 +97,7 @@ describe("ReactionEventPreview", () => {
});
it("should use display name for your others' reactions", () => {
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
const room = new Room(roomId, cli, userId);
mocked(cli.getRoom).mockReturnValue(room);

View File

@ -36,7 +36,7 @@ describe("StopGapWidget", () => {
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
widget = new StopGapWidget({
app: {

View File

@ -61,7 +61,7 @@ describe("StopGapWidgetDriver", () => {
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
client.getUserId.mockReturnValue("@alice:example.org");
});

View File

@ -71,6 +71,7 @@ export const getMockClientWithEventEmitter = (
const mock = mocked(new MockClientWithEventEmitter(mockProperties) as unknown as MatrixClient);
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(mock);
jest.spyOn(MatrixClientPeg, "safeGet").mockReturnValue(mock);
// @ts-ignore simplified test stub
mock.canSupport = new Map();
@ -80,7 +81,10 @@ export const getMockClientWithEventEmitter = (
return mock;
};
export const unmockClientPeg = () => jest.spyOn(MatrixClientPeg, "get").mockRestore();
export const unmockClientPeg = () => {
jest.spyOn(MatrixClientPeg, "get").mockRestore();
jest.spyOn(MatrixClientPeg, "safeGet").mockRestore();
};
/**
* Returns basic mocked client methods related to the current user

View File

@ -69,13 +69,13 @@ export function stubClient(): MatrixClient {
// 'sandbox.restore()' doesn't work correctly on inherited methods,
// so we do this for each method
jest.spyOn(peg, "get");
jest.spyOn(peg, "safeGet");
jest.spyOn(peg, "unset");
jest.spyOn(peg, "replaceUsingCreds");
// MatrixClientPeg.get() is called a /lot/, so implement it with our own
// MatrixClientPeg.safeGet() is called a /lot/, so implement it with our own
// fast stub function rather than a sinon stub
peg.get = function () {
return client;
};
peg.get = () => client;
peg.safeGet = () => client;
MatrixClientBackedSettingsHandler.matrixClient = client;
return client;
}

View File

@ -29,7 +29,7 @@ export function wrapInMatrixClientContext<T>(WrappedComponent: ComponentType<T>)
constructor(props: WrapperProps<T>) {
super(props);
this._matrixClient = peg.get();
this._matrixClient = peg.safeGet();
}
render() {

View File

@ -60,7 +60,7 @@ describe("IncomingCallEvent", () => {
beforeEach(async () => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
room = new Room("!1:example.org", client, "@alice:example.org");

View File

@ -25,7 +25,7 @@ import { MatrixClientPeg } from "../src/MatrixClientPeg";
describe("useTopic", () => {
it("should display the room topic", () => {
stubClient();
const room = new Room("!TESTROOM", MatrixClientPeg.get(), "@alice:example.org");
const room = new Room("!TESTROOM", MatrixClientPeg.safeGet(), "@alice:example.org");
const topic = mkEvent({
type: "m.room.topic",
room: "!TESTROOM",

View File

@ -430,7 +430,7 @@ describe("EventUtils", () => {
jest.clearAllMocks();
stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
room = new Room(ROOM_ID, client, client.getUserId()!, {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -80,7 +80,7 @@ describe("MultiInviter", () => {
jest.resetAllMocks();
TestUtilsMatrix.stubClient();
client = MatrixClientPeg.get() as jest.Mocked<MatrixClient>;
client = MatrixClientPeg.safeGet() as jest.Mocked<MatrixClient>;
client.invite = jest.fn();
client.invite.mockResolvedValue({});

View File

@ -53,7 +53,7 @@ describe("export", function () {
let events: MatrixEvent[];
beforeEach(() => {
stubClient();
client = MatrixClientPeg.get();
client = MatrixClientPeg.safeGet();
client.getUserId = () => {
return MY_USER_ID;
};

View File

@ -40,7 +40,7 @@ describe("leaveRoomBehaviour", () => {
beforeEach(async () => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
DMRoomMap.makeShared(client);
room = mkRoom(client, "!1:example.org");

View File

@ -119,7 +119,7 @@ describe("notifications", () => {
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
room = new Room(ROOM_ID, client, USER_ID);
message = mkMessage({
event: true,
@ -172,7 +172,7 @@ describe("notifications", () => {
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
client = mocked(MatrixClientPeg.safeGet());
room = new Room(ROOM_ID, client, USER_ID);
sendReadReceiptSpy = jest.spyOn(client, "sendReadReceipt").mockResolvedValue({});
jest.spyOn(client, "getRooms").mockReturnValue([room]);

View File

@ -36,7 +36,7 @@ describe("pillify", () => {
beforeEach(() => {
stubClient();
const cli = MatrixClientPeg.get();
const cli = MatrixClientPeg.safeGet();
(cli.getRoom as jest.Mock).mockReturnValue(new Room(roomId, cli, cli.getUserId()!));
cli.pushRules!.global = {
override: [
@ -69,7 +69,7 @@ describe("pillify", () => {
const { container } = render(<div />);
const originalHtml = container.outerHTML;
const containers: Element[] = [];
pillifyLinks(MatrixClientPeg.get(), [container], event, containers);
pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers);
expect(containers).toHaveLength(0);
expect(container.outerHTML).toEqual(originalHtml);
});
@ -77,7 +77,7 @@ describe("pillify", () => {
it("should pillify @room", () => {
const { container } = render(<div>@room</div>);
const containers: Element[] = [];
pillifyLinks(MatrixClientPeg.get(), [container], event, containers);
pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers);
expect(containers).toHaveLength(1);
expect(container.querySelector(".mx_Pill.mx_AtRoomPill")?.textContent).toBe("!@room");
});
@ -85,10 +85,10 @@ describe("pillify", () => {
it("should not double up pillification on repeated calls", () => {
const { container } = render(<div>@room</div>);
const containers: Element[] = [];
pillifyLinks(MatrixClientPeg.get(), [container], event, containers);
pillifyLinks(MatrixClientPeg.get(), [container], event, containers);
pillifyLinks(MatrixClientPeg.get(), [container], event, containers);
pillifyLinks(MatrixClientPeg.get(), [container], event, containers);
pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers);
pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers);
pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers);
pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers);
expect(containers).toHaveLength(1);
expect(container.querySelector(".mx_Pill.mx_AtRoomPill")?.textContent).toBe("!@room");
});

View File

@ -48,7 +48,7 @@ describe("textForVoiceBroadcastStoppedEvent", () => {
};
}
return render(<div>{textForVoiceBroadcastStoppedEvent(event)()}</div>);
return render(<div>{textForVoiceBroadcastStoppedEvent(event, client)()}</div>);
};
beforeEach(() => {