Merge branch 'develop' into johannes/find-myself
This commit is contained in:
commit
d0e9331f07
612 changed files with 3608 additions and 2769 deletions
|
@ -83,7 +83,7 @@ describe("avatarUrlForRoom", () => {
|
|||
|
||||
it("should return null if there is no other member in the room", () => {
|
||||
mocked(dmRoomMap).getUserIdForRoomId.mockReturnValue("@user:example.com");
|
||||
mocked(room.getAvatarFallbackMember).mockReturnValue(null);
|
||||
mocked(room.getAvatarFallbackMember).mockReturnValue(undefined);
|
||||
expect(avatarUrlForRoom(room, 128, 128)).toBeNull();
|
||||
});
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ describe("LegacyCallHandler", () => {
|
|||
return [];
|
||||
}
|
||||
},
|
||||
} as DMRoomMap;
|
||||
} as unknown as DMRoomMap;
|
||||
DMRoomMap.setShared(dmRoomMap);
|
||||
|
||||
pstnLookup = null;
|
||||
|
|
|
@ -266,7 +266,7 @@ describe("Notifier", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("_displayPopupNotification", () => {
|
||||
describe("displayPopupNotification", () => {
|
||||
const testCases: { event: IContent | undefined; count: number }[] = [
|
||||
{ event: { is_silenced: true }, count: 0 },
|
||||
{ event: { is_silenced: false }, count: 1 },
|
||||
|
@ -274,13 +274,13 @@ describe("Notifier", () => {
|
|||
];
|
||||
it.each(testCases)("does not dispatch when notifications are silenced", ({ event, count }) => {
|
||||
mockClient.setAccountData(accountDataEventKey, event!);
|
||||
Notifier._displayPopupNotification(testEvent, testRoom);
|
||||
Notifier.displayPopupNotification(testEvent, testRoom);
|
||||
expect(MockPlatform.displayNotification).toHaveBeenCalledTimes(count);
|
||||
});
|
||||
|
||||
it("should display a notification for a voice message", () => {
|
||||
const audioEvent = mkAudioEvent();
|
||||
Notifier._displayPopupNotification(audioEvent, testRoom);
|
||||
Notifier.displayPopupNotification(audioEvent, testRoom);
|
||||
expect(MockPlatform.displayNotification).toHaveBeenCalledWith(
|
||||
"@user:example.com (!room1:server)",
|
||||
"@user:example.com: test audio message",
|
||||
|
@ -292,7 +292,7 @@ describe("Notifier", () => {
|
|||
|
||||
it("should display the expected notification for a broadcast chunk with sequence = 1", () => {
|
||||
const audioEvent = mkAudioEvent({ sequence: 1 });
|
||||
Notifier._displayPopupNotification(audioEvent, testRoom);
|
||||
Notifier.displayPopupNotification(audioEvent, testRoom);
|
||||
expect(MockPlatform.displayNotification).toHaveBeenCalledWith(
|
||||
"@user:example.com (!room1:server)",
|
||||
"@user:example.com started a voice broadcast",
|
||||
|
@ -304,7 +304,7 @@ describe("Notifier", () => {
|
|||
|
||||
it("should display the expected notification for a broadcast chunk with sequence = 1", () => {
|
||||
const audioEvent = mkAudioEvent({ sequence: 2 });
|
||||
Notifier._displayPopupNotification(audioEvent, testRoom);
|
||||
Notifier.displayPopupNotification(audioEvent, testRoom);
|
||||
expect(MockPlatform.displayNotification).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -330,7 +330,7 @@ describe("Notifier", () => {
|
|||
Notifier.getSoundForRoom = jest.fn();
|
||||
|
||||
mockClient.setAccountData(accountDataEventKey, event!);
|
||||
Notifier._playAudioNotification(testEvent, testRoom);
|
||||
Notifier.playAudioNotification(testEvent, testRoom);
|
||||
expect(Notifier.getSoundForRoom).toHaveBeenCalledTimes(count);
|
||||
});
|
||||
});
|
||||
|
@ -445,7 +445,7 @@ describe("Notifier", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("_evaluateEvent", () => {
|
||||
describe("evaluateEvent", () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(SdkContextClass.instance.roomViewStore, "getRoomId").mockReturnValue(testRoom.roomId);
|
||||
|
||||
|
@ -453,7 +453,7 @@ describe("Notifier", () => {
|
|||
|
||||
jest.spyOn(Modal, "hasDialogs").mockReturnValue(false);
|
||||
|
||||
jest.spyOn(Notifier, "_displayPopupNotification").mockReset();
|
||||
jest.spyOn(Notifier, "displayPopupNotification").mockReset();
|
||||
jest.spyOn(Notifier, "isEnabled").mockReturnValue(true);
|
||||
|
||||
mockClient.getPushActionsForEvent.mockReturnValue({
|
||||
|
@ -465,9 +465,9 @@ describe("Notifier", () => {
|
|||
});
|
||||
|
||||
it("should show a pop-up", () => {
|
||||
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
|
||||
Notifier._evaluateEvent(testEvent);
|
||||
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
|
||||
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(0);
|
||||
Notifier.evaluateEvent(testEvent);
|
||||
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(0);
|
||||
|
||||
const eventFromOtherRoom = mkEvent({
|
||||
event: true,
|
||||
|
@ -477,8 +477,8 @@ describe("Notifier", () => {
|
|||
content: {},
|
||||
});
|
||||
|
||||
Notifier._evaluateEvent(eventFromOtherRoom);
|
||||
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
|
||||
Notifier.evaluateEvent(eventFromOtherRoom);
|
||||
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should a pop-up for thread event", async () => {
|
||||
|
@ -489,13 +489,13 @@ describe("Notifier", () => {
|
|||
participantUserIds: ["@bob:example.org"],
|
||||
});
|
||||
|
||||
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
|
||||
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(0);
|
||||
|
||||
Notifier._evaluateEvent(rootEvent);
|
||||
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
|
||||
Notifier.evaluateEvent(rootEvent);
|
||||
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(0);
|
||||
|
||||
Notifier._evaluateEvent(events[1]);
|
||||
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
|
||||
Notifier.evaluateEvent(events[1]);
|
||||
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(1);
|
||||
|
||||
dis.dispatch<ThreadPayload>({
|
||||
action: Action.ViewThread,
|
||||
|
@ -504,13 +504,13 @@ describe("Notifier", () => {
|
|||
|
||||
await waitFor(() => expect(SdkContextClass.instance.roomViewStore.getThreadId()).toBe(rootEvent.getId()));
|
||||
|
||||
Notifier._evaluateEvent(events[1]);
|
||||
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
|
||||
Notifier.evaluateEvent(events[1]);
|
||||
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should show a pop-up for an audio message", () => {
|
||||
Notifier._evaluateEvent(mkAudioEvent());
|
||||
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
|
||||
Notifier.evaluateEvent(mkAudioEvent());
|
||||
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should not show a notification for broadcast info events in any case", () => {
|
||||
|
@ -527,8 +527,8 @@ describe("Notifier", () => {
|
|||
"ABC123",
|
||||
);
|
||||
|
||||
Notifier._evaluateEvent(broadcastStartedEvent);
|
||||
expect(Notifier._displayPopupNotification).not.toHaveBeenCalled();
|
||||
Notifier.evaluateEvent(broadcastStartedEvent);
|
||||
expect(Notifier.displayPopupNotification).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ export interface ITestEvent extends IPosthogEvent {
|
|||
|
||||
describe("PosthogAnalytics", () => {
|
||||
let fakePosthog: PostHog;
|
||||
const shaHashes = {
|
||||
const shaHashes: Record<string, string> = {
|
||||
"42": "73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049",
|
||||
"some": "a6b46dd0d1ae5e86cbc8f37e75ceeb6760230c1ca4ffbcb0c97b96dd7d9c464b",
|
||||
"pii": "bd75b3e080945674c0351f75e0db33d1e90986fa07b318ea7edf776f5eef38d4",
|
||||
|
@ -54,7 +54,7 @@ describe("PosthogAnalytics", () => {
|
|||
|
||||
window.crypto = {
|
||||
subtle: {
|
||||
digest: async (_, encodedMessage) => {
|
||||
digest: async (_: AlgorithmIdentifier, encodedMessage: BufferSource) => {
|
||||
const message = new TextDecoder().decode(encodedMessage);
|
||||
const hexHash = shaHashes[message];
|
||||
const bytes = [];
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
import { mocked } from "jest-mock";
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import ScalarAuthClient from "../src/ScalarAuthClient";
|
||||
import { stubClient } from "./test-utils";
|
||||
|
@ -32,7 +33,7 @@ describe("ScalarAuthClient", function () {
|
|||
expires_in: 999,
|
||||
};
|
||||
|
||||
let client;
|
||||
let client: MatrixClient;
|
||||
beforeEach(function () {
|
||||
jest.clearAllMocks();
|
||||
client = stubClient();
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import { EventType, MatrixClient, MatrixEvent, Room, RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
import TestRenderer from "react-test-renderer";
|
||||
import { ReactElement } from "react";
|
||||
import { mocked } from "jest-mock";
|
||||
import { Mocked, mocked } from "jest-mock";
|
||||
|
||||
import { textForEvent } from "../src/TextForEvent";
|
||||
import SettingsStore from "../src/settings/SettingsStore";
|
||||
|
@ -49,8 +49,14 @@ function mockPinnedEvent(pinnedMessageIds?: string[], prevPinnedMessageIds?: str
|
|||
// Helper function that renders a component to a plain text string.
|
||||
// Once snapshots are introduced in tests, this function will no longer be necessary,
|
||||
// and should be replaced with snapshots.
|
||||
function renderComponent(component): string {
|
||||
const serializeObject = (object): string => {
|
||||
function renderComponent(component: TestRenderer.ReactTestRenderer): string {
|
||||
const serializeObject = (
|
||||
object:
|
||||
| TestRenderer.ReactTestRendererJSON
|
||||
| TestRenderer.ReactTestRendererJSON[]
|
||||
| TestRenderer.ReactTestRendererNode
|
||||
| TestRenderer.ReactTestRendererNode[],
|
||||
): string => {
|
||||
if (typeof object === "string") {
|
||||
return object === " " ? "" : object;
|
||||
}
|
||||
|
@ -59,8 +65,8 @@ function renderComponent(component): string {
|
|||
return object[0];
|
||||
}
|
||||
|
||||
if (object["type"] !== undefined && typeof object["children"] !== undefined) {
|
||||
return serializeObject(object.children);
|
||||
if (!Array.isArray(object) && object["type"] !== undefined && typeof object["children"] !== undefined) {
|
||||
return serializeObject(object.children!);
|
||||
}
|
||||
|
||||
if (!Array.isArray(object)) {
|
||||
|
@ -74,7 +80,7 @@ function renderComponent(component): string {
|
|||
.join("");
|
||||
};
|
||||
|
||||
return serializeObject(component.toJSON());
|
||||
return serializeObject(component.toJSON()!);
|
||||
}
|
||||
|
||||
describe("TextForEvent", () => {
|
||||
|
@ -168,26 +174,26 @@ describe("TextForEvent", () => {
|
|||
});
|
||||
|
||||
describe("textForPowerEvent()", () => {
|
||||
let mockClient;
|
||||
let mockClient: Mocked<MatrixClient>;
|
||||
const mockRoom = {
|
||||
getMember: jest.fn(),
|
||||
};
|
||||
} as unknown as Mocked<Room>;
|
||||
|
||||
const userA = {
|
||||
id: "@a",
|
||||
userId: "@a",
|
||||
name: "Alice",
|
||||
rawDisplayName: "Alice",
|
||||
};
|
||||
} as RoomMember;
|
||||
const userB = {
|
||||
id: "@b",
|
||||
userId: "@b",
|
||||
name: "Bob (@b)",
|
||||
rawDisplayName: "Bob",
|
||||
};
|
||||
} as RoomMember;
|
||||
const userC = {
|
||||
id: "@c",
|
||||
userId: "@c",
|
||||
name: "Bob (@c)",
|
||||
rawDisplayName: "Bob",
|
||||
};
|
||||
} as RoomMember;
|
||||
interface PowerEventProps {
|
||||
usersDefault?: number;
|
||||
prevDefault?: number;
|
||||
|
@ -197,7 +203,7 @@ describe("TextForEvent", () => {
|
|||
const mockPowerEvent = ({ usersDefault, prevDefault, users, prevUsers }: PowerEventProps): MatrixEvent => {
|
||||
const mxEvent = new MatrixEvent({
|
||||
type: EventType.RoomPowerLevels,
|
||||
sender: userA.id,
|
||||
sender: userA.userId,
|
||||
state_key: "",
|
||||
content: {
|
||||
users_default: usersDefault,
|
||||
|
@ -213,12 +219,12 @@ describe("TextForEvent", () => {
|
|||
};
|
||||
|
||||
beforeAll(() => {
|
||||
mockClient = createTestClient();
|
||||
mockClient = createTestClient() as Mocked<MatrixClient>;
|
||||
MatrixClientPeg.get = () => mockClient;
|
||||
mockClient.getRoom.mockClear().mockReturnValue(mockRoom);
|
||||
mockRoom.getMember
|
||||
.mockClear()
|
||||
.mockImplementation((userId) => [userA, userB, userC].find((u) => u.id === userId));
|
||||
.mockImplementation((userId) => [userA, userB, userC].find((u) => u.userId === userId) || null);
|
||||
(SettingsStore.getValue as jest.Mock).mockReturnValue(true);
|
||||
});
|
||||
|
||||
|
@ -231,10 +237,10 @@ describe("TextForEvent", () => {
|
|||
it("returns falsy when no users have changed power level", () => {
|
||||
const event = mockPowerEvent({
|
||||
users: {
|
||||
[userA.id]: 100,
|
||||
[userA.userId]: 100,
|
||||
},
|
||||
prevUsers: {
|
||||
[userA.id]: 100,
|
||||
[userA.userId]: 100,
|
||||
},
|
||||
});
|
||||
expect(textForEvent(event)).toBeFalsy();
|
||||
|
@ -245,10 +251,10 @@ describe("TextForEvent", () => {
|
|||
usersDefault: 100,
|
||||
prevDefault: 50,
|
||||
users: {
|
||||
[userA.id]: 100,
|
||||
[userA.userId]: 100,
|
||||
},
|
||||
prevUsers: {
|
||||
[userA.id]: 50,
|
||||
[userA.userId]: 50,
|
||||
},
|
||||
});
|
||||
expect(textForEvent(event)).toBeFalsy();
|
||||
|
@ -257,10 +263,10 @@ describe("TextForEvent", () => {
|
|||
it("returns correct message for a single user with changed power level", () => {
|
||||
const event = mockPowerEvent({
|
||||
users: {
|
||||
[userB.id]: 100,
|
||||
[userB.userId]: 100,
|
||||
},
|
||||
prevUsers: {
|
||||
[userB.id]: 50,
|
||||
[userB.userId]: 50,
|
||||
},
|
||||
});
|
||||
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Admin.";
|
||||
|
@ -272,10 +278,10 @@ describe("TextForEvent", () => {
|
|||
usersDefault: 20,
|
||||
prevDefault: 101,
|
||||
users: {
|
||||
[userB.id]: 20,
|
||||
[userB.userId]: 20,
|
||||
},
|
||||
prevUsers: {
|
||||
[userB.id]: 50,
|
||||
[userB.userId]: 50,
|
||||
},
|
||||
});
|
||||
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Default.";
|
||||
|
@ -285,10 +291,10 @@ describe("TextForEvent", () => {
|
|||
it("returns correct message for a single user with power level changed to a custom level", () => {
|
||||
const event = mockPowerEvent({
|
||||
users: {
|
||||
[userB.id]: -1,
|
||||
[userB.userId]: -1,
|
||||
},
|
||||
prevUsers: {
|
||||
[userB.id]: 50,
|
||||
[userB.userId]: 50,
|
||||
},
|
||||
});
|
||||
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Custom (-1).";
|
||||
|
@ -298,12 +304,12 @@ describe("TextForEvent", () => {
|
|||
it("returns correct message for a multiple power level changes", () => {
|
||||
const event = mockPowerEvent({
|
||||
users: {
|
||||
[userB.id]: 100,
|
||||
[userC.id]: 50,
|
||||
[userB.userId]: 100,
|
||||
[userC.userId]: 50,
|
||||
},
|
||||
prevUsers: {
|
||||
[userB.id]: 50,
|
||||
[userC.id]: 101,
|
||||
[userB.userId]: 50,
|
||||
[userC.userId]: 101,
|
||||
},
|
||||
});
|
||||
const expectedText =
|
||||
|
@ -315,7 +321,7 @@ describe("TextForEvent", () => {
|
|||
|
||||
describe("textForCanonicalAliasEvent()", () => {
|
||||
const userA = {
|
||||
id: "@a",
|
||||
userId: "@a",
|
||||
name: "Alice",
|
||||
};
|
||||
|
||||
|
@ -328,7 +334,7 @@ describe("TextForEvent", () => {
|
|||
const mockEvent = ({ alias, prevAlias, altAliases, prevAltAliases }: AliasEventProps): MatrixEvent =>
|
||||
new MatrixEvent({
|
||||
type: EventType.RoomCanonicalAlias,
|
||||
sender: userA.id,
|
||||
sender: userA.userId,
|
||||
state_key: "",
|
||||
content: {
|
||||
alias,
|
||||
|
@ -418,7 +424,7 @@ describe("TextForEvent", () => {
|
|||
});
|
||||
|
||||
describe("textForPollStartEvent()", () => {
|
||||
let pollEvent;
|
||||
let pollEvent: MatrixEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
pollEvent = new MatrixEvent({
|
||||
|
@ -449,7 +455,7 @@ describe("TextForEvent", () => {
|
|||
});
|
||||
|
||||
describe("textForMessageEvent()", () => {
|
||||
let messageEvent;
|
||||
let messageEvent: MatrixEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
messageEvent = new MatrixEvent({
|
||||
|
|
|
@ -20,34 +20,32 @@ import EventEmitter from "events";
|
|||
import UserActivity from "../src/UserActivity";
|
||||
|
||||
class FakeDomEventEmitter extends EventEmitter {
|
||||
addEventListener(what, l) {
|
||||
addEventListener(what: string, l: (...args: any[]) => void) {
|
||||
this.on(what, l);
|
||||
}
|
||||
|
||||
removeEventListener(what, l) {
|
||||
removeEventListener(what: string, l: (...args: any[]) => void) {
|
||||
this.removeListener(what, l);
|
||||
}
|
||||
}
|
||||
|
||||
describe("UserActivity", function () {
|
||||
let fakeWindow;
|
||||
let fakeDocument;
|
||||
let userActivity;
|
||||
let clock;
|
||||
let fakeWindow: FakeDomEventEmitter;
|
||||
let fakeDocument: FakeDomEventEmitter & { hasFocus?(): boolean };
|
||||
let userActivity: UserActivity;
|
||||
let clock: FakeTimers.InstalledClock;
|
||||
|
||||
beforeEach(function () {
|
||||
fakeWindow = new FakeDomEventEmitter();
|
||||
fakeDocument = new FakeDomEventEmitter();
|
||||
userActivity = new UserActivity(fakeWindow, fakeDocument);
|
||||
userActivity = new UserActivity(fakeWindow as unknown as Window, fakeDocument as unknown as Document);
|
||||
userActivity.start();
|
||||
clock = FakeTimers.install();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
userActivity.stop();
|
||||
userActivity = null;
|
||||
clock.uninstall();
|
||||
clock = null;
|
||||
});
|
||||
|
||||
it("should return the same shared instance", function () {
|
||||
|
@ -65,7 +63,7 @@ describe("UserActivity", function () {
|
|||
it("should not consider user active after activity if no window focus", function () {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(false);
|
||||
|
||||
userActivity.onUserActivity({});
|
||||
userActivity.onUserActivity({ type: "event" } as Event);
|
||||
expect(userActivity.userActiveNow()).toBe(false);
|
||||
expect(userActivity.userActiveRecently()).toBe(false);
|
||||
});
|
||||
|
@ -73,7 +71,7 @@ describe("UserActivity", function () {
|
|||
it("should consider user active shortly after activity", function () {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity.onUserActivity({});
|
||||
userActivity.onUserActivity({ type: "event" } as Event);
|
||||
expect(userActivity.userActiveNow()).toBe(true);
|
||||
expect(userActivity.userActiveRecently()).toBe(true);
|
||||
clock.tick(200);
|
||||
|
@ -84,7 +82,7 @@ describe("UserActivity", function () {
|
|||
it("should consider user not active after 10s of no activity", function () {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity.onUserActivity({});
|
||||
userActivity.onUserActivity({ type: "event" } as Event);
|
||||
clock.tick(10000);
|
||||
expect(userActivity.userActiveNow()).toBe(false);
|
||||
});
|
||||
|
@ -92,7 +90,7 @@ describe("UserActivity", function () {
|
|||
it("should consider user passive after 10s of no activity", function () {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity.onUserActivity({});
|
||||
userActivity.onUserActivity({ type: "event" } as Event);
|
||||
clock.tick(10000);
|
||||
expect(userActivity.userActiveRecently()).toBe(true);
|
||||
});
|
||||
|
@ -100,7 +98,7 @@ describe("UserActivity", function () {
|
|||
it("should not consider user passive after 10s if window un-focused", function () {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity.onUserActivity({});
|
||||
userActivity.onUserActivity({ type: "event" } as Event);
|
||||
clock.tick(10000);
|
||||
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(false);
|
||||
|
@ -112,7 +110,7 @@ describe("UserActivity", function () {
|
|||
it("should not consider user passive after 3 mins", function () {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity.onUserActivity({});
|
||||
userActivity.onUserActivity({ type: "event" } as Event);
|
||||
clock.tick(3 * 60 * 1000);
|
||||
|
||||
expect(userActivity.userActiveRecently()).toBe(false);
|
||||
|
@ -121,11 +119,11 @@ describe("UserActivity", function () {
|
|||
it("should extend timer on activity", function () {
|
||||
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
|
||||
|
||||
userActivity.onUserActivity({});
|
||||
userActivity.onUserActivity({ type: "event" } as Event);
|
||||
clock.tick(1 * 60 * 1000);
|
||||
userActivity.onUserActivity({});
|
||||
userActivity.onUserActivity({ type: "event" } as Event);
|
||||
clock.tick(1 * 60 * 1000);
|
||||
userActivity.onUserActivity({});
|
||||
userActivity.onUserActivity({ type: "event" } as Event);
|
||||
clock.tick(1 * 60 * 1000);
|
||||
|
||||
expect(userActivity.userActiveRecently()).toBe(true);
|
||||
|
|
|
@ -20,7 +20,7 @@ import { mockPlatformPeg, unmockPlatformPeg } from "../test-utils";
|
|||
const PATH_TO_KEYBOARD_SHORTCUTS = "../../src/accessibility/KeyboardShortcuts";
|
||||
const PATH_TO_KEYBOARD_SHORTCUT_UTILS = "../../src/accessibility/KeyboardShortcutUtils";
|
||||
|
||||
const mockKeyboardShortcuts = (override) => {
|
||||
const mockKeyboardShortcuts = (override: Record<string, any>) => {
|
||||
jest.doMock(PATH_TO_KEYBOARD_SHORTCUTS, () => {
|
||||
const original = jest.requireActual(PATH_TO_KEYBOARD_SHORTCUTS);
|
||||
return {
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import React, { HTMLAttributes } from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import {
|
||||
|
@ -26,8 +26,8 @@ import {
|
|||
useRovingTabIndex,
|
||||
} from "../../src/accessibility/RovingTabIndex";
|
||||
|
||||
const Button = (props) => {
|
||||
const [onFocus, isActive, ref] = useRovingTabIndex();
|
||||
const Button = (props: HTMLAttributes<HTMLButtonElement>) => {
|
||||
const [onFocus, isActive, ref] = useRovingTabIndex<HTMLButtonElement>();
|
||||
return <button {...props} onFocus={onFocus} tabIndex={isActive ? 0 : -1} ref={ref} />;
|
||||
};
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { EventEmitter } from "events";
|
||||
import { Room, RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixEvent, Room, RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
import FakeTimers from "@sinonjs/fake-timers";
|
||||
import { render } from "@testing-library/react";
|
||||
import { Thread } from "matrix-js-sdk/src/models/thread";
|
||||
|
@ -46,7 +46,7 @@ jest.mock("../../../src/utils/beacon", () => ({
|
|||
const roomId = "!roomId:server_name";
|
||||
|
||||
describe("MessagePanel", function () {
|
||||
let clock = null;
|
||||
let clock: FakeTimers.InstalledClock | null = null;
|
||||
const realSetTimeout = window.setTimeout;
|
||||
const events = mkEvents();
|
||||
const userId = "@me:here";
|
||||
|
@ -79,7 +79,7 @@ describe("MessagePanel", function () {
|
|||
callEventGroupers: new Map(),
|
||||
room,
|
||||
className: "cls",
|
||||
events: [],
|
||||
events: [] as MatrixEvent[],
|
||||
};
|
||||
|
||||
const defaultRoomContext = {
|
||||
|
@ -322,8 +322,8 @@ describe("MessagePanel", function () {
|
|||
];
|
||||
}
|
||||
|
||||
function isReadMarkerVisible(rmContainer) {
|
||||
return rmContainer && rmContainer.children.length > 0;
|
||||
function isReadMarkerVisible(rmContainer?: Element) {
|
||||
return rmContainer?.children.length > 0;
|
||||
}
|
||||
|
||||
it("should show the events", function () {
|
||||
|
|
|
@ -49,7 +49,7 @@ describe("<RoomSearchView/>", () => {
|
|||
stubClient();
|
||||
client = MatrixClientPeg.get();
|
||||
client.supportsThreads = jest.fn().mockReturnValue(true);
|
||||
room = new Room("!room:server", client, client.getUserId());
|
||||
room = new Room("!room:server", client, client.getUserId()!);
|
||||
mocked(client.getRoom).mockReturnValue(room);
|
||||
permalinkCreator = new RoomPermalinkCreator(room, room.roomId);
|
||||
|
||||
|
@ -92,7 +92,7 @@ describe("<RoomSearchView/>", () => {
|
|||
result: {
|
||||
room_id: room.roomId,
|
||||
event_id: "$2",
|
||||
sender: client.getUserId(),
|
||||
sender: client.getUserId()!,
|
||||
origin_server_ts: 1,
|
||||
content: { body: "Foo Test Bar", msgtype: "m.text" },
|
||||
type: EventType.RoomMessage,
|
||||
|
@ -103,7 +103,7 @@ describe("<RoomSearchView/>", () => {
|
|||
{
|
||||
room_id: room.roomId,
|
||||
event_id: "$1",
|
||||
sender: client.getUserId(),
|
||||
sender: client.getUserId()!,
|
||||
origin_server_ts: 1,
|
||||
content: { body: "Before", msgtype: "m.text" },
|
||||
type: EventType.RoomMessage,
|
||||
|
@ -113,7 +113,7 @@ describe("<RoomSearchView/>", () => {
|
|||
{
|
||||
room_id: room.roomId,
|
||||
event_id: "$3",
|
||||
sender: client.getUserId(),
|
||||
sender: client.getUserId()!,
|
||||
origin_server_ts: 1,
|
||||
content: { body: "After", msgtype: "m.text" },
|
||||
type: EventType.RoomMessage,
|
||||
|
@ -154,7 +154,7 @@ describe("<RoomSearchView/>", () => {
|
|||
result: {
|
||||
room_id: room.roomId,
|
||||
event_id: "$2",
|
||||
sender: client.getUserId(),
|
||||
sender: client.getUserId()!,
|
||||
origin_server_ts: 1,
|
||||
content: { body: "Foo Test Bar", msgtype: "m.text" },
|
||||
type: EventType.RoomMessage,
|
||||
|
@ -192,7 +192,7 @@ describe("<RoomSearchView/>", () => {
|
|||
result: {
|
||||
room_id: room.roomId,
|
||||
event_id: "$2",
|
||||
sender: client.getUserId(),
|
||||
sender: client.getUserId()!,
|
||||
origin_server_ts: 1,
|
||||
content: { body: "Foo Test Bar", msgtype: "m.text" },
|
||||
type: EventType.RoomMessage,
|
||||
|
@ -221,7 +221,7 @@ describe("<RoomSearchView/>", () => {
|
|||
result: {
|
||||
room_id: room.roomId,
|
||||
event_id: "$4",
|
||||
sender: client.getUserId(),
|
||||
sender: client.getUserId()!,
|
||||
origin_server_ts: 4,
|
||||
content: { body: "Potato", msgtype: "m.text" },
|
||||
type: EventType.RoomMessage,
|
||||
|
|
|
@ -55,6 +55,7 @@ const RoomView = wrapInMatrixClientContext(_RoomView);
|
|||
describe("RoomView", () => {
|
||||
let cli: MockedObject<MatrixClient>;
|
||||
let room: Room;
|
||||
let rooms: Map<string, Room>;
|
||||
let roomCount = 0;
|
||||
let stores: SdkContextClass;
|
||||
|
||||
|
@ -64,8 +65,11 @@ describe("RoomView", () => {
|
|||
cli = mocked(MatrixClientPeg.get());
|
||||
|
||||
room = new Room(`!${roomCount++}:example.org`, cli, "@alice:example.org");
|
||||
jest.spyOn(room, "findPredecessor");
|
||||
room.getPendingEvents = () => [];
|
||||
cli.getRoom.mockImplementation(() => room);
|
||||
rooms = new Map();
|
||||
rooms.set(room.roomId, room);
|
||||
cli.getRoom.mockImplementation((roomId: string | undefined) => rooms.get(roomId || "") || null);
|
||||
// Re-emit certain events on the mocked client
|
||||
room.on(RoomEvent.Timeline, (...args) => cli.emit(RoomEvent.Timeline, ...args));
|
||||
room.on(RoomEvent.TimelineReset, (...args) => cli.emit(RoomEvent.TimelineReset, ...args));
|
||||
|
@ -158,6 +162,42 @@ describe("RoomView", () => {
|
|||
const getRoomViewInstance = async (): Promise<_RoomView> =>
|
||||
(await mountRoomView()).find(_RoomView).instance() as _RoomView;
|
||||
|
||||
it("when there is no room predecessor, getHiddenHighlightCount should return 0", async () => {
|
||||
const instance = await getRoomViewInstance();
|
||||
expect(instance.getHiddenHighlightCount()).toBe(0);
|
||||
});
|
||||
|
||||
describe("when there is an old room", () => {
|
||||
let instance: _RoomView;
|
||||
let oldRoom: Room;
|
||||
|
||||
beforeEach(async () => {
|
||||
instance = await getRoomViewInstance();
|
||||
oldRoom = new Room("!old:example.com", cli, cli.getSafeUserId());
|
||||
rooms.set(oldRoom.roomId, oldRoom);
|
||||
jest.spyOn(room, "findPredecessor").mockReturnValue({ roomId: oldRoom.roomId, eventId: null });
|
||||
});
|
||||
|
||||
it("and it has 0 unreads, getHiddenHighlightCount should return 0", async () => {
|
||||
jest.spyOn(oldRoom, "getUnreadNotificationCount").mockReturnValue(0);
|
||||
expect(instance.getHiddenHighlightCount()).toBe(0);
|
||||
// assert that msc3946ProcessDynamicPredecessor is false by default
|
||||
expect(room.findPredecessor).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it("and it has 23 unreads, getHiddenHighlightCount should return 23", async () => {
|
||||
jest.spyOn(oldRoom, "getUnreadNotificationCount").mockReturnValue(23);
|
||||
expect(instance.getHiddenHighlightCount()).toBe(23);
|
||||
});
|
||||
|
||||
it("and feature_dynamic_room_predecessors is enabled it should pass the setting to findPredecessor", async () => {
|
||||
SettingsStore.setValue("feature_dynamic_room_predecessors", null, SettingLevel.DEVICE, true);
|
||||
expect(instance.getHiddenHighlightCount()).toBe(0);
|
||||
expect(room.findPredecessor).toHaveBeenCalledWith(true);
|
||||
SettingsStore.setValue("feature_dynamic_room_predecessors", null, SettingLevel.DEVICE, null);
|
||||
});
|
||||
});
|
||||
|
||||
it("updates url preview visibility on encryption state change", async () => {
|
||||
// we should be starting unencrypted
|
||||
expect(cli.isCryptoEnabled()).toEqual(false);
|
||||
|
@ -248,6 +288,7 @@ describe("RoomView", () => {
|
|||
|
||||
beforeEach(async () => {
|
||||
localRoom = room = await createDmLocalRoom(cli, [new DirectoryMember({ user_id: "@user:example.com" })]);
|
||||
rooms.set(localRoom.roomId, localRoom);
|
||||
cli.store.storeRoom(room);
|
||||
});
|
||||
|
||||
|
|
|
@ -43,20 +43,20 @@ describe("<TabbedView />", () => {
|
|||
|
||||
it("renders first tab as active tab when no initialTabId", () => {
|
||||
const { container } = render(getComponent());
|
||||
expect(getActiveTab(container).textContent).toEqual(generalTab.label);
|
||||
expect(getActiveTabBody(container).textContent).toEqual("general");
|
||||
expect(getActiveTab(container)?.textContent).toEqual(generalTab.label);
|
||||
expect(getActiveTabBody(container)?.textContent).toEqual("general");
|
||||
});
|
||||
|
||||
it("renders first tab as active tab when initialTabId is not valid", () => {
|
||||
const { container } = render(getComponent({ initialTabId: "bad-tab-id" }));
|
||||
expect(getActiveTab(container).textContent).toEqual(generalTab.label);
|
||||
expect(getActiveTabBody(container).textContent).toEqual("general");
|
||||
expect(getActiveTab(container)?.textContent).toEqual(generalTab.label);
|
||||
expect(getActiveTabBody(container)?.textContent).toEqual("general");
|
||||
});
|
||||
|
||||
it("renders initialTabId tab as active when valid", () => {
|
||||
const { container } = render(getComponent({ initialTabId: securityTab.id }));
|
||||
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
|
||||
expect(getActiveTabBody(container).textContent).toEqual("security");
|
||||
expect(getActiveTab(container)?.textContent).toEqual(securityTab.label);
|
||||
expect(getActiveTabBody(container)?.textContent).toEqual("security");
|
||||
});
|
||||
|
||||
it("renders without error when there are no tabs", () => {
|
||||
|
@ -71,8 +71,8 @@ describe("<TabbedView />", () => {
|
|||
fireEvent.click(getByTestId(getTabTestId(securityTab)));
|
||||
});
|
||||
|
||||
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
|
||||
expect(getActiveTabBody(container).textContent).toEqual("security");
|
||||
expect(getActiveTab(container)?.textContent).toEqual(securityTab.label);
|
||||
expect(getActiveTabBody(container)?.textContent).toEqual("security");
|
||||
});
|
||||
|
||||
it("calls onchange on on tab click", () => {
|
||||
|
@ -90,29 +90,29 @@ describe("<TabbedView />", () => {
|
|||
// start with middle tab active
|
||||
const { container, rerender } = render(getComponent({ initialTabId: labsTab.id }));
|
||||
|
||||
expect(getActiveTab(container).textContent).toEqual(labsTab.label);
|
||||
expect(getActiveTab(container)?.textContent).toEqual(labsTab.label);
|
||||
|
||||
rerender(getComponent({ tabs: [labsTab, generalTab, securityTab] }));
|
||||
|
||||
// labs tab still active
|
||||
expect(getActiveTab(container).textContent).toEqual(labsTab.label);
|
||||
expect(getActiveTab(container)?.textContent).toEqual(labsTab.label);
|
||||
});
|
||||
|
||||
it("does not reactivate inititalTabId on rerender", () => {
|
||||
const { container, getByTestId, rerender } = render(getComponent());
|
||||
|
||||
expect(getActiveTab(container).textContent).toEqual(generalTab.label);
|
||||
expect(getActiveTab(container)?.textContent).toEqual(generalTab.label);
|
||||
|
||||
// make security tab active
|
||||
act(() => {
|
||||
fireEvent.click(getByTestId(getTabTestId(securityTab)));
|
||||
});
|
||||
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
|
||||
expect(getActiveTab(container)?.textContent).toEqual(securityTab.label);
|
||||
|
||||
// rerender with new tab location
|
||||
rerender(getComponent({ tabLocation: TabLocation.TOP }));
|
||||
|
||||
// still security tab
|
||||
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
|
||||
expect(getActiveTab(container)?.textContent).toEqual(securityTab.label);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -83,7 +83,7 @@ describe("ThreadView", () => {
|
|||
return renderResult;
|
||||
}
|
||||
|
||||
async function sendMessage(container, text): Promise<void> {
|
||||
async function sendMessage(container: HTMLElement, text: string): Promise<void> {
|
||||
const composer = getByTestId(container, "basicmessagecomposer");
|
||||
await userEvent.click(composer);
|
||||
await userEvent.keyboard(text);
|
||||
|
@ -91,7 +91,7 @@ describe("ThreadView", () => {
|
|||
await userEvent.click(sendMessageBtn);
|
||||
}
|
||||
|
||||
function expectedMessageBody(rootEvent, message) {
|
||||
function expectedMessageBody(rootEvent: MatrixEvent, message: string) {
|
||||
return {
|
||||
"body": message,
|
||||
"m.relates_to": {
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import { mocked } from "jest-mock";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
@ -71,7 +71,7 @@ describe("<RecordingPlayback />", () => {
|
|||
mocked(createAudioContext).mockReturnValue(mockAudioContext as unknown as AudioContext);
|
||||
});
|
||||
|
||||
const getPlayButton = (component) => findByTestId(component, "play-pause-button").at(0);
|
||||
const getPlayButton = (component: ReactWrapper) => findByTestId(component, "play-pause-button").at(0);
|
||||
|
||||
it("renders recording playback", () => {
|
||||
const playback = new Playback(new ArrayBuffer(8));
|
||||
|
|
|
@ -19,7 +19,7 @@ import { mocked } from "jest-mock";
|
|||
import { MatrixClient, PendingEventOrdering } from "matrix-js-sdk/src/client";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
|
||||
import MemberAvatar from "../../../../src/components/views/avatars/MemberAvatar";
|
||||
import RoomContext from "../../../../src/contexts/RoomContext";
|
||||
|
@ -35,7 +35,7 @@ describe("MemberAvatar", () => {
|
|||
let room: Room;
|
||||
let member: RoomMember;
|
||||
|
||||
function getComponent(props) {
|
||||
function getComponent(props: Partial<ComponentProps<typeof MemberAvatar>>) {
|
||||
return (
|
||||
<RoomContext.Provider value={getRoomContext(room, {})}>
|
||||
<MemberAvatar member={null} width={35} height={35} {...props} />
|
||||
|
|
|
@ -101,7 +101,7 @@ describe("<BeaconViewDialog />", () => {
|
|||
|
||||
it("renders a map with markers", () => {
|
||||
const room = setupRoom([defaultEvent]);
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
||||
beacon.addLocations([location1]);
|
||||
const component = getComponent();
|
||||
expect(component.find("Map").props()).toEqual(
|
||||
|
@ -116,7 +116,7 @@ describe("<BeaconViewDialog />", () => {
|
|||
it("does not render any own beacon status when user is not live sharing", () => {
|
||||
// default event belongs to alice, we are bob
|
||||
const room = setupRoom([defaultEvent]);
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
||||
beacon.addLocations([location1]);
|
||||
const component = getComponent();
|
||||
expect(component.find("DialogOwnBeaconStatus").html()).toBeNull();
|
||||
|
@ -125,7 +125,7 @@ describe("<BeaconViewDialog />", () => {
|
|||
it("renders own beacon status when user is live sharing", () => {
|
||||
// default event belongs to alice
|
||||
const room = setupRoom([defaultEvent]);
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
||||
beacon.addLocations([location1]);
|
||||
// mock own beacon store to show default event as alice's live beacon
|
||||
jest.spyOn(OwnBeaconStore.instance, "getLiveBeaconIds").mockReturnValue([beacon.identifier]);
|
||||
|
@ -141,7 +141,7 @@ describe("<BeaconViewDialog />", () => {
|
|||
|
||||
it("updates markers on changes to beacons", () => {
|
||||
const room = setupRoom([defaultEvent]);
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
||||
beacon.addLocations([location1]);
|
||||
const component = getComponent();
|
||||
expect(component.find("BeaconMarker").length).toEqual(1);
|
||||
|
@ -161,7 +161,7 @@ describe("<BeaconViewDialog />", () => {
|
|||
|
||||
it("does not update bounds or center on changing beacons", () => {
|
||||
const room = setupRoom([defaultEvent]);
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
||||
beacon.addLocations([location1]);
|
||||
const component = getComponent();
|
||||
expect(component.find("BeaconMarker").length).toEqual(1);
|
||||
|
@ -200,7 +200,7 @@ describe("<BeaconViewDialog />", () => {
|
|||
it("renders map without markers when no live beacons remain", () => {
|
||||
const onFinished = jest.fn();
|
||||
const room = setupRoom([defaultEvent]);
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
||||
beacon.addLocations([location1]);
|
||||
const component = getComponent({ onFinished });
|
||||
expect(component.find("BeaconMarker").length).toEqual(1);
|
||||
|
@ -233,7 +233,7 @@ describe("<BeaconViewDialog />", () => {
|
|||
describe("sidebar", () => {
|
||||
it("opens sidebar on view list button click", () => {
|
||||
const room = setupRoom([defaultEvent]);
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
||||
beacon.addLocations([location1]);
|
||||
const component = getComponent();
|
||||
|
||||
|
@ -244,7 +244,7 @@ describe("<BeaconViewDialog />", () => {
|
|||
|
||||
it("closes sidebar on close button click", () => {
|
||||
const room = setupRoom([defaultEvent]);
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
||||
beacon.addLocations([location1]);
|
||||
const component = getComponent();
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { fireEvent, render } from "@testing-library/react";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
||||
|
@ -29,7 +29,7 @@ import {
|
|||
} from "../../../test-utils";
|
||||
|
||||
describe("<DialogSidebar />", () => {
|
||||
const defaultProps = {
|
||||
const defaultProps: ComponentProps<typeof DialogSidebar> = {
|
||||
beacons: [],
|
||||
requestClose: jest.fn(),
|
||||
onBeaconClick: jest.fn(),
|
||||
|
|
|
@ -15,16 +15,15 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import { mocked } from "jest-mock";
|
||||
import { Beacon } from "matrix-js-sdk/src/matrix";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
||||
import OwnBeaconStatus from "../../../../src/components/views/beacon/OwnBeaconStatus";
|
||||
import { BeaconDisplayStatus } from "../../../../src/components/views/beacon/displayStatus";
|
||||
import { useOwnLiveBeacons } from "../../../../src/utils/beacon";
|
||||
import { findByTestId, makeBeaconInfoEvent } from "../../../test-utils";
|
||||
import { makeBeaconInfoEvent } from "../../../test-utils";
|
||||
|
||||
jest.mock("../../../../src/utils/beacon/useOwnLiveBeacons", () => ({
|
||||
useOwnLiveBeacons: jest.fn(),
|
||||
|
@ -36,8 +35,11 @@ describe("<OwnBeaconStatus />", () => {
|
|||
};
|
||||
const userId = "@user:server";
|
||||
const roomId = "!room:server";
|
||||
let defaultBeacon;
|
||||
const getComponent = (props = {}) => mount(<OwnBeaconStatus {...defaultProps} {...props} />);
|
||||
let defaultBeacon: Beacon;
|
||||
const renderComponent = (props: Partial<React.ComponentProps<typeof OwnBeaconStatus>> = {}) =>
|
||||
render(<OwnBeaconStatus {...defaultProps} {...props} />);
|
||||
const getRetryButton = () => screen.getByRole("button", { name: "Retry" });
|
||||
const getStopButton = () => screen.getByRole("button", { name: "Stop" });
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(global.Date, "now").mockReturnValue(123456789);
|
||||
|
@ -47,13 +49,8 @@ describe("<OwnBeaconStatus />", () => {
|
|||
});
|
||||
|
||||
it("renders without a beacon instance", () => {
|
||||
const component = getComponent();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders loading state correctly", () => {
|
||||
const component = getComponent();
|
||||
expect(component.find("BeaconStatus").props()).toBeTruthy();
|
||||
const { asFragment } = renderComponent();
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe("Active state", () => {
|
||||
|
@ -62,24 +59,19 @@ describe("<OwnBeaconStatus />", () => {
|
|||
mocked(useOwnLiveBeacons).mockReturnValue({
|
||||
onStopSharing: jest.fn(),
|
||||
});
|
||||
const component = getComponent({ displayStatus, beacon: defaultBeacon });
|
||||
expect(component.text()).toContain("Live location enabled");
|
||||
|
||||
expect(findByTestId(component, "beacon-status-stop-beacon").length).toBeTruthy();
|
||||
renderComponent({ displayStatus, beacon: defaultBeacon });
|
||||
expect(screen.getByText("Live location enabled")).toBeInTheDocument();
|
||||
expect(getStopButton()).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("stops sharing on stop button click", () => {
|
||||
it("stops sharing on stop button click", async () => {
|
||||
const displayStatus = BeaconDisplayStatus.Active;
|
||||
const onStopSharing = jest.fn();
|
||||
mocked(useOwnLiveBeacons).mockReturnValue({
|
||||
onStopSharing,
|
||||
});
|
||||
const component = getComponent({ displayStatus, beacon: defaultBeacon });
|
||||
|
||||
act(() => {
|
||||
findByTestId(component, "beacon-status-stop-beacon").at(0).simulate("click");
|
||||
});
|
||||
|
||||
renderComponent({ displayStatus, beacon: defaultBeacon });
|
||||
await userEvent.click(getStopButton());
|
||||
expect(onStopSharing).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -87,11 +79,11 @@ describe("<OwnBeaconStatus />", () => {
|
|||
describe("errors", () => {
|
||||
it("renders in error mode when displayStatus is error", () => {
|
||||
const displayStatus = BeaconDisplayStatus.Error;
|
||||
const component = getComponent({ displayStatus });
|
||||
expect(component.text()).toEqual("Live location error");
|
||||
renderComponent({ displayStatus });
|
||||
expect(screen.getByText("Live location error")).toBeInTheDocument();
|
||||
|
||||
// no actions for plain error
|
||||
expect(component.find("AccessibleButton").length).toBeFalsy();
|
||||
expect(screen.queryByRole("button")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe("with location publish error", () => {
|
||||
|
@ -101,23 +93,21 @@ describe("<OwnBeaconStatus />", () => {
|
|||
hasLocationPublishError: true,
|
||||
onResetLocationPublishError: jest.fn(),
|
||||
});
|
||||
const component = getComponent({ displayStatus, beacon: defaultBeacon });
|
||||
expect(component.text()).toContain("Live location error");
|
||||
renderComponent({ displayStatus, beacon: defaultBeacon });
|
||||
expect(screen.getByText("Live location error")).toBeInTheDocument();
|
||||
// retry button
|
||||
expect(findByTestId(component, "beacon-status-reset-wire-error").length).toBeTruthy();
|
||||
expect(getRetryButton()).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("retry button resets location publish error", () => {
|
||||
it("retry button resets location publish error", async () => {
|
||||
const displayStatus = BeaconDisplayStatus.Active;
|
||||
const onResetLocationPublishError = jest.fn();
|
||||
mocked(useOwnLiveBeacons).mockReturnValue({
|
||||
hasLocationPublishError: true,
|
||||
onResetLocationPublishError,
|
||||
});
|
||||
const component = getComponent({ displayStatus, beacon: defaultBeacon });
|
||||
act(() => {
|
||||
findByTestId(component, "beacon-status-reset-wire-error").at(0).simulate("click");
|
||||
});
|
||||
renderComponent({ displayStatus, beacon: defaultBeacon });
|
||||
await userEvent.click(getRetryButton());
|
||||
|
||||
expect(onResetLocationPublishError).toHaveBeenCalled();
|
||||
});
|
||||
|
@ -131,23 +121,21 @@ describe("<OwnBeaconStatus />", () => {
|
|||
hasStopSharingError: true,
|
||||
onStopSharing: jest.fn(),
|
||||
});
|
||||
const component = getComponent({ displayStatus, beacon: defaultBeacon });
|
||||
expect(component.text()).toContain("Live location error");
|
||||
renderComponent({ displayStatus, beacon: defaultBeacon });
|
||||
expect(screen.getByText("Live location error")).toBeInTheDocument();
|
||||
// retry button
|
||||
expect(findByTestId(component, "beacon-status-stop-beacon-retry").length).toBeTruthy();
|
||||
expect(getRetryButton()).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("retry button retries stop sharing", () => {
|
||||
it("retry button retries stop sharing", async () => {
|
||||
const displayStatus = BeaconDisplayStatus.Active;
|
||||
const onStopSharing = jest.fn();
|
||||
mocked(useOwnLiveBeacons).mockReturnValue({
|
||||
hasStopSharingError: true,
|
||||
onStopSharing,
|
||||
});
|
||||
const component = getComponent({ displayStatus, beacon: defaultBeacon });
|
||||
act(() => {
|
||||
findByTestId(component, "beacon-status-stop-beacon-retry").at(0).simulate("click");
|
||||
});
|
||||
renderComponent({ displayStatus, beacon: defaultBeacon });
|
||||
await userEvent.click(getRetryButton());
|
||||
|
||||
expect(onStopSharing).toHaveBeenCalled();
|
||||
});
|
||||
|
@ -155,7 +143,7 @@ describe("<OwnBeaconStatus />", () => {
|
|||
});
|
||||
|
||||
it("renders loading state correctly", () => {
|
||||
const component = getComponent();
|
||||
const component = renderComponent();
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,27 +1,19 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<OwnBeaconStatus /> renders without a beacon instance 1`] = `
|
||||
<OwnBeaconStatus
|
||||
displayStatus="Loading"
|
||||
>
|
||||
<BeaconStatus
|
||||
displayLiveTimeRemaining={true}
|
||||
displayStatus="Loading"
|
||||
label="Live location enabled"
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_BeaconStatus mx_BeaconStatus_Loading"
|
||||
>
|
||||
<div
|
||||
className="mx_BeaconStatus mx_BeaconStatus_Loading"
|
||||
class="mx_BeaconStatus_description"
|
||||
>
|
||||
<div
|
||||
className="mx_BeaconStatus_description"
|
||||
<span
|
||||
class="mx_BeaconStatus_description_status"
|
||||
>
|
||||
<span
|
||||
className="mx_BeaconStatus_description_status"
|
||||
>
|
||||
Loading live location...
|
||||
</span>
|
||||
</div>
|
||||
Loading live location...
|
||||
</span>
|
||||
</div>
|
||||
</BeaconStatus>
|
||||
</OwnBeaconStatus>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { IPassphraseInfo } from "matrix-js-sdk/src/crypto/api";
|
||||
import { act, fireEvent, render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
@ -29,7 +29,7 @@ const securityKey = "EsTc WKmb ivvk jLS7 Y1NH 5CcQ mP1E JJwj B3Fd pFWm t4Dp dbyu
|
|||
describe("AccessSecretStorageDialog", () => {
|
||||
let mockClient: Mocked<MatrixClient>;
|
||||
|
||||
const defaultProps = {
|
||||
const defaultProps: ComponentProps<typeof AccessSecretStorageDialog> = {
|
||||
onFinished: jest.fn(),
|
||||
checkPrivateKey: jest.fn(),
|
||||
keyInfo: undefined,
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import { mocked } from "jest-mock";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
|
@ -60,42 +60,43 @@ describe("<ExportDialog />", () => {
|
|||
|
||||
const getComponent = (props = {}) => mount(<ExportDialog {...defaultProps} {...props} />);
|
||||
|
||||
const getSizeInput = (component) => component.find('input[id="size-limit"]');
|
||||
const getExportTypeInput = (component) => component.find('select[id="export-type"]');
|
||||
const getAttachmentsCheckbox = (component) => component.find('input[id="include-attachments"]');
|
||||
const getMessageCountInput = (component) => component.find('input[id="message-count"]');
|
||||
const getExportFormatInput = (component, format) => component.find(`input[id="exportFormat-${format}"]`);
|
||||
const getPrimaryButton = (component) => component.find('[data-testid="dialog-primary-button"]');
|
||||
const getSecondaryButton = (component) => component.find('[data-testid="dialog-cancel-button"]');
|
||||
const getSizeInput = (component: ReactWrapper) => component.find('input[id="size-limit"]');
|
||||
const getExportTypeInput = (component: ReactWrapper) => component.find('select[id="export-type"]');
|
||||
const getAttachmentsCheckbox = (component: ReactWrapper) => component.find('input[id="include-attachments"]');
|
||||
const getMessageCountInput = (component: ReactWrapper) => component.find('input[id="message-count"]');
|
||||
const getExportFormatInput = (component: ReactWrapper, format: ExportFormat) =>
|
||||
component.find(`input[id="exportFormat-${format}"]`);
|
||||
const getPrimaryButton = (component: ReactWrapper) => component.find('[data-testid="dialog-primary-button"]');
|
||||
const getSecondaryButton = (component: ReactWrapper) => component.find('[data-testid="dialog-cancel-button"]');
|
||||
|
||||
const submitForm = async (component) =>
|
||||
const submitForm = async (component: ReactWrapper) =>
|
||||
act(async () => {
|
||||
getPrimaryButton(component).simulate("click");
|
||||
component.setProps({});
|
||||
});
|
||||
const selectExportFormat = async (component, format: ExportFormat) =>
|
||||
const selectExportFormat = async (component: ReactWrapper, format: ExportFormat) =>
|
||||
act(async () => {
|
||||
getExportFormatInput(component, format).simulate("change");
|
||||
component.setProps({});
|
||||
});
|
||||
const selectExportType = async (component, type: ExportType) =>
|
||||
const selectExportType = async (component: ReactWrapper, type: ExportType) =>
|
||||
act(async () => {
|
||||
getExportTypeInput(component).simulate("change", { target: { value: type } });
|
||||
component.setProps({});
|
||||
});
|
||||
const setMessageCount = async (component, count: number) =>
|
||||
const setMessageCount = async (component: ReactWrapper, count: number) =>
|
||||
act(async () => {
|
||||
getMessageCountInput(component).simulate("change", { target: { value: count } });
|
||||
component.setProps({});
|
||||
});
|
||||
|
||||
const setSizeLimit = async (component, limit: number) =>
|
||||
const setSizeLimit = async (component: ReactWrapper, limit: number) =>
|
||||
act(async () => {
|
||||
getSizeInput(component).simulate("change", { target: { value: limit } });
|
||||
component.setProps({});
|
||||
});
|
||||
|
||||
const setIncludeAttachments = async (component, checked) =>
|
||||
const setIncludeAttachments = async (component: ReactWrapper, checked: boolean) =>
|
||||
act(async () => {
|
||||
getAttachmentsCheckbox(component).simulate("change", { target: { checked } });
|
||||
component.setProps({});
|
||||
|
|
|
@ -125,8 +125,8 @@ describe("ForwardDialog", () => {
|
|||
const { container } = mountForwardDialog();
|
||||
|
||||
// Make sendEvent require manual resolution so we can see the sending state
|
||||
let finishSend;
|
||||
let cancelSend;
|
||||
let finishSend: (arg?: any) => void;
|
||||
let cancelSend: () => void;
|
||||
mockClient.sendEvent.mockImplementation(
|
||||
<T extends {}>() =>
|
||||
new Promise<T>((resolve, reject) => {
|
||||
|
@ -135,8 +135,8 @@ describe("ForwardDialog", () => {
|
|||
}),
|
||||
);
|
||||
|
||||
let firstButton;
|
||||
let secondButton;
|
||||
let firstButton: Element;
|
||||
let secondButton: Element;
|
||||
const update = () => {
|
||||
[firstButton, secondButton] = container.querySelectorAll(".mx_ForwardList_sendButton");
|
||||
};
|
||||
|
@ -253,7 +253,7 @@ describe("ForwardDialog", () => {
|
|||
[M_ASSET.name]: { type: LocationAssetType.Pin },
|
||||
[M_LOCATION.name]: {
|
||||
uri: geoUri,
|
||||
description: undefined,
|
||||
description: undefined as string,
|
||||
},
|
||||
};
|
||||
expect(mockClient.sendEvent).toHaveBeenCalledWith(
|
||||
|
@ -280,7 +280,7 @@ describe("ForwardDialog", () => {
|
|||
[M_ASSET.name]: { type: LocationAssetType.Pin },
|
||||
[M_LOCATION.name]: {
|
||||
uri: geoUri,
|
||||
description: undefined,
|
||||
description: undefined as string,
|
||||
},
|
||||
};
|
||||
expect(mockClient.sendEvent).toHaveBeenCalledWith(
|
||||
|
@ -301,7 +301,7 @@ describe("ForwardDialog", () => {
|
|||
[M_ASSET.name]: { type: LocationAssetType.Pin },
|
||||
[M_LOCATION.name]: {
|
||||
uri: geoUri,
|
||||
description: undefined,
|
||||
description: undefined as string,
|
||||
},
|
||||
geo_uri: geoUri,
|
||||
[M_TIMESTAMP.name]: timestamp,
|
||||
|
|
|
@ -16,9 +16,8 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import { act } from "react-dom/test-utils";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
||||
import InteractiveAuthDialog from "../../../../src/components/views/dialogs/InteractiveAuthDialog";
|
||||
import { flushPromises, getMockClientWithEventEmitter, unmockClientPeg } from "../../../test-utils";
|
||||
|
@ -33,7 +32,10 @@ describe("InteractiveAuthDialog", function () {
|
|||
makeRequest: jest.fn().mockResolvedValue(undefined),
|
||||
onFinished: jest.fn(),
|
||||
};
|
||||
const getComponent = (props = {}) => mount(<InteractiveAuthDialog {...defaultProps} {...props} />);
|
||||
|
||||
const renderComponent = (props = {}) => render(<InteractiveAuthDialog {...defaultProps} {...props} />);
|
||||
const getPasswordField = () => screen.getByLabelText("Password");
|
||||
const getSubmitButton = () => screen.getByRole("button", { name: "Continue" });
|
||||
|
||||
beforeEach(function () {
|
||||
jest.clearAllMocks();
|
||||
|
@ -44,8 +46,6 @@ describe("InteractiveAuthDialog", function () {
|
|||
unmockClientPeg();
|
||||
});
|
||||
|
||||
const getSubmitButton = (wrapper: ReactWrapper) => wrapper.find('[type="submit"]').at(0);
|
||||
|
||||
it("Should successfully complete a password flow", async () => {
|
||||
const onFinished = jest.fn();
|
||||
const makeRequest = jest.fn().mockResolvedValue({ a: 1 });
|
||||
|
@ -56,31 +56,24 @@ describe("InteractiveAuthDialog", function () {
|
|||
flows: [{ stages: ["m.login.password"] }],
|
||||
};
|
||||
|
||||
const wrapper = getComponent({ makeRequest, onFinished, authData });
|
||||
renderComponent({ makeRequest, onFinished, authData });
|
||||
|
||||
const passwordNode = wrapper.find('input[type="password"]').at(0);
|
||||
const submitNode = getSubmitButton(wrapper);
|
||||
const passwordField = getPasswordField();
|
||||
const submitButton = getSubmitButton();
|
||||
|
||||
const formNode = wrapper.find("form").at(0);
|
||||
expect(passwordNode).toBeTruthy();
|
||||
expect(submitNode).toBeTruthy();
|
||||
expect(passwordField).toBeTruthy();
|
||||
expect(submitButton).toBeTruthy();
|
||||
|
||||
// submit should be disabled
|
||||
expect(submitNode.props().disabled).toBe(true);
|
||||
expect(submitButton).toBeDisabled();
|
||||
|
||||
// put something in the password box
|
||||
act(() => {
|
||||
passwordNode.simulate("change", { target: { value: "s3kr3t" } });
|
||||
wrapper.setProps({});
|
||||
});
|
||||
await userEvent.type(passwordField, "s3kr3t");
|
||||
|
||||
expect(wrapper.find('input[type="password"]').at(0).props().value).toEqual("s3kr3t");
|
||||
expect(getSubmitButton(wrapper).props().disabled).toBe(false);
|
||||
expect(submitButton).not.toBeDisabled();
|
||||
|
||||
// hit enter; that should trigger a request
|
||||
act(() => {
|
||||
formNode.simulate("submit");
|
||||
});
|
||||
await userEvent.click(submitButton);
|
||||
|
||||
// wait for auth request to resolve
|
||||
await flushPromises();
|
||||
|
|
|
@ -76,9 +76,9 @@ describe("InviteDialog", () => {
|
|||
});
|
||||
|
||||
it("should label with space name", () => {
|
||||
mockClient.getRoom(roomId).isSpaceRoom = jest.fn().mockReturnValue(true);
|
||||
mockClient.getRoom(roomId).getType = jest.fn().mockReturnValue(RoomType.Space);
|
||||
mockClient.getRoom(roomId).name = "Space";
|
||||
mockClient.getRoom(roomId)!.isSpaceRoom = jest.fn().mockReturnValue(true);
|
||||
mockClient.getRoom(roomId)!.getType = jest.fn().mockReturnValue(RoomType.Space);
|
||||
mockClient.getRoom(roomId)!.name = "Space";
|
||||
render(<InviteDialog kind={KIND_INVITE} roomId={roomId} onFinished={jest.fn()} />);
|
||||
|
||||
expect(screen.queryByText("Invite to Space")).toBeTruthy();
|
||||
|
|
|
@ -73,8 +73,9 @@ describe("<UserSettingsDialog />", () => {
|
|||
mockSdkConfig.get.mockReturnValue({ brand: "Test" });
|
||||
});
|
||||
|
||||
const getActiveTabLabel = (container) => container.querySelector(".mx_TabbedView_tabLabel_active").textContent;
|
||||
const getActiveTabHeading = (container) => container.querySelector(".mx_SettingsTab_heading").textContent;
|
||||
const getActiveTabLabel = (container: Element) =>
|
||||
container.querySelector(".mx_TabbedView_tabLabel_active").textContent;
|
||||
const getActiveTabHeading = (container: Element) => container.querySelector(".mx_SettingsTab_heading").textContent;
|
||||
|
||||
it("should render general settings tab when no initialTabId", () => {
|
||||
const { container } = render(getComponent());
|
||||
|
|
|
@ -15,15 +15,17 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import { MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { fireEvent, render } from "@testing-library/react";
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { PollHistoryDialog } from "../../../../../src/components/views/dialogs/polls/PollHistoryDialog";
|
||||
import {
|
||||
getMockClientWithEventEmitter,
|
||||
makePollEndEvent,
|
||||
makePollStartEvent,
|
||||
mockClientMethodsUser,
|
||||
mockIntlDateTimeFormat,
|
||||
setupRoomWithPollEvents,
|
||||
unmockIntlDateTimeFormat,
|
||||
} from "../../../../test-utils";
|
||||
|
||||
|
@ -33,6 +35,8 @@ describe("<PollHistoryDialog />", () => {
|
|||
const mockClient = getMockClientWithEventEmitter({
|
||||
...mockClientMethodsUser(userId),
|
||||
getRoom: jest.fn(),
|
||||
relations: jest.fn(),
|
||||
decryptEventIfNeeded: jest.fn(),
|
||||
});
|
||||
const room = new Room(roomId, mockClient, userId);
|
||||
|
||||
|
@ -49,6 +53,7 @@ describe("<PollHistoryDialog />", () => {
|
|||
|
||||
beforeEach(() => {
|
||||
mockClient.getRoom.mockReturnValue(room);
|
||||
mockClient.relations.mockResolvedValue({ events: [] });
|
||||
const timeline = room.getLiveTimeline();
|
||||
jest.spyOn(timeline, "getEvents").mockReturnValue([]);
|
||||
});
|
||||
|
@ -63,24 +68,58 @@ describe("<PollHistoryDialog />", () => {
|
|||
expect(() => getComponent()).toThrow("Cannot find room");
|
||||
});
|
||||
|
||||
it("renders a no polls message when there are no polls in the timeline", () => {
|
||||
it("renders a no polls message when there are no active polls in the timeline", () => {
|
||||
const { getByText } = getComponent();
|
||||
|
||||
expect(getByText("There are no polls in this room")).toBeTruthy();
|
||||
expect(getByText("There are no active polls in this room")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders a list of polls when there are polls in the timeline", async () => {
|
||||
it("renders a no past polls message when there are no past polls in the timeline", () => {
|
||||
const { getByText } = getComponent();
|
||||
|
||||
fireEvent.click(getByText("Past polls"));
|
||||
|
||||
expect(getByText("There are no past polls in this room")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders a list of active polls when there are polls in the timeline", async () => {
|
||||
const timestamp = 1675300825090;
|
||||
const pollStart1 = makePollStartEvent("Question?", userId, undefined, { ts: timestamp, id: "$1" });
|
||||
const pollStart2 = makePollStartEvent("Where?", userId, undefined, { ts: timestamp + 10000, id: "$2" });
|
||||
const pollStart3 = makePollStartEvent("What?", userId, undefined, { ts: timestamp + 70000, id: "$3" });
|
||||
const pollEnd3 = makePollEndEvent(pollStart3.getId()!, roomId, userId, timestamp + 1);
|
||||
await setupRoomWithPollEvents([pollStart2, pollStart3, pollStart1], [], [pollEnd3], mockClient, room);
|
||||
|
||||
const { container, queryByText, getByTestId } = getComponent();
|
||||
|
||||
expect(getByTestId("filter-tab-PollHistoryDialog_filter-ACTIVE").firstElementChild).toBeChecked();
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
// this poll is ended, and default filter is ACTIVE
|
||||
expect(queryByText("What?")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("filters ended polls", async () => {
|
||||
const pollStart1 = makePollStartEvent("Question?", userId, undefined, { ts: 1675300825090, id: "$1" });
|
||||
const pollStart2 = makePollStartEvent("Where?", userId, undefined, { ts: 1675300725090, id: "$2" });
|
||||
const pollStart3 = makePollStartEvent("What?", userId, undefined, { ts: 1675200725090, id: "$3" });
|
||||
const message = new MatrixEvent({
|
||||
type: "m.room.message",
|
||||
content: {},
|
||||
});
|
||||
const timeline = room.getLiveTimeline();
|
||||
jest.spyOn(timeline, "getEvents").mockReturnValue([pollStart1, pollStart2, pollStart3, message]);
|
||||
const { container } = getComponent();
|
||||
const pollEnd3 = makePollEndEvent(pollStart3.getId()!, roomId, userId, 1675200725090 + 1);
|
||||
await setupRoomWithPollEvents([pollStart1, pollStart2, pollStart3], [], [pollEnd3], mockClient, room);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
const { getByText, queryByText, getByTestId } = getComponent();
|
||||
|
||||
expect(getByText("Question?")).toBeInTheDocument();
|
||||
expect(getByText("Where?")).toBeInTheDocument();
|
||||
// this poll is ended, and default filter is ACTIVE
|
||||
expect(queryByText("What?")).not.toBeInTheDocument();
|
||||
|
||||
fireEvent.click(getByText("Past polls"));
|
||||
expect(getByTestId("filter-tab-PollHistoryDialog_filter-ENDED").firstElementChild).toBeChecked();
|
||||
|
||||
// active polls no longer shown
|
||||
expect(queryByText("Question?")).not.toBeInTheDocument();
|
||||
expect(queryByText("Where?")).not.toBeInTheDocument();
|
||||
// this poll is ended
|
||||
expect(getByText("What?")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<PollHistoryDialog /> renders a list of polls when there are polls in the timeline 1`] = `
|
||||
exports[`<PollHistoryDialog /> renders a list of active polls when there are polls in the timeline 1`] = `
|
||||
<div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
|
@ -35,25 +35,38 @@ exports[`<PollHistoryDialog /> renders a list of polls when there are polls in t
|
|||
<div
|
||||
class="mx_PollHistoryList"
|
||||
>
|
||||
<fieldset
|
||||
class="mx_FilterTabGroup"
|
||||
>
|
||||
<label
|
||||
data-testid="filter-tab-PollHistoryDialog_filter-ACTIVE"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
name="PollHistoryDialog_filter"
|
||||
type="radio"
|
||||
value="ACTIVE"
|
||||
/>
|
||||
<span>
|
||||
Active polls
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
data-testid="filter-tab-PollHistoryDialog_filter-ENDED"
|
||||
>
|
||||
<input
|
||||
name="PollHistoryDialog_filter"
|
||||
type="radio"
|
||||
value="ENDED"
|
||||
/>
|
||||
<span>
|
||||
Past polls
|
||||
</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
<ol
|
||||
class="mx_PollHistoryList_list"
|
||||
>
|
||||
<li
|
||||
class="mx_PollListItem"
|
||||
data-testid="pollListItem-$1"
|
||||
>
|
||||
<span>
|
||||
02/02/23
|
||||
</span>
|
||||
<div
|
||||
class="mx_PollListItem_icon"
|
||||
/>
|
||||
<span
|
||||
class="mx_PollListItem_question"
|
||||
>
|
||||
Question?
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
class="mx_PollListItem"
|
||||
data-testid="pollListItem-$2"
|
||||
|
@ -72,10 +85,10 @@ exports[`<PollHistoryDialog /> renders a list of polls when there are polls in t
|
|||
</li>
|
||||
<li
|
||||
class="mx_PollListItem"
|
||||
data-testid="pollListItem-$3"
|
||||
data-testid="pollListItem-$1"
|
||||
>
|
||||
<span>
|
||||
31/01/23
|
||||
02/02/23
|
||||
</span>
|
||||
<div
|
||||
class="mx_PollListItem_icon"
|
||||
|
@ -83,7 +96,7 @@ exports[`<PollHistoryDialog /> renders a list of polls when there are polls in t
|
|||
<span
|
||||
class="mx_PollListItem_question"
|
||||
>
|
||||
What?
|
||||
Question?
|
||||
</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import { MatrixEvent, RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
|
@ -60,7 +60,7 @@ describe("EventListSummary", function () {
|
|||
*/
|
||||
interface MembershipEventParams {
|
||||
senderId?: string;
|
||||
userId: string;
|
||||
userId?: string;
|
||||
membership: string;
|
||||
prevMembership?: string;
|
||||
}
|
||||
|
@ -100,11 +100,11 @@ describe("EventListSummary", function () {
|
|||
// Generate the same sequence of `events` for `n` users, where each user ID
|
||||
// is created by replacing the first "$" in userIdTemplate with `i` for
|
||||
// `i = 0 .. n`.
|
||||
const generateEventsForUsers = (userIdTemplate, n, events) => {
|
||||
const generateEventsForUsers = (userIdTemplate: string, n: number, events: MembershipEventParams[]) => {
|
||||
let eventsForUsers: MatrixEvent[] = [];
|
||||
let userId = "";
|
||||
for (let i = 0; i < n; i++) {
|
||||
userId = userIdTemplate.replace("$", i);
|
||||
userId = userIdTemplate.replace("$", String(i));
|
||||
events.forEach((e) => {
|
||||
e.userId = userId;
|
||||
});
|
||||
|
@ -117,7 +117,7 @@ describe("EventListSummary", function () {
|
|||
...mockClientMethodsUser(),
|
||||
});
|
||||
|
||||
const defaultProps = {
|
||||
const defaultProps: ComponentProps<typeof EventListSummary> = {
|
||||
layout: Layout.Bubble,
|
||||
events: [],
|
||||
children: [],
|
||||
|
|
54
test/components/views/elements/FilterTabGroup-test.tsx
Normal file
54
test/components/views/elements/FilterTabGroup-test.tsx
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { fireEvent, render } from "@testing-library/react";
|
||||
|
||||
import { FilterTabGroup } from "../../../../src/components/views/elements/FilterTabGroup";
|
||||
|
||||
describe("<FilterTabGroup />", () => {
|
||||
enum TestOption {
|
||||
Apple = "Apple",
|
||||
Banana = "Banana",
|
||||
Orange = "Orange",
|
||||
}
|
||||
const defaultProps = {
|
||||
"name": "test",
|
||||
"value": TestOption.Apple,
|
||||
"onFilterChange": jest.fn(),
|
||||
"tabs": [
|
||||
{ id: TestOption.Apple, label: `Label for ${TestOption.Apple}` },
|
||||
{ id: TestOption.Banana, label: `Label for ${TestOption.Banana}` },
|
||||
{ id: TestOption.Orange, label: `Label for ${TestOption.Orange}` },
|
||||
],
|
||||
"data-testid": "test",
|
||||
};
|
||||
const getComponent = (props = {}) => <FilterTabGroup<TestOption> {...defaultProps} {...props} />;
|
||||
|
||||
it("renders options", () => {
|
||||
const { container } = render(getComponent());
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("calls onChange handler on selection", () => {
|
||||
const onFilterChange = jest.fn();
|
||||
const { getByText } = render(getComponent({ onFilterChange }));
|
||||
|
||||
fireEvent.click(getByText("Label for Banana"));
|
||||
|
||||
expect(onFilterChange).toHaveBeenCalledWith(TestOption.Banana);
|
||||
});
|
||||
});
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import { fireEvent, render } from "@testing-library/react";
|
||||
import { fireEvent, render, RenderResult } from "@testing-library/react";
|
||||
|
||||
import StyledRadioGroup from "../../../../src/components/views/elements/StyledRadioGroup";
|
||||
|
||||
|
@ -44,8 +44,10 @@ describe("<StyledRadioGroup />", () => {
|
|||
};
|
||||
const getComponent = (props = {}) => render(<StyledRadioGroup {...defaultProps} {...props} />);
|
||||
|
||||
const getInputByValue = (component, value) => component.container.querySelector(`input[value="${value}"]`);
|
||||
const getCheckedInput = (component) => component.container.querySelector("input[checked]");
|
||||
const getInputByValue = (component: RenderResult, value: string) =>
|
||||
component.container.querySelector<HTMLInputElement>(`input[value="${value}"]`);
|
||||
const getCheckedInput = (component: RenderResult) =>
|
||||
component.container.querySelector<HTMLInputElement>("input[checked]");
|
||||
|
||||
it("renders radios correctly when no value is provided", () => {
|
||||
const component = getComponent();
|
||||
|
|
|
@ -61,7 +61,7 @@ describe("<TooltipTarget />", () => {
|
|||
});
|
||||
|
||||
const alignmentKeys = Object.keys(Alignment).filter((o: any) => isNaN(o));
|
||||
it.each(alignmentKeys)("displays %s aligned tooltip on mouseover", async (alignment) => {
|
||||
it.each(alignmentKeys)("displays %s aligned tooltip on mouseover", async (alignment: any) => {
|
||||
const wrapper = getComponent({ alignment: Alignment[alignment] });
|
||||
act(() => {
|
||||
Simulate.mouseOver(wrapper);
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<FilterTabGroup /> renders options 1`] = `
|
||||
<div>
|
||||
<fieldset
|
||||
class="mx_FilterTabGroup"
|
||||
data-testid="test"
|
||||
>
|
||||
<label
|
||||
data-testid="filter-tab-test-Apple"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
name="test"
|
||||
type="radio"
|
||||
value="Apple"
|
||||
/>
|
||||
<span>
|
||||
Label for Apple
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
data-testid="filter-tab-test-Banana"
|
||||
>
|
||||
<input
|
||||
name="test"
|
||||
type="radio"
|
||||
value="Banana"
|
||||
/>
|
||||
<span>
|
||||
Label for Banana
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
data-testid="filter-tab-test-Orange"
|
||||
>
|
||||
<input
|
||||
name="test"
|
||||
type="radio"
|
||||
value="Orange"
|
||||
/>
|
||||
<span>
|
||||
Label for Orange
|
||||
</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
</div>
|
||||
`;
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
||||
import LiveDurationDropdown, {
|
||||
|
@ -33,9 +33,9 @@ describe("<LiveDurationDropdown />", () => {
|
|||
};
|
||||
const getComponent = (props = {}) => mount(<LiveDurationDropdown {...defaultProps} {...props} />);
|
||||
|
||||
const getOption = (wrapper, timeout) => findById(wrapper, `live-duration__${timeout}`).at(0);
|
||||
const getSelectedOption = (wrapper) => findById(wrapper, "live-duration_value");
|
||||
const openDropdown = (wrapper) =>
|
||||
const getOption = (wrapper: ReactWrapper, timeout: number) => findById(wrapper, `live-duration__${timeout}`).at(0);
|
||||
const getSelectedOption = (wrapper: ReactWrapper) => findById(wrapper, "live-duration_value");
|
||||
const openDropdown = (wrapper: ReactWrapper) =>
|
||||
act(() => {
|
||||
wrapper.find('[role="button"]').at(0).simulate("click");
|
||||
wrapper.setProps({});
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import React from "react";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
|
@ -239,11 +239,12 @@ describe("LocationPicker", () => {
|
|||
const shareType = LocationShareType.Live;
|
||||
testUserLocationShareTypes(shareType);
|
||||
|
||||
const getOption = (wrapper, timeout) => findById(wrapper, `live-duration__${timeout}`).at(0);
|
||||
const getDropdown = (wrapper) => findByTestId(wrapper, "live-duration-dropdown");
|
||||
const getSelectedOption = (wrapper) => findById(wrapper, "live-duration_value");
|
||||
const getOption = (wrapper: ReactWrapper, timeout: number) =>
|
||||
findById(wrapper, `live-duration__${timeout}`).at(0);
|
||||
const getDropdown = (wrapper: ReactWrapper) => findByTestId(wrapper, "live-duration-dropdown");
|
||||
const getSelectedOption = (wrapper: ReactWrapper) => findById(wrapper, "live-duration_value");
|
||||
|
||||
const openDropdown = (wrapper) =>
|
||||
const openDropdown = (wrapper: ReactWrapper) =>
|
||||
act(() => {
|
||||
const dropdown = getDropdown(wrapper);
|
||||
dropdown.find('[role="button"]').at(0).simulate("click");
|
||||
|
|
|
@ -52,7 +52,6 @@ describe("<LocationViewDialog />", () => {
|
|||
// @ts-ignore cheat assignment to property
|
||||
selfShareEvent.sender = member;
|
||||
const component = getComponent({ mxEvent: selfShareEvent });
|
||||
// @ts-ignore fix when moving to rtl
|
||||
expect(component.find("SmartMarker").props()["roomMember"]).toEqual(member);
|
||||
expect(component.find("SmartMarker").prop("roomMember")).toEqual(member);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -40,7 +40,7 @@ describe("DateSeparator", () => {
|
|||
};
|
||||
const RealDate = global.Date;
|
||||
class MockDate extends Date {
|
||||
constructor(date) {
|
||||
constructor(date: string | number | Date) {
|
||||
super(date || now);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
@ -63,7 +63,7 @@ describe("<MBeaconBody />", () => {
|
|||
|
||||
const defaultEvent = makeBeaconInfoEvent(aliceId, roomId, { isLive: true }, "$alice-room1-1");
|
||||
|
||||
const defaultProps = {
|
||||
const defaultProps: ComponentProps<typeof MBeaconBody> = {
|
||||
mxEvent: defaultEvent,
|
||||
highlights: [],
|
||||
highlightLink: "",
|
||||
|
@ -80,7 +80,10 @@ describe("<MBeaconBody />", () => {
|
|||
wrappingComponentProps: { value: mockClient },
|
||||
});
|
||||
|
||||
const modalSpy = jest.spyOn(Modal, "createDialog").mockReturnValue(undefined);
|
||||
const modalSpy = jest.spyOn(Modal, "createDialog").mockReturnValue({
|
||||
finished: Promise.resolve([true]),
|
||||
close: () => {},
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
@ -169,7 +172,7 @@ describe("<MBeaconBody />", () => {
|
|||
const room = makeRoomWithStateEvents([aliceBeaconInfo1], { roomId, mockClient });
|
||||
const component = getComponent({ mxEvent: aliceBeaconInfo1 });
|
||||
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo1));
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo1))!;
|
||||
// update alice's beacon with a new edition
|
||||
// beacon instance emits
|
||||
act(() => {
|
||||
|
@ -190,7 +193,7 @@ describe("<MBeaconBody />", () => {
|
|||
const aliceBeaconInfo = makeBeaconInfoEvent(aliceId, roomId, { isLive: true }, "$alice-room1-1");
|
||||
|
||||
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
|
||||
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
||||
|
||||
act(() => {
|
||||
|
@ -240,7 +243,7 @@ describe("<MBeaconBody />", () => {
|
|||
|
||||
it("renders a live beacon with a location correctly", () => {
|
||||
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
|
||||
beaconInstance.addLocations([location1]);
|
||||
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
||||
|
||||
|
@ -249,7 +252,7 @@ describe("<MBeaconBody />", () => {
|
|||
|
||||
it("opens maximised map view on click when beacon has a live location", () => {
|
||||
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
|
||||
beaconInstance.addLocations([location1]);
|
||||
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
||||
|
||||
|
@ -274,7 +277,7 @@ describe("<MBeaconBody />", () => {
|
|||
|
||||
it("renders a live beacon with a location correctly", () => {
|
||||
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
|
||||
beaconInstance.addLocations([location1]);
|
||||
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
||||
|
||||
|
@ -283,7 +286,7 @@ describe("<MBeaconBody />", () => {
|
|||
|
||||
it("opens maximised map view on click when beacon has a live location", () => {
|
||||
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
|
||||
beaconInstance.addLocations([location1]);
|
||||
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
||||
|
||||
|
@ -299,7 +302,7 @@ describe("<MBeaconBody />", () => {
|
|||
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
|
||||
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
||||
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
|
||||
act(() => {
|
||||
beaconInstance.addLocations([location1]);
|
||||
component.setProps({});
|
||||
|
@ -343,9 +346,9 @@ describe("<MBeaconBody />", () => {
|
|||
|
||||
const redactionEvent = new MatrixEvent({ type: EventType.RoomRedaction, content: { reason: "test reason" } });
|
||||
|
||||
const setupRoomWithBeacon = (beaconInfoEvent, locationEvents: MatrixEvent[] = []) => {
|
||||
const setupRoomWithBeacon = (beaconInfoEvent: MatrixEvent, locationEvents: MatrixEvent[] = []) => {
|
||||
const room = makeRoomWithStateEvents([beaconInfoEvent], { roomId, mockClient });
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(beaconInfoEvent));
|
||||
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(beaconInfoEvent))!;
|
||||
beaconInstance.addLocations(locationEvents);
|
||||
};
|
||||
const mockGetRelationsForEvent = (locationEvents: MatrixEvent[] = []) => {
|
||||
|
|
|
@ -69,7 +69,7 @@ describe("<MImageBody/>", () => {
|
|||
const props = {
|
||||
onHeightChanged: jest.fn(),
|
||||
onMessageAllowed: jest.fn(),
|
||||
permalinkCreator: new RoomPermalinkCreator(new Room(encryptedMediaEvent.getRoomId(), cli, cli.getUserId())),
|
||||
permalinkCreator: new RoomPermalinkCreator(new Room(encryptedMediaEvent.getRoomId()!, cli, cli.getUserId()!)),
|
||||
};
|
||||
|
||||
it("should show error when encrypted media cannot be downloaded", async () => {
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { LocationAssetType } from "matrix-js-sdk/src/@types/location";
|
||||
|
@ -46,7 +46,7 @@ describe("MLocationBody", () => {
|
|||
isGuest: jest.fn().mockReturnValue(false),
|
||||
});
|
||||
const defaultEvent = makeLocationEvent("geo:51.5076,-0.1276", LocationAssetType.Pin);
|
||||
const defaultProps = {
|
||||
const defaultProps: ComponentProps<typeof MLocationBody> = {
|
||||
mxEvent: defaultEvent,
|
||||
highlights: [],
|
||||
highlightLink: "",
|
||||
|
@ -79,7 +79,7 @@ describe("MLocationBody", () => {
|
|||
});
|
||||
|
||||
describe("with error", () => {
|
||||
let sdkConfigSpy;
|
||||
let sdkConfigSpy: jest.SpyInstance<any>;
|
||||
|
||||
beforeEach(() => {
|
||||
// eat expected errors to keep console clean
|
||||
|
@ -171,7 +171,7 @@ describe("MLocationBody", () => {
|
|||
const component = getComponent({ mxEvent: selfShareEvent });
|
||||
|
||||
// render self locations with user avatars
|
||||
expect(component.find("SmartMarker").at(0).props()["roomMember"]).toEqual(member);
|
||||
expect(component.find("SmartMarker").at(0).prop("roomMember")).toEqual(member);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,7 +42,7 @@ import MPollBody from "../../../../src/components/views/messages/MPollBody";
|
|||
import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks";
|
||||
import { MediaEventHelper } from "../../../../src/utils/MediaEventHelper";
|
||||
|
||||
const CHECKED = "mx_MPollBody_option_checked";
|
||||
const CHECKED = "mx_PollOption_checked";
|
||||
const userId = "@me:example.com";
|
||||
|
||||
const mockClient = getMockClientWithEventEmitter({
|
||||
|
@ -227,7 +227,7 @@ describe("MPollBody", () => {
|
|||
content: newPollStart(undefined, undefined, true),
|
||||
});
|
||||
const props = getMPollBodyPropsFromEvent(mxEvent);
|
||||
const room = await setupRoomWithPollEvents(mxEvent, votes, [], mockClient);
|
||||
const room = await setupRoomWithPollEvents([mxEvent], votes, [], mockClient);
|
||||
const renderResult = renderMPollBodyWithWrapper(props);
|
||||
// wait for /relations promise to resolve
|
||||
await flushPromises();
|
||||
|
@ -255,7 +255,7 @@ describe("MPollBody", () => {
|
|||
content: newPollStart(undefined, undefined, true),
|
||||
});
|
||||
const props = getMPollBodyPropsFromEvent(mxEvent);
|
||||
const room = await setupRoomWithPollEvents(mxEvent, votes, [], mockClient);
|
||||
const room = await setupRoomWithPollEvents([mxEvent], votes, [], mockClient);
|
||||
const renderResult = renderMPollBodyWithWrapper(props);
|
||||
// wait for /relations promise to resolve
|
||||
await flushPromises();
|
||||
|
@ -383,7 +383,7 @@ describe("MPollBody", () => {
|
|||
const votes: MatrixEvent[] = [];
|
||||
const ends: MatrixEvent[] = [];
|
||||
const { container } = await newMPollBody(votes, ends, answers);
|
||||
expect(container.querySelectorAll(".mx_MPollBody_option").length).toBe(20);
|
||||
expect(container.querySelectorAll(".mx_PollOption").length).toBe(20);
|
||||
});
|
||||
|
||||
it("hides scores if I voted but the poll is undisclosed", async () => {
|
||||
|
@ -429,7 +429,7 @@ describe("MPollBody", () => {
|
|||
];
|
||||
const ends = [newPollEndEvent("@me:example.com", 12)];
|
||||
const renderResult = await newMPollBody(votes, ends, undefined, false);
|
||||
expect(endedVotesCount(renderResult, "pizza")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "pizza")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("1 vote");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("1 vote");
|
||||
|
@ -531,9 +531,9 @@ describe("MPollBody", () => {
|
|||
const ends = [newPollEndEvent("@me:example.com", 25)];
|
||||
const renderResult = await newMPollBody(votes, ends);
|
||||
expect(endedVotesCount(renderResult, "pizza")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("1 vote");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe('<div class="mx_PollOption_winnerIcon"></div>1 vote');
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("1 vote");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>1 vote');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 2 votes");
|
||||
});
|
||||
|
||||
|
@ -542,7 +542,7 @@ describe("MPollBody", () => {
|
|||
const ends = [newPollEndEvent("@me:example.com", 25)];
|
||||
const renderResult = await newMPollBody(votes, ends);
|
||||
expect(endedVotesCount(renderResult, "pizza")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("1 vote");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe('<div class="mx_PollOption_winnerIcon"></div>1 vote');
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("0 votes");
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 1 vote");
|
||||
|
@ -564,7 +564,7 @@ describe("MPollBody", () => {
|
|||
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||
});
|
||||
|
||||
|
@ -584,7 +584,7 @@ describe("MPollBody", () => {
|
|||
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||
});
|
||||
|
||||
|
@ -607,7 +607,7 @@ describe("MPollBody", () => {
|
|||
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||
});
|
||||
|
||||
|
@ -634,7 +634,7 @@ describe("MPollBody", () => {
|
|||
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||
});
|
||||
|
||||
|
@ -653,8 +653,8 @@ describe("MPollBody", () => {
|
|||
expect(endedVoteChecked(renderResult, "pizza")).toBe(false);
|
||||
|
||||
// Double-check by looking for the endedOptionWinner class
|
||||
expect(endedVoteDiv(renderResult, "wings").className.includes("mx_MPollBody_endedOptionWinner")).toBe(true);
|
||||
expect(endedVoteDiv(renderResult, "pizza").className.includes("mx_MPollBody_endedOptionWinner")).toBe(false);
|
||||
expect(endedVoteDiv(renderResult, "wings").className.includes("mx_PollOption_endedOptionWinner")).toBe(true);
|
||||
expect(endedVoteDiv(renderResult, "pizza").className.includes("mx_PollOption_endedOptionWinner")).toBe(false);
|
||||
});
|
||||
|
||||
it("highlights multiple winning votes", async () => {
|
||||
|
@ -670,13 +670,13 @@ describe("MPollBody", () => {
|
|||
expect(endedVoteChecked(renderResult, "wings")).toBe(true);
|
||||
expect(endedVoteChecked(renderResult, "poutine")).toBe(true);
|
||||
expect(endedVoteChecked(renderResult, "italian")).toBe(false);
|
||||
expect(renderResult.container.getElementsByClassName("mx_MPollBody_option_checked")).toHaveLength(3);
|
||||
expect(renderResult.container.getElementsByClassName(CHECKED)).toHaveLength(3);
|
||||
});
|
||||
|
||||
it("highlights nothing if poll has no votes", async () => {
|
||||
const ends = [newPollEndEvent("@me:example.com", 25)];
|
||||
const renderResult = await newMPollBody([], ends);
|
||||
expect(renderResult.container.getElementsByClassName("mx_MPollBody_option_checked")).toHaveLength(0);
|
||||
expect(renderResult.container.getElementsByClassName(CHECKED)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("says poll is not ended if there is no end event", async () => {
|
||||
|
@ -700,7 +700,7 @@ describe("MPollBody", () => {
|
|||
});
|
||||
const ends = [newPollEndEvent("@me:example.com", 25)];
|
||||
|
||||
await setupRoomWithPollEvents(pollEvent, [], ends, mockClient);
|
||||
await setupRoomWithPollEvents([pollEvent], [], ends, mockClient);
|
||||
const poll = mockClient.getRoom(pollEvent.getRoomId()!)!.polls.get(pollEvent.getId()!)!;
|
||||
// start fetching, dont await
|
||||
poll.getResponses();
|
||||
|
@ -745,7 +745,7 @@ describe("MPollBody", () => {
|
|||
expect(inputs[0].getAttribute("value")).toEqual("n1");
|
||||
expect(inputs[1].getAttribute("value")).toEqual("n2");
|
||||
expect(inputs[2].getAttribute("value")).toEqual("n3");
|
||||
const options = container.querySelectorAll(".mx_MPollBody_optionText");
|
||||
const options = container.querySelectorAll(".mx_PollOption_optionText");
|
||||
expect(options).toHaveLength(3);
|
||||
expect(options[0].innerHTML).toEqual("new answer 1");
|
||||
expect(options[1].innerHTML).toEqual("new answer 2");
|
||||
|
@ -920,7 +920,7 @@ async function newMPollBodyFromEvent(
|
|||
): Promise<RenderResult> {
|
||||
const props = getMPollBodyPropsFromEvent(mxEvent);
|
||||
|
||||
await setupRoomWithPollEvents(mxEvent, relationEvents, endEvents, mockClient);
|
||||
await setupRoomWithPollEvents([mxEvent], relationEvents, endEvents, mockClient);
|
||||
|
||||
return renderMPollBodyWithWrapper(props);
|
||||
}
|
||||
|
@ -934,11 +934,11 @@ function voteButton({ getByTestId }: RenderResult, value: string): Element {
|
|||
}
|
||||
|
||||
function votesCount({ getByTestId }: RenderResult, value: string): string {
|
||||
return getByTestId(`pollOption-${value}`).querySelector(".mx_MPollBody_optionVoteCount")!.innerHTML;
|
||||
return getByTestId(`pollOption-${value}`).querySelector(".mx_PollOption_optionVoteCount")!.innerHTML;
|
||||
}
|
||||
|
||||
function endedVoteChecked({ getByTestId }: RenderResult, value: string): boolean {
|
||||
return getByTestId(`pollOption-${value}`).className.includes("mx_MPollBody_option_checked");
|
||||
return getByTestId(`pollOption-${value}`).className.includes(CHECKED);
|
||||
}
|
||||
|
||||
function endedVoteDiv({ getByTestId }: RenderResult, value: string): Element {
|
||||
|
@ -1036,7 +1036,7 @@ async function runIsPollEnded(ends: MatrixEvent[]) {
|
|||
content: newPollStart(),
|
||||
});
|
||||
|
||||
await setupRoomWithPollEvents(pollEvent, [], ends, mockClient);
|
||||
await setupRoomWithPollEvents([pollEvent], [], ends, mockClient);
|
||||
|
||||
return isPollEnded(pollEvent, mockClient);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ describe("<MPollEndBody />", () => {
|
|||
|
||||
const setupRoomWithEventsTimeline = async (pollEnd: MatrixEvent, pollStart?: MatrixEvent): Promise<Room> => {
|
||||
if (pollStart) {
|
||||
await setupRoomWithPollEvents(pollStart, [], [pollEnd], mockClient);
|
||||
await setupRoomWithPollEvents([pollStart], [], [pollEnd], mockClient);
|
||||
}
|
||||
const room = mockClient.getRoom(roomId) || new Room(roomId, mockClient, userId);
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { IContent, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { render, RenderResult } from "@testing-library/react";
|
||||
|
||||
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||
|
@ -43,7 +43,7 @@ describe("MVideoBody", () => {
|
|||
});
|
||||
|
||||
function makeMVideoBody(w: number, h: number): RenderResult {
|
||||
const content = {
|
||||
const content: IContent = {
|
||||
info: {
|
||||
"w": w,
|
||||
"h": h,
|
||||
|
@ -66,7 +66,7 @@ function makeMVideoBody(w: number, h: number): RenderResult {
|
|||
content,
|
||||
});
|
||||
|
||||
const defaultProps = {
|
||||
const defaultProps: ComponentProps<typeof MVideoBody> = {
|
||||
mxEvent: event,
|
||||
highlights: [],
|
||||
highlightLink: "",
|
||||
|
|
|
@ -76,7 +76,7 @@ describe("<MessageActionBar />", () => {
|
|||
});
|
||||
|
||||
const localStorageMock = (() => {
|
||||
let store = {};
|
||||
let store: Record<string, any> = {};
|
||||
return {
|
||||
getItem: jest.fn().mockImplementation((key) => store[key] ?? null),
|
||||
setItem: jest.fn().mockImplementation((key, value) => {
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { MockedObject } from "jest-mock";
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
|
@ -38,9 +38,9 @@ describe("<TextualBody />", () => {
|
|||
beforeEach(() => {
|
||||
defaultMatrixClient = getMockClientWithEventEmitter({
|
||||
getRoom: () => defaultRoom,
|
||||
getAccountData: () => undefined,
|
||||
getAccountData: (): MatrixEvent | undefined => undefined,
|
||||
isGuest: () => false,
|
||||
mxcUrlToHttp: (s) => s,
|
||||
mxcUrlToHttp: (s: string) => s,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -56,7 +56,7 @@ describe("<TextualBody />", () => {
|
|||
});
|
||||
const defaultProps = {
|
||||
mxEvent: defaultEvent,
|
||||
highlights: [],
|
||||
highlights: [] as string[],
|
||||
highlightLink: "",
|
||||
onMessageAllowed: jest.fn(),
|
||||
onHeightChanged: jest.fn(),
|
||||
|
@ -158,17 +158,17 @@ describe("<TextualBody />", () => {
|
|||
});
|
||||
|
||||
describe("renders formatted m.text correctly", () => {
|
||||
let matrixClient;
|
||||
let matrixClient: MatrixClient;
|
||||
beforeEach(() => {
|
||||
matrixClient = getMockClientWithEventEmitter({
|
||||
getRoom: () => mkStubRoom("room_id", "room name", undefined),
|
||||
getAccountData: () => undefined,
|
||||
getAccountData: (): MatrixEvent | undefined => undefined,
|
||||
getUserId: () => "@me:my_server",
|
||||
getHomeserverUrl: () => "https://my_server/",
|
||||
on: () => undefined,
|
||||
removeListener: () => undefined,
|
||||
on: (): void => undefined,
|
||||
removeListener: (): void => undefined,
|
||||
isGuest: () => false,
|
||||
mxcUrlToHttp: (s) => s,
|
||||
mxcUrlToHttp: (s: string) => s,
|
||||
});
|
||||
DMRoomMap.makeShared();
|
||||
});
|
||||
|
@ -375,10 +375,10 @@ describe("<TextualBody />", () => {
|
|||
|
||||
const matrixClient = getMockClientWithEventEmitter({
|
||||
getRoom: () => mkStubRoom("room_id", "room name", undefined),
|
||||
getAccountData: () => undefined,
|
||||
getUrlPreview: (url) => new Promise(() => {}),
|
||||
getAccountData: (): MatrixClient | undefined => undefined,
|
||||
getUrlPreview: (url: string) => new Promise(() => {}),
|
||||
isGuest: () => false,
|
||||
mxcUrlToHttp: (s) => s,
|
||||
mxcUrlToHttp: (s: string) => s,
|
||||
});
|
||||
DMRoomMap.makeShared();
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,65 +22,65 @@ exports[`<MPollEndBody /> when poll start event exists in current timeline rende
|
|||
class="mx_MPollBody_allOptions"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_option mx_MPollBody_option_ended"
|
||||
class="mx_PollOption mx_PollOption_ended"
|
||||
data-testid="pollOption-socks"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_endedOption"
|
||||
class="mx_PollOption_endedOption"
|
||||
data-value="socks"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_optionDescription"
|
||||
class="mx_PollOption_content"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_optionText"
|
||||
class="mx_PollOption_optionText"
|
||||
>
|
||||
Socks
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_optionVoteCount"
|
||||
class="mx_PollOption_optionVoteCount"
|
||||
>
|
||||
0 votes
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_popularityBackground"
|
||||
class="mx_PollOption_popularityBackground"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_popularityAmount"
|
||||
class="mx_PollOption_popularityAmount"
|
||||
style="width: 0%;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_option mx_MPollBody_option_ended"
|
||||
class="mx_PollOption mx_PollOption_ended"
|
||||
data-testid="pollOption-shoes"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_endedOption"
|
||||
class="mx_PollOption_endedOption"
|
||||
data-value="shoes"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_optionDescription"
|
||||
class="mx_PollOption_content"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_optionText"
|
||||
class="mx_PollOption_optionText"
|
||||
>
|
||||
Shoes
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_optionVoteCount"
|
||||
class="mx_PollOption_optionVoteCount"
|
||||
>
|
||||
0 votes
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_popularityBackground"
|
||||
class="mx_PollOption_popularityBackground"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_popularityAmount"
|
||||
class="mx_PollOption_popularityAmount"
|
||||
style="width: 0%;"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -83,7 +83,7 @@ describe("<PinnedMessagesCard />", () => {
|
|||
};
|
||||
|
||||
const mountPins = async (room: Room): Promise<ReactWrapper<ComponentProps<typeof PinnedMessagesCard>>> => {
|
||||
let pins;
|
||||
let pins!: ReactWrapper<ComponentProps<typeof PinnedMessagesCard>>;
|
||||
await act(async () => {
|
||||
pins = mount(
|
||||
<PinnedMessagesCard
|
||||
|
@ -239,9 +239,9 @@ describe("<PinnedMessagesCard />", () => {
|
|||
|
||||
const answers = (poll.unstableExtensibleEvent as PollStartEvent).answers;
|
||||
const responses = [
|
||||
["@alice:example.org", 0],
|
||||
["@bob:example.org", 0],
|
||||
["@eve:example.org", 1],
|
||||
["@alice:example.org", 0] as [string, number],
|
||||
["@bob:example.org", 0] as [string, number],
|
||||
["@eve:example.org", 1] as [string, number],
|
||||
].map(([user, option], i) =>
|
||||
mkEvent({
|
||||
...PollResponseEvent.from([answers[option as number].id], poll.getId()!).serialize(),
|
||||
|
@ -287,8 +287,8 @@ describe("<PinnedMessagesCard />", () => {
|
|||
const pinTile = pins.find(MPollBody);
|
||||
|
||||
expect(pinTile.length).toEqual(1);
|
||||
expect(pinTile.find(".mx_MPollBody_option_ended").length).toEqual(2);
|
||||
expect(pinTile.find(".mx_MPollBody_optionVoteCount").first().text()).toEqual("2 votes");
|
||||
expect(pinTile.find(".mx_MPollBody_optionVoteCount").last().text()).toEqual("1 vote");
|
||||
expect(pinTile.find(".mx_PollOption_ended").length).toEqual(2);
|
||||
expect(pinTile.find(".mx_PollOption_optionVoteCount").first().text()).toEqual("2 votes");
|
||||
expect(pinTile.find(".mx_PollOption_optionVoteCount").last().text()).toEqual("1 vote");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,13 +15,14 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { Component } from "react";
|
||||
import ReactTestUtils from "react-dom/test-utils";
|
||||
import ReactDOM from "react-dom";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||
import { User } from "matrix-js-sdk/src/models/user";
|
||||
import { compare } from "matrix-js-sdk/src/utils";
|
||||
import { MatrixClient, RoomState } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import * as TestUtils from "../../../test-utils";
|
||||
|
@ -43,15 +44,15 @@ describe("MemberList", () => {
|
|||
return room;
|
||||
}
|
||||
|
||||
let parentDiv = null;
|
||||
let client = null;
|
||||
let root = null;
|
||||
let memberListRoom;
|
||||
let memberList = null;
|
||||
let parentDiv: HTMLDivElement = null;
|
||||
let client: MatrixClient = null;
|
||||
let root: Component = null;
|
||||
let memberListRoom: Room;
|
||||
let memberList: MemberList = null;
|
||||
|
||||
let adminUsers = [];
|
||||
let moderatorUsers = [];
|
||||
let defaultUsers = [];
|
||||
let adminUsers: RoomMember[] = [];
|
||||
let moderatorUsers: RoomMember[] = [];
|
||||
let defaultUsers: RoomMember[] = [];
|
||||
|
||||
beforeEach(function () {
|
||||
TestUtils.stubClient();
|
||||
|
@ -109,13 +110,14 @@ describe("MemberList", () => {
|
|||
memberListRoom.currentState = {
|
||||
members: {},
|
||||
getMember: jest.fn(),
|
||||
getStateEvents: (eventType, stateKey) => (stateKey === undefined ? [] : null), // ignore 3pid invites
|
||||
};
|
||||
getStateEvents: ((eventType, stateKey) =>
|
||||
stateKey === undefined ? [] : null) as RoomState["getStateEvents"], // ignore 3pid invites
|
||||
} as unknown as RoomState;
|
||||
for (const member of [...adminUsers, ...moderatorUsers, ...defaultUsers]) {
|
||||
memberListRoom.currentState.members[member.userId] = member;
|
||||
}
|
||||
|
||||
const gatherWrappedRef = (r) => {
|
||||
const gatherWrappedRef = (r: MemberList) => {
|
||||
memberList = r;
|
||||
};
|
||||
const context = new TestSdkContext();
|
||||
|
@ -131,7 +133,7 @@ describe("MemberList", () => {
|
|||
/>
|
||||
</SDKContext.Provider>,
|
||||
parentDiv,
|
||||
);
|
||||
) as unknown as Component;
|
||||
});
|
||||
|
||||
afterEach((done) => {
|
||||
|
@ -144,7 +146,7 @@ describe("MemberList", () => {
|
|||
done();
|
||||
});
|
||||
|
||||
function expectOrderedByPresenceAndPowerLevel(memberTiles, isPresenceEnabled) {
|
||||
function expectOrderedByPresenceAndPowerLevel(memberTiles: MemberTile[], isPresenceEnabled: boolean) {
|
||||
let prevMember = null;
|
||||
for (const tile of memberTiles) {
|
||||
const memberA = prevMember;
|
||||
|
@ -164,8 +166,8 @@ describe("MemberList", () => {
|
|||
let groupChange = false;
|
||||
|
||||
if (isPresenceEnabled) {
|
||||
const convertPresence = (p) => (p === "unavailable" ? "online" : p);
|
||||
const presenceIndex = (p) => {
|
||||
const convertPresence = (p: string) => (p === "unavailable" ? "online" : p);
|
||||
const presenceIndex = (p: string) => {
|
||||
const order = ["active", "online", "offline"];
|
||||
const idx = order.indexOf(convertPresence(p));
|
||||
return idx === -1 ? order.length : idx; // unknown states at the end
|
||||
|
@ -212,7 +214,7 @@ describe("MemberList", () => {
|
|||
}
|
||||
}
|
||||
|
||||
function itDoesOrderMembersCorrectly(enablePresence) {
|
||||
function itDoesOrderMembersCorrectly(enablePresence: boolean) {
|
||||
describe("does order members correctly", () => {
|
||||
// Note: even if presence is disabled, we still expect that the presence
|
||||
// tests will pass. All expectOrderedByPresenceAndPowerLevel does is ensure
|
||||
|
@ -251,7 +253,7 @@ describe("MemberList", () => {
|
|||
// We already have admin, moderator, and default users so leave them alone
|
||||
|
||||
// Bypass all the event listeners and skip to the good part
|
||||
memberList._showPresence = enablePresence;
|
||||
memberList.showPresence = enablePresence;
|
||||
memberList.updateListNow();
|
||||
|
||||
const tiles = ReactTestUtils.scryRenderedComponentsWithType(root, MemberTile);
|
||||
|
|
|
@ -53,7 +53,7 @@ describe("NewRoomIntro", () => {
|
|||
describe("for a DM Room", () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(userId);
|
||||
const room = new Room(roomId, client, client.getUserId());
|
||||
const room = new Room(roomId, client, client.getUserId()!);
|
||||
room.name = "test_room";
|
||||
renderNewRoomIntro(client, room);
|
||||
});
|
||||
|
@ -67,7 +67,7 @@ describe("NewRoomIntro", () => {
|
|||
describe("for a DM LocalRoom", () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(userId);
|
||||
const localRoom = new LocalRoom(roomId, client, client.getUserId());
|
||||
const localRoom = new LocalRoom(roomId, client, client.getUserId()!);
|
||||
localRoom.name = "test_room";
|
||||
localRoom.targets.push(new DirectoryMember({ user_id: userId }));
|
||||
renderNewRoomIntro(client, localRoom);
|
||||
|
|
|
@ -248,13 +248,12 @@ function createRoom(info: IRoomCreationInfo) {
|
|||
}
|
||||
|
||||
function mountHeader(room: Room, propsOverride = {}, roomContext?: Partial<IRoomState>): ReactWrapper {
|
||||
const props = {
|
||||
const props: RoomHeaderProps = {
|
||||
room,
|
||||
inRoom: true,
|
||||
onSearchClick: () => {},
|
||||
onInviteClick: null,
|
||||
onForgetClick: () => {},
|
||||
onCallPlaced: (_type) => {},
|
||||
onAppsClick: () => {},
|
||||
e2eStatus: E2EStatus.Normal,
|
||||
appsShown: true,
|
||||
|
@ -320,7 +319,7 @@ function mkJoinEvent(roomId: string, userId: string) {
|
|||
}
|
||||
|
||||
function mkDirectEvent(roomId: string, userId: string, otherUsers: string[]): MatrixEvent {
|
||||
const content = {};
|
||||
const content: Record<string, string[]> = {};
|
||||
for (const otherUserId of otherUsers) {
|
||||
content[otherUserId] = [roomId];
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ const setupMainMenu = async (client: MatrixClient, testSpace: Room): Promise<Ren
|
|||
|
||||
expect(wrapper.container.textContent).toBe("Test Space");
|
||||
act(() => {
|
||||
wrapper.container.querySelector<HTMLElement>('[aria-label="Test Space menu"]').click();
|
||||
wrapper.container.querySelector<HTMLElement>('[aria-label="Test Space menu"]')?.click();
|
||||
});
|
||||
|
||||
return wrapper;
|
||||
|
@ -77,7 +77,7 @@ const setupPlusMenu = async (client: MatrixClient, testSpace: Room): Promise<Ren
|
|||
|
||||
expect(wrapper.container.textContent).toBe("Test Space");
|
||||
act(() => {
|
||||
wrapper.container.querySelector<HTMLElement>('[aria-label="Add"]').click();
|
||||
wrapper.container.querySelector<HTMLElement>('[aria-label="Add"]')?.click();
|
||||
});
|
||||
|
||||
return wrapper;
|
||||
|
@ -92,7 +92,7 @@ const checkMenuLabels = (items: NodeListOf<Element>, labelArray: Array<string>)
|
|||
expect(items).toHaveLength(labelArray.length);
|
||||
|
||||
const checkLabel = (item: Element, label: string) => {
|
||||
expect(item.querySelector(".mx_IconizedContextMenu_label").textContent).toBe(label);
|
||||
expect(item.querySelector(".mx_IconizedContextMenu_label")?.textContent).toBe(label);
|
||||
};
|
||||
|
||||
labelArray.forEach((label, index) => {
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { render, fireEvent, RenderResult, waitFor } from "@testing-library/react";
|
||||
import { Room, RoomMember, MatrixError, IContent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
|
@ -71,7 +71,7 @@ describe("<RoomPreviewBar />", () => {
|
|||
const inviterUserId = "@inviter:test.com";
|
||||
const otherUserId = "@othertester:test.com";
|
||||
|
||||
const getComponent = (props = {}) => {
|
||||
const getComponent = (props: ComponentProps<typeof RoomPreviewBar> = {}) => {
|
||||
const defaultProps = {
|
||||
room: createRoom(roomId, userId),
|
||||
};
|
||||
|
@ -84,9 +84,9 @@ describe("<RoomPreviewBar />", () => {
|
|||
const getActions = (wrapper: RenderResult) =>
|
||||
wrapper.container.querySelector<HTMLDivElement>(".mx_RoomPreviewBar_actions");
|
||||
const getPrimaryActionButton = (wrapper: RenderResult) =>
|
||||
getActions(wrapper).querySelector(".mx_AccessibleButton_kind_primary");
|
||||
getActions(wrapper)?.querySelector(".mx_AccessibleButton_kind_primary");
|
||||
const getSecondaryActionButton = (wrapper: RenderResult) =>
|
||||
getActions(wrapper).querySelector(".mx_AccessibleButton_kind_secondary");
|
||||
getActions(wrapper)?.querySelector(".mx_AccessibleButton_kind_secondary");
|
||||
|
||||
beforeEach(() => {
|
||||
stubClient();
|
||||
|
@ -102,17 +102,17 @@ describe("<RoomPreviewBar />", () => {
|
|||
const component = getComponent({ joining: true });
|
||||
|
||||
expect(isSpinnerRendered(component)).toBeTruthy();
|
||||
expect(getMessage(component).textContent).toEqual("Joining …");
|
||||
expect(getMessage(component)?.textContent).toEqual("Joining …");
|
||||
});
|
||||
it("renders rejecting message", () => {
|
||||
const component = getComponent({ rejecting: true });
|
||||
expect(isSpinnerRendered(component)).toBeTruthy();
|
||||
expect(getMessage(component).textContent).toEqual("Rejecting invite …");
|
||||
expect(getMessage(component)?.textContent).toEqual("Rejecting invite …");
|
||||
});
|
||||
it("renders loading message", () => {
|
||||
const component = getComponent({ loading: true });
|
||||
expect(isSpinnerRendered(component)).toBeTruthy();
|
||||
expect(getMessage(component).textContent).toEqual("Loading …");
|
||||
expect(getMessage(component)?.textContent).toEqual("Loading …");
|
||||
});
|
||||
|
||||
it("renders not logged in message", () => {
|
||||
|
@ -120,7 +120,7 @@ describe("<RoomPreviewBar />", () => {
|
|||
const component = getComponent({ loading: true });
|
||||
|
||||
expect(isSpinnerRendered(component)).toBeFalsy();
|
||||
expect(getMessage(component).textContent).toEqual("Join the conversation with an account");
|
||||
expect(getMessage(component)?.textContent).toEqual("Join the conversation with an account");
|
||||
});
|
||||
|
||||
it("should send room oob data to start login", async () => {
|
||||
|
@ -136,8 +136,8 @@ describe("<RoomPreviewBar />", () => {
|
|||
const dispatcherSpy = jest.fn();
|
||||
const dispatcherRef = defaultDispatcher.register(dispatcherSpy);
|
||||
|
||||
expect(getMessage(component).textContent).toEqual("Join the conversation with an account");
|
||||
fireEvent.click(getPrimaryActionButton(component));
|
||||
expect(getMessage(component)?.textContent).toEqual("Join the conversation with an account");
|
||||
fireEvent.click(getPrimaryActionButton(component)!);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(dispatcherSpy).toHaveBeenCalledWith(
|
||||
|
@ -222,13 +222,13 @@ describe("<RoomPreviewBar />", () => {
|
|||
});
|
||||
describe("without an invited email", () => {
|
||||
describe("for a non-dm room", () => {
|
||||
const mockGetMember = (id) => {
|
||||
const mockGetMember = (id: string) => {
|
||||
if (id === userId) return userMember;
|
||||
return inviterMember;
|
||||
};
|
||||
const onJoinClick = jest.fn();
|
||||
const onRejectClick = jest.fn();
|
||||
let room;
|
||||
let room: Room;
|
||||
|
||||
beforeEach(() => {
|
||||
room = createRoom(roomId, userId);
|
||||
|
@ -268,27 +268,27 @@ describe("<RoomPreviewBar />", () => {
|
|||
|
||||
it("joins room on primary button click", () => {
|
||||
const component = getComponent({ inviterName, room, onJoinClick, onRejectClick });
|
||||
fireEvent.click(getPrimaryActionButton(component));
|
||||
fireEvent.click(getPrimaryActionButton(component)!);
|
||||
|
||||
expect(onJoinClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects invite on secondary button click", () => {
|
||||
const component = getComponent({ inviterName, room, onJoinClick, onRejectClick });
|
||||
fireEvent.click(getSecondaryActionButton(component));
|
||||
fireEvent.click(getSecondaryActionButton(component)!);
|
||||
|
||||
expect(onRejectClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("for a dm room", () => {
|
||||
const mockGetMember = (id) => {
|
||||
const mockGetMember = (id: string) => {
|
||||
if (id === userId) return userMemberWithDmInvite;
|
||||
return inviterMember;
|
||||
};
|
||||
const onJoinClick = jest.fn();
|
||||
const onRejectClick = jest.fn();
|
||||
let room;
|
||||
let room: Room;
|
||||
|
||||
beforeEach(() => {
|
||||
room = createRoom(roomId, userId);
|
||||
|
@ -324,14 +324,14 @@ describe("<RoomPreviewBar />", () => {
|
|||
{ medium: "not-email", address: "address 2" },
|
||||
];
|
||||
|
||||
const testJoinButton = (props) => async () => {
|
||||
const testJoinButton = (props: ComponentProps<typeof RoomPreviewBar>) => async () => {
|
||||
const onJoinClick = jest.fn();
|
||||
const onRejectClick = jest.fn();
|
||||
const component = getComponent({ ...props, onJoinClick, onRejectClick });
|
||||
await new Promise(setImmediate);
|
||||
expect(getPrimaryActionButton(component)).toBeTruthy();
|
||||
expect(getSecondaryActionButton(component)).toBeFalsy();
|
||||
fireEvent.click(getPrimaryActionButton(component));
|
||||
fireEvent.click(getPrimaryActionButton(component)!);
|
||||
expect(onJoinClick).toHaveBeenCalled();
|
||||
};
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ describe("<SendMessageComposer/>", () => {
|
|||
resizing: false,
|
||||
narrow: false,
|
||||
activeCall: null,
|
||||
msc3946ProcessDynamicPredecessor: false,
|
||||
};
|
||||
describe("createMessageContent", () => {
|
||||
const permalinkCreator = jest.fn() as any;
|
||||
|
|
|
@ -24,8 +24,8 @@ import * as mockKeyboard from "../../../../../../src/Keyboard";
|
|||
|
||||
describe("PlainTextComposer", () => {
|
||||
const customRender = (
|
||||
onChange = (_content: string) => void 0,
|
||||
onSend = () => void 0,
|
||||
onChange = (_content: string): void => void 0,
|
||||
onSend = (): void => void 0,
|
||||
disabled = false,
|
||||
initialContent?: string,
|
||||
) => {
|
||||
|
|
|
@ -21,7 +21,7 @@ import { Key } from "../../../../src/Keyboard";
|
|||
import { mockPlatformPeg, unmockPlatformPeg } from "../../../test-utils/platform";
|
||||
import { KeyboardKey, KeyboardShortcut } from "../../../../src/components/views/settings/KeyboardShortcut";
|
||||
|
||||
const renderKeyboardShortcut = (Component, props?) => {
|
||||
const renderKeyboardShortcut = (Component: React.FunctionComponentFactory<any>, props: Record<string, any>) => {
|
||||
return render(<Component {...props} />).container;
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
MatrixEvent,
|
||||
Room,
|
||||
NotificationCountType,
|
||||
PushRuleActionName,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { IThreepid, ThreepidMedium } from "matrix-js-sdk/src/@types/threepids";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
@ -38,15 +39,14 @@ jest.mock("matrix-js-sdk/src/logger");
|
|||
// Avoid indirectly importing any eagerly created stores that would require extra setup
|
||||
jest.mock("../../../../src/Notifier");
|
||||
|
||||
const masterRule = {
|
||||
actions: ["dont_notify"],
|
||||
const masterRule: IPushRule = {
|
||||
actions: [PushRuleActionName.DontNotify],
|
||||
conditions: [],
|
||||
default: true,
|
||||
enabled: false,
|
||||
rule_id: RuleId.Master,
|
||||
};
|
||||
// eslint-disable-next-line max-len
|
||||
const oneToOneRule = {
|
||||
const oneToOneRule: IPushRule = {
|
||||
conditions: [
|
||||
{ kind: "room_member_count", is: "2" },
|
||||
{ kind: "event_match", key: "type", pattern: "m.room.message" },
|
||||
|
@ -56,8 +56,7 @@ const oneToOneRule = {
|
|||
default: true,
|
||||
enabled: true,
|
||||
} as IPushRule;
|
||||
// eslint-disable-next-line max-len
|
||||
const encryptedOneToOneRule = {
|
||||
const encryptedOneToOneRule: IPushRule = {
|
||||
conditions: [
|
||||
{ kind: "room_member_count", is: "2" },
|
||||
{ kind: "event_match", key: "type", pattern: "m.room.encrypted" },
|
||||
|
@ -67,15 +66,13 @@ const encryptedOneToOneRule = {
|
|||
default: true,
|
||||
enabled: true,
|
||||
} as IPushRule;
|
||||
// eslint-disable-next-line max-len
|
||||
const encryptedGroupRule = {
|
||||
const encryptedGroupRule: IPushRule = {
|
||||
conditions: [{ kind: "event_match", key: "type", pattern: "m.room.encrypted" }],
|
||||
actions: ["dont_notify"],
|
||||
rule_id: ".m.rule.encrypted",
|
||||
default: true,
|
||||
enabled: true,
|
||||
} as IPushRule;
|
||||
// eslint-disable-next-line max-len
|
||||
const pushRules: IPushRules = {
|
||||
global: {
|
||||
underride: [
|
||||
|
@ -367,7 +364,7 @@ describe("<Notifications />", () => {
|
|||
|
||||
it("toggles and sets settings correctly", async () => {
|
||||
await getComponentAndWait();
|
||||
let audioNotifsToggle;
|
||||
let audioNotifsToggle: HTMLDivElement;
|
||||
|
||||
const update = () => {
|
||||
audioNotifsToggle = screen
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { fireEvent, render } from "@testing-library/react";
|
||||
import { PUSHER_ENABLED } from "matrix-js-sdk/src/@types/event";
|
||||
|
||||
|
@ -28,11 +28,10 @@ describe("<DeviceDetails />", () => {
|
|||
isVerified: false,
|
||||
deviceType: DeviceType.Unknown,
|
||||
};
|
||||
const defaultProps = {
|
||||
const defaultProps: ComponentProps<typeof DeviceDetails> = {
|
||||
device: baseDevice,
|
||||
pusher: null,
|
||||
isSigningOut: false,
|
||||
isLoading: false,
|
||||
onSignOutDevice: jest.fn(),
|
||||
saveDeviceName: jest.fn(),
|
||||
setPushNotifications: jest.fn(),
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { act, fireEvent, render } from "@testing-library/react";
|
||||
|
||||
import { FilteredDeviceList } from "../../../../../src/components/views/settings/devices/FilteredDeviceList";
|
||||
|
@ -26,6 +26,9 @@ mockPlatformPeg();
|
|||
|
||||
const MS_DAY = 86400000;
|
||||
describe("<FilteredDeviceList />", () => {
|
||||
// 14.03.2022 16:15
|
||||
const now = 1647270879403;
|
||||
jest.spyOn(global.Date, "now").mockReturnValue(now);
|
||||
const newDevice = {
|
||||
device_id: "new",
|
||||
last_seen_ts: Date.now() - 500,
|
||||
|
@ -56,13 +59,12 @@ describe("<FilteredDeviceList />", () => {
|
|||
last_seen_ts: Date.now() - MS_DAY * 100,
|
||||
deviceType: DeviceType.Unknown,
|
||||
};
|
||||
const defaultProps = {
|
||||
const defaultProps: ComponentProps<typeof FilteredDeviceList> = {
|
||||
onFilterChange: jest.fn(),
|
||||
onDeviceExpandToggle: jest.fn(),
|
||||
onSignOutDevices: jest.fn(),
|
||||
saveDeviceName: jest.fn(),
|
||||
setPushNotifications: jest.fn(),
|
||||
setPusherEnabled: jest.fn(),
|
||||
setSelectedDeviceIds: jest.fn(),
|
||||
localNotificationSettings: new Map(),
|
||||
expandedDeviceIds: [],
|
||||
|
@ -81,6 +83,10 @@ describe("<FilteredDeviceList />", () => {
|
|||
|
||||
const getComponent = (props = {}) => <FilteredDeviceList {...defaultProps} {...props} />;
|
||||
|
||||
afterAll(() => {
|
||||
jest.spyOn(global.Date, "now").mockRestore();
|
||||
});
|
||||
|
||||
it("renders devices in correct order", () => {
|
||||
const { container } = render(getComponent());
|
||||
const tiles = container.querySelectorAll(".mx_DeviceTile");
|
||||
|
|
|
@ -28,7 +28,7 @@ jest.mock("matrix-js-sdk/src/rendezvous/channels");
|
|||
|
||||
const mockedFlow = jest.fn();
|
||||
|
||||
jest.mock("../../../../../src/components/views/auth/LoginWithQRFlow", () => (props) => {
|
||||
jest.mock("../../../../../src/components/views/auth/LoginWithQRFlow", () => (props: Record<string, any>) => {
|
||||
mockedFlow(props);
|
||||
return <div />;
|
||||
});
|
||||
|
|
|
@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { UIAFlow } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { deleteDevicesWithInteractiveAuth } from "../../../../../src/components/views/settings/devices/deleteDevices";
|
||||
import Modal from "../../../../../src/Modal";
|
||||
import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../../test-utils";
|
||||
|
@ -28,7 +30,7 @@ describe("deleteDevices()", () => {
|
|||
|
||||
const modalSpy = jest.spyOn(Modal, "createDialog");
|
||||
|
||||
const interactiveAuthError = { httpStatus: 401, data: { flows: [] } };
|
||||
const interactiveAuthError = { httpStatus: 401, data: { flows: [] as UIAFlow[] } };
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
|
|
@ -39,11 +39,11 @@ describe("RolesRoomSettingsTab", () => {
|
|||
};
|
||||
|
||||
const getVoiceBroadcastsSelect = (): HTMLElement => {
|
||||
return renderTab().container.querySelector("select[label='Voice broadcasts']");
|
||||
return renderTab().container.querySelector("select[label='Voice broadcasts']")!;
|
||||
};
|
||||
|
||||
const getVoiceBroadcastsSelectedOption = (): HTMLElement => {
|
||||
return renderTab().container.querySelector("select[label='Voice broadcasts'] option:checked");
|
||||
return renderTab().container.querySelector("select[label='Voice broadcasts'] option:checked")!;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -65,7 +65,7 @@ describe("RolesRoomSettingsTab", () => {
|
|||
state_key: "",
|
||||
content: {
|
||||
users: {
|
||||
[cli.getUserId()]: 100,
|
||||
[cli.getUserId()!]: 100,
|
||||
"@admin:server": 100,
|
||||
},
|
||||
},
|
||||
|
@ -108,19 +108,19 @@ describe("RolesRoomSettingsTab", () => {
|
|||
};
|
||||
|
||||
const getStartCallSelect = (tab: RenderResult): HTMLElement => {
|
||||
return tab.container.querySelector("select[label='Start Element Call calls']");
|
||||
return tab.container.querySelector("select[label='Start Element Call calls']")!;
|
||||
};
|
||||
|
||||
const getStartCallSelectedOption = (tab: RenderResult): HTMLElement => {
|
||||
return tab.container.querySelector("select[label='Start Element Call calls'] option:checked");
|
||||
return tab.container.querySelector("select[label='Start Element Call calls'] option:checked")!;
|
||||
};
|
||||
|
||||
const getJoinCallSelect = (tab: RenderResult): HTMLElement => {
|
||||
return tab.container.querySelector("select[label='Join Element Call calls']");
|
||||
return tab.container.querySelector("select[label='Join Element Call calls']")!;
|
||||
};
|
||||
|
||||
const getJoinCallSelectedOption = (tab: RenderResult): HTMLElement => {
|
||||
return tab.container.querySelector("select[label='Join Element Call calls'] option:checked");
|
||||
return tab.container.querySelector("select[label='Join Element Call calls'] option:checked")!;
|
||||
};
|
||||
|
||||
describe("Element Call enabled", () => {
|
||||
|
|
|
@ -46,7 +46,7 @@ describe("RolesRoomSettingsTab", () => {
|
|||
});
|
||||
|
||||
describe("Element Call", () => {
|
||||
const mockPowerLevels = (events): void => {
|
||||
const mockPowerLevels = (events: Record<string, number>): void => {
|
||||
jest.spyOn(room.currentState, "getStateEvents").mockReturnValue({
|
||||
getContent: () => ({
|
||||
events,
|
||||
|
|
|
@ -24,7 +24,7 @@ import { mockPlatformPeg } from "../../../../../test-utils/platform";
|
|||
const PATH_TO_KEYBOARD_SHORTCUTS = "../../../../../../src/accessibility/KeyboardShortcuts";
|
||||
const PATH_TO_KEYBOARD_SHORTCUT_UTILS = "../../../../../../src/accessibility/KeyboardShortcutUtils";
|
||||
|
||||
const mockKeyboardShortcuts = (override) => {
|
||||
const mockKeyboardShortcuts = (override: Record<string, any>) => {
|
||||
jest.doMock(PATH_TO_KEYBOARD_SHORTCUTS, () => {
|
||||
const original = jest.requireActual(PATH_TO_KEYBOARD_SHORTCUTS);
|
||||
return {
|
||||
|
@ -34,7 +34,7 @@ const mockKeyboardShortcuts = (override) => {
|
|||
});
|
||||
};
|
||||
|
||||
const mockKeyboardShortcutUtils = (override) => {
|
||||
const mockKeyboardShortcutUtils = (override: Record<string, any>) => {
|
||||
jest.doMock(PATH_TO_KEYBOARD_SHORTCUT_UTILS, () => {
|
||||
const original = jest.requireActual(PATH_TO_KEYBOARD_SHORTCUT_UTILS);
|
||||
return {
|
||||
|
@ -68,7 +68,7 @@ describe("KeyboardUserSettingsTab", () => {
|
|||
},
|
||||
});
|
||||
mockKeyboardShortcutUtils({
|
||||
getKeyboardShortcutValue: (name) => {
|
||||
getKeyboardShortcutValue: (name: string) => {
|
||||
switch (name) {
|
||||
case "keybind1":
|
||||
return {
|
||||
|
@ -88,7 +88,7 @@ describe("KeyboardUserSettingsTab", () => {
|
|||
}
|
||||
}
|
||||
},
|
||||
getKeyboardShortcutDisplayName: (name) => {
|
||||
getKeyboardShortcutDisplayName: (name: string) => {
|
||||
switch (name) {
|
||||
case "keybind1":
|
||||
return "Cancel replying to a message";
|
||||
|
|
|
@ -927,7 +927,7 @@ describe("<SessionManagerTab />", () => {
|
|||
// get a handle for resolving the delete call
|
||||
// because promise flushing after the confirm modal is resolving this too
|
||||
// and we want to test the loading state here
|
||||
let resolveDeleteRequest;
|
||||
let resolveDeleteRequest: (v?: IAuthData) => void;
|
||||
mockClient.deleteMultipleDevices.mockImplementation(() => {
|
||||
const promise = new Promise<IAuthData>((resolve) => {
|
||||
resolveDeleteRequest = resolve;
|
||||
|
|
|
@ -21,7 +21,7 @@ import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
|||
|
||||
import UnwrappedSpacePanel from "../../../../src/components/views/spaces/SpacePanel";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import { SpaceKey } from "../../../../src/stores/spaces";
|
||||
import { MetaSpace, SpaceKey } from "../../../../src/stores/spaces";
|
||||
import { shouldShowComponent } from "../../../../src/customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../../../../src/settings/UIFeature";
|
||||
import { wrapInSdkContext } from "../../../test-utils";
|
||||
|
@ -31,9 +31,9 @@ jest.mock("../../../../src/stores/spaces/SpaceStore", () => {
|
|||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const EventEmitter = require("events");
|
||||
class MockSpaceStore extends EventEmitter {
|
||||
invitedSpaces = [];
|
||||
enabledMetaSpaces = [];
|
||||
spacePanelSpaces = [];
|
||||
invitedSpaces: SpaceKey[] = [];
|
||||
enabledMetaSpaces: MetaSpace[] = [];
|
||||
spacePanelSpaces: string[] = [];
|
||||
activeSpace: SpaceKey = "!space1";
|
||||
}
|
||||
return {
|
||||
|
|
|
@ -93,15 +93,15 @@ describe("<SpaceSettingsVisibilityTab />", () => {
|
|||
};
|
||||
|
||||
const getByTestId = (container: Element, id: string) => container.querySelector(`[data-test-id=${id}]`);
|
||||
const toggleGuestAccessSection = async (component) => {
|
||||
const toggleGuestAccessSection = async (component: Element) => {
|
||||
const toggleButton = getByTestId(component, "toggle-guest-access-btn");
|
||||
await act(async () => {
|
||||
Simulate.click(toggleButton);
|
||||
});
|
||||
};
|
||||
const getGuestAccessToggle = (component) => component.querySelector('[aria-label="Enable guest access"');
|
||||
const getHistoryVisibilityToggle = (component) => component.querySelector('[aria-label="Preview Space"');
|
||||
const getErrorMessage = (component) => getByTestId(component, "space-settings-error")?.textContent;
|
||||
const getGuestAccessToggle = (component: Element) => component.querySelector('[aria-label="Enable guest access"');
|
||||
const getHistoryVisibilityToggle = (component: Element) => component.querySelector('[aria-label="Preview Space"');
|
||||
const getErrorMessage = (component: Element) => getByTestId(component, "space-settings-error")?.textContent;
|
||||
|
||||
beforeEach(() => {
|
||||
(mockMatrixClient.sendStateEvent as jest.Mock).mockClear().mockResolvedValue({});
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { parseEvent } from "../../src/editor/deserialize";
|
||||
import { Part } from "../../src/editor/parts";
|
||||
import { createPartCreator } from "./mock";
|
||||
|
||||
const FOUR_SPACES = " ".repeat(4);
|
||||
|
@ -50,12 +51,12 @@ function textMessageReply(body: string, msgtype = "m.text") {
|
|||
} as unknown as MatrixEvent;
|
||||
}
|
||||
|
||||
function mergeAdjacentParts(parts) {
|
||||
let prevPart;
|
||||
function mergeAdjacentParts(parts: Part[]) {
|
||||
let prevPart: Part | undefined;
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
let part = parts[i];
|
||||
const isEmpty = !part.text.length;
|
||||
const isMerged = !isEmpty && prevPart && prevPart.merge(part);
|
||||
const isMerged = !isEmpty && prevPart && prevPart.merge?.(part);
|
||||
if (isEmpty || isMerged) {
|
||||
// remove empty or merged part
|
||||
part = prevPart;
|
||||
|
@ -67,7 +68,7 @@ function mergeAdjacentParts(parts) {
|
|||
}
|
||||
}
|
||||
|
||||
function normalize(parts) {
|
||||
function normalize(parts: Part[]) {
|
||||
// merge adjacent parts as this will happen
|
||||
// in the model anyway, and whether 1 or multiple
|
||||
// plain parts are returned is an implementation detail
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Room, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { Room, MatrixClient, RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import AutocompleteWrapperModel, { UpdateCallback } from "../../src/editor/autocomplete";
|
||||
import { Caret } from "../../src/editor/caret";
|
||||
|
@ -63,7 +63,7 @@ class MockAutoComplete {
|
|||
// MockClient & MockRoom are only used for avatars in room and user pills,
|
||||
// which is not tested
|
||||
class MockRoom {
|
||||
getMember() {
|
||||
getMember(): RoomMember | null {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,10 @@ limitations under the License.
|
|||
|
||||
import EditorModel from "../../src/editor/model";
|
||||
import { createPartCreator } from "./mock";
|
||||
import { Caret } from "../../src/editor/caret";
|
||||
|
||||
function createRenderer() {
|
||||
const render = (c) => {
|
||||
const render = (c: Caret) => {
|
||||
render.caret = c;
|
||||
render.count += 1;
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@ describe("useDebouncedCallback", () => {
|
|||
beforeAll(() => jest.useFakeTimers());
|
||||
afterAll(() => jest.useRealTimers());
|
||||
|
||||
function render(enabled: boolean, callback: (...params: any) => void, params: any) {
|
||||
function render(enabled: boolean, callback: (...params: any[]) => void, params: any[]) {
|
||||
return renderHook(({ enabled, callback, params }) => useDebouncedCallback(enabled, callback, params), {
|
||||
initialProps: {
|
||||
enabled,
|
||||
|
@ -34,7 +34,7 @@ describe("useDebouncedCallback", () => {
|
|||
|
||||
it("should be able to handle empty parameters", async () => {
|
||||
// When
|
||||
const params = [];
|
||||
const params: any[] = [];
|
||||
const callback = jest.fn();
|
||||
render(true, callback, params);
|
||||
jest.advanceTimersByTime(1);
|
||||
|
|
|
@ -22,12 +22,12 @@ import { act } from "react-dom/test-utils";
|
|||
|
||||
import { useLatestResult } from "../../src/hooks/useLatestResult";
|
||||
|
||||
function LatestResultsComponent({ query, doRequest }) {
|
||||
function LatestResultsComponent({ query, doRequest }: { query: number; doRequest(query: number): Promise<number> }) {
|
||||
const [value, setValueInternal] = useState<number>(0);
|
||||
const [updateQuery, updateResult] = useLatestResult(setValueInternal);
|
||||
useEffect(() => {
|
||||
updateQuery(query);
|
||||
doRequest(query).then((it) => {
|
||||
doRequest(query).then((it: number) => {
|
||||
updateResult(query, it);
|
||||
});
|
||||
}, [doRequest, query, updateQuery, updateResult]);
|
||||
|
@ -37,7 +37,7 @@ function LatestResultsComponent({ query, doRequest }) {
|
|||
|
||||
describe("useLatestResult", () => {
|
||||
it("should return results", async () => {
|
||||
const doRequest = async (query) => {
|
||||
const doRequest = async (query: number) => {
|
||||
await sleep(180);
|
||||
return query;
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ describe("useLatestResult", () => {
|
|||
});
|
||||
|
||||
it("should prevent out-of-order results", async () => {
|
||||
const doRequest = async (query) => {
|
||||
const doRequest = async (query: number) => {
|
||||
await sleep(query);
|
||||
return query;
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
import React from "react";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
@ -24,7 +25,7 @@ import { useProfileInfo } from "../../src/hooks/useProfileInfo";
|
|||
import { MatrixClientPeg } from "../../src/MatrixClientPeg";
|
||||
import { stubClient } from "../test-utils/test-utils";
|
||||
|
||||
function ProfileInfoComponent({ onClick }) {
|
||||
function ProfileInfoComponent({ onClick }: { onClick(hook: ReturnType<typeof useProfileInfo>): void }) {
|
||||
const profileInfo = useProfileInfo();
|
||||
|
||||
const { ready, loading, profile } = profileInfo;
|
||||
|
@ -38,7 +39,7 @@ function ProfileInfoComponent({ onClick }) {
|
|||
}
|
||||
|
||||
describe("useProfileInfo", () => {
|
||||
let cli;
|
||||
let cli: MatrixClient;
|
||||
|
||||
beforeEach(() => {
|
||||
stubClient();
|
||||
|
@ -58,7 +59,6 @@ describe("useProfileInfo", () => {
|
|||
<ProfileInfoComponent
|
||||
onClick={(hook) => {
|
||||
hook.search({
|
||||
limit: 1,
|
||||
query,
|
||||
});
|
||||
}}
|
||||
|
@ -79,7 +79,6 @@ describe("useProfileInfo", () => {
|
|||
<ProfileInfoComponent
|
||||
onClick={(hook) => {
|
||||
hook.search({
|
||||
limit: 1,
|
||||
query: "",
|
||||
});
|
||||
}}
|
||||
|
@ -103,7 +102,6 @@ describe("useProfileInfo", () => {
|
|||
<ProfileInfoComponent
|
||||
onClick={(hook) => {
|
||||
hook.search({
|
||||
limit: 1,
|
||||
query,
|
||||
});
|
||||
}}
|
||||
|
@ -130,7 +128,6 @@ describe("useProfileInfo", () => {
|
|||
<ProfileInfoComponent
|
||||
onClick={(hook) => {
|
||||
hook.search({
|
||||
limit: 1,
|
||||
query,
|
||||
});
|
||||
}}
|
||||
|
@ -153,7 +150,6 @@ describe("useProfileInfo", () => {
|
|||
<ProfileInfoComponent
|
||||
onClick={(hook) => {
|
||||
hook.search({
|
||||
limit: 1,
|
||||
query,
|
||||
});
|
||||
}}
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
import React from "react";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
@ -24,7 +25,7 @@ import { usePublicRoomDirectory } from "../../src/hooks/usePublicRoomDirectory";
|
|||
import { MatrixClientPeg } from "../../src/MatrixClientPeg";
|
||||
import { stubClient } from "../test-utils/test-utils";
|
||||
|
||||
function PublicRoomComponent({ onClick }) {
|
||||
function PublicRoomComponent({ onClick }: { onClick(hook: ReturnType<typeof usePublicRoomDirectory>): void }) {
|
||||
const roomDirectory = usePublicRoomDirectory();
|
||||
|
||||
const { ready, loading, publicRooms } = roomDirectory;
|
||||
|
@ -38,7 +39,7 @@ function PublicRoomComponent({ onClick }) {
|
|||
}
|
||||
|
||||
describe("usePublicRoomDirectory", () => {
|
||||
let cli;
|
||||
let cli: MatrixClient;
|
||||
|
||||
beforeEach(() => {
|
||||
stubClient();
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from "enzyme";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
import React from "react";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
@ -24,7 +25,7 @@ import { useUserDirectory } from "../../src/hooks/useUserDirectory";
|
|||
import { MatrixClientPeg } from "../../src/MatrixClientPeg";
|
||||
import { stubClient } from "../test-utils";
|
||||
|
||||
function UserDirectoryComponent({ onClick }) {
|
||||
function UserDirectoryComponent({ onClick }: { onClick(hook: ReturnType<typeof useUserDirectory>): void }) {
|
||||
const userDirectory = useUserDirectory();
|
||||
|
||||
const { ready, loading, users } = userDirectory;
|
||||
|
@ -37,7 +38,7 @@ function UserDirectoryComponent({ onClick }) {
|
|||
}
|
||||
|
||||
describe("useUserDirectory", () => {
|
||||
let cli;
|
||||
let cli: MatrixClient;
|
||||
|
||||
beforeEach(() => {
|
||||
stubClient();
|
||||
|
@ -53,6 +54,7 @@ describe("useUserDirectory", () => {
|
|||
display_name: query,
|
||||
},
|
||||
],
|
||||
limited: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ describe("languageHandler", function () {
|
|||
{ policyLink: () => "foo" },
|
||||
"Accept foo to continue:",
|
||||
],
|
||||
["handles text in tags", textInTagSub, {}, { a: (sub) => `x${sub}x` }, "xUpgradex to your own domain"],
|
||||
["handles text in tags", textInTagSub, {}, { a: (sub: string) => `x${sub}x` }, "xUpgradex to your own domain"],
|
||||
[
|
||||
"handles variable substitution with React function component",
|
||||
variableSub,
|
||||
|
@ -82,7 +82,7 @@ describe("languageHandler", function () {
|
|||
],
|
||||
];
|
||||
|
||||
let oldNodeEnv;
|
||||
let oldNodeEnv: string;
|
||||
beforeAll(() => {
|
||||
oldNodeEnv = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = "test";
|
||||
|
@ -138,7 +138,7 @@ describe("languageHandler", function () {
|
|||
// counterpart doesnt expose any way to restore default config
|
||||
// missingEntryGenerator is mocked in the root setup file
|
||||
// reset to default here
|
||||
const counterpartDefaultMissingEntryGen = function (key) {
|
||||
const counterpartDefaultMissingEntryGen = function (key: string) {
|
||||
return "missing translation: " + key;
|
||||
};
|
||||
setMissingEntryGenerator(counterpartDefaultMissingEntryGen);
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
import { linkify, Type } from "../src/linkify-matrix";
|
||||
|
||||
describe("linkify-matrix", () => {
|
||||
const linkTypesByInitialCharacter = {
|
||||
const linkTypesByInitialCharacter: Record<string, string> = {
|
||||
"#": "roomalias",
|
||||
"@": "userid",
|
||||
};
|
||||
|
|
|
@ -28,7 +28,7 @@ const TEST_DATA = [
|
|||
];
|
||||
|
||||
describe("SettingsStore", () => {
|
||||
let platformSettings: object;
|
||||
let platformSettings: Record<string, any>;
|
||||
|
||||
beforeAll(() => {
|
||||
jest.clearAllMocks();
|
||||
|
|
|
@ -72,17 +72,15 @@ describe("IncompatibleController", () => {
|
|||
describe("getValueOverride()", () => {
|
||||
it("returns forced value when setting is incompatible", () => {
|
||||
settingsGetValueSpy.mockReturnValue(true);
|
||||
const forcedValue = { key: null };
|
||||
const controller = new IncompatibleController("feature_spotlight", forcedValue);
|
||||
const controller = new IncompatibleController("feature_spotlight", { key: null });
|
||||
expect(
|
||||
controller.getValueOverride(SettingLevel.ACCOUNT, "$room:server", true, SettingLevel.ACCOUNT),
|
||||
).toEqual(forcedValue);
|
||||
).toEqual({ key: null });
|
||||
});
|
||||
|
||||
it("returns null when setting is not incompatible", () => {
|
||||
settingsGetValueSpy.mockReturnValue(false);
|
||||
const forcedValue = { key: null };
|
||||
const controller = new IncompatibleController("feature_spotlight", forcedValue);
|
||||
const controller = new IncompatibleController("feature_spotlight", { key: null });
|
||||
expect(
|
||||
controller.getValueOverride(SettingLevel.ACCOUNT, "$room:server", true, SettingLevel.ACCOUNT),
|
||||
).toEqual(null);
|
||||
|
|
|
@ -30,8 +30,10 @@ const lv = {
|
|||
// de_DE.json
|
||||
// lv.json - mock version with few translations, used to test fallback translation
|
||||
|
||||
function weblateToCounterpart(inTrs: object): object {
|
||||
const outTrs = {};
|
||||
type Translations = Record<string, Record<string, string> | string>;
|
||||
|
||||
function weblateToCounterpart(inTrs: Record<string, string>): Translations {
|
||||
const outTrs: Translations = {};
|
||||
|
||||
for (const key of Object.keys(inTrs)) {
|
||||
const keyParts = key.split("|", 2);
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
import { TextDecoder, TextEncoder } from "util";
|
||||
import fetch from "node-fetch";
|
||||
import { Response } from "node-fetch";
|
||||
|
||||
// jest 27 removes setImmediate from jsdom
|
||||
// polyfill until setImmediate use in client can be removed
|
||||
|
@ -88,7 +88,8 @@ fetchMock.get("/image-file-stub", "image file stub");
|
|||
// @ts-ignore
|
||||
window.fetch = fetchMock.sandbox();
|
||||
|
||||
window.Response = fetch.Response;
|
||||
// @ts-ignore
|
||||
window.Response = Response;
|
||||
|
||||
// set up mediaDevices mock
|
||||
Object.defineProperty(navigator, "mediaDevices", {
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
import { makeBeaconContent, makeBeaconInfoContent } from "matrix-js-sdk/src/content-helpers";
|
||||
import { M_BEACON } from "matrix-js-sdk/src/@types/beacon";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { Mocked } from "jest-mock";
|
||||
|
||||
import { OwnBeaconStore, OwnBeaconStoreEvent } from "../../src/stores/OwnBeaconStore";
|
||||
import {
|
||||
|
@ -48,7 +49,7 @@ jest.mock("lodash", () => ({
|
|||
jest.useFakeTimers();
|
||||
|
||||
describe("OwnBeaconStore", () => {
|
||||
let geolocation;
|
||||
let geolocation: Mocked<Geolocation>;
|
||||
// 14.03.2022 16:15
|
||||
const now = 1647270879403;
|
||||
const HOUR_MS = 3600000;
|
||||
|
@ -82,7 +83,7 @@ describe("OwnBeaconStore", () => {
|
|||
|
||||
// make fresh rooms every time
|
||||
// as we update room state
|
||||
const makeRoomsWithStateEvents = (stateEvents = []): [Room, Room] => {
|
||||
const makeRoomsWithStateEvents = (stateEvents: MatrixEvent[] = []): [Room, Room] => {
|
||||
const room1 = new Room(room1Id, mockClient, aliceId);
|
||||
const room2 = new Room(room2Id, mockClient, aliceId);
|
||||
|
||||
|
@ -100,7 +101,7 @@ describe("OwnBeaconStore", () => {
|
|||
return store;
|
||||
};
|
||||
|
||||
const expireBeaconAndEmit = (store, beaconInfoEvent: MatrixEvent): void => {
|
||||
const expireBeaconAndEmit = (store: OwnBeaconStore, beaconInfoEvent: MatrixEvent): void => {
|
||||
const beacon = store.getBeaconById(getBeaconInfoIdentifier(beaconInfoEvent));
|
||||
// time travel until beacon is expired
|
||||
advanceDateAndTime(beacon.beaconInfo.timeout + 100);
|
||||
|
@ -112,7 +113,11 @@ describe("OwnBeaconStore", () => {
|
|||
mockClient.emit(BeaconEvent.LivenessChange, false, beacon);
|
||||
};
|
||||
|
||||
const updateBeaconLivenessAndEmit = (store, beaconInfoEvent: MatrixEvent, isLive: boolean): void => {
|
||||
const updateBeaconLivenessAndEmit = (
|
||||
store: OwnBeaconStore,
|
||||
beaconInfoEvent: MatrixEvent,
|
||||
isLive: boolean,
|
||||
): void => {
|
||||
const beacon = store.getBeaconById(getBeaconInfoIdentifier(beaconInfoEvent));
|
||||
// matches original state of event content
|
||||
// except for live property
|
||||
|
|
|
@ -20,7 +20,7 @@ import { EventType } from "matrix-js-sdk/src/@types/event";
|
|||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
import { ClientEvent, RoomEvent, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { ClientEvent, RoomEvent, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import SpaceStore from "../../src/stores/spaces/SpaceStore";
|
||||
import {
|
||||
|
@ -68,7 +68,7 @@ const space2 = "!space2:server";
|
|||
const space3 = "!space3:server";
|
||||
const space4 = "!space4:server";
|
||||
|
||||
const getUserIdForRoomId = jest.fn((roomId) => {
|
||||
const getUserIdForRoomId = jest.fn((roomId: string) => {
|
||||
return {
|
||||
[dm1]: dm1Partner.userId,
|
||||
[dm2]: dm2Partner.userId,
|
||||
|
@ -97,10 +97,10 @@ describe("SpaceStore", () => {
|
|||
|
||||
const spyDispatcher = jest.spyOn(defaultDispatcher, "dispatch");
|
||||
|
||||
let rooms = [];
|
||||
let rooms: Room[] = [];
|
||||
const mkRoom = (roomId: string) => testUtils.mkRoom(client, roomId, rooms);
|
||||
const mkSpace = (spaceId: string, children: string[] = []) => testUtils.mkSpace(client, spaceId, rooms, children);
|
||||
const viewRoom = (roomId) => defaultDispatcher.dispatch({ action: Action.ViewRoom, room_id: roomId }, true);
|
||||
const viewRoom = (roomId: string) => defaultDispatcher.dispatch({ action: Action.ViewRoom, room_id: roomId }, true);
|
||||
|
||||
const run = async () => {
|
||||
mocked(client).getRoom.mockImplementation((roomId) => rooms.find((room) => room.roomId === roomId));
|
||||
|
@ -785,17 +785,17 @@ describe("SpaceStore", () => {
|
|||
mkSpace(space1, [fav1, room1, space4]);
|
||||
});
|
||||
|
||||
const addChildRoom = (spaceId, childId) => {
|
||||
const addChildRoom = (spaceId: string, childId: string) => {
|
||||
const childEvent = mkEvent({
|
||||
event: true,
|
||||
type: EventType.SpaceChild,
|
||||
room: spaceId,
|
||||
user: client.getUserId(),
|
||||
user: client.getUserId()!,
|
||||
skey: childId,
|
||||
content: { via: [], canonical: true },
|
||||
ts: Date.now(),
|
||||
});
|
||||
const spaceRoom = client.getRoom(spaceId);
|
||||
const spaceRoom = client.getRoom(spaceId)!;
|
||||
mocked(spaceRoom.currentState).getStateEvents.mockImplementation(
|
||||
testUtils.mockStateEventImplementation([childEvent]),
|
||||
);
|
||||
|
@ -803,12 +803,12 @@ describe("SpaceStore", () => {
|
|||
client.emit(RoomStateEvent.Events, childEvent, spaceRoom.currentState, undefined);
|
||||
};
|
||||
|
||||
const addMember = (spaceId, user: RoomMember) => {
|
||||
const addMember = (spaceId: string, user: RoomMember) => {
|
||||
const memberEvent = mkEvent({
|
||||
event: true,
|
||||
type: EventType.RoomMember,
|
||||
room: spaceId,
|
||||
user: client.getUserId(),
|
||||
user: client.getUserId()!,
|
||||
skey: user.userId,
|
||||
content: { membership: "join" },
|
||||
ts: Date.now(),
|
||||
|
@ -998,8 +998,8 @@ describe("SpaceStore", () => {
|
|||
});
|
||||
|
||||
describe("context switching tests", () => {
|
||||
let dispatcherRef;
|
||||
let currentRoom = null;
|
||||
let dispatcherRef: string;
|
||||
let currentRoom: Room | null = null;
|
||||
|
||||
beforeEach(async () => {
|
||||
[room1, room2, orphan1].forEach(mkRoom);
|
||||
|
@ -1313,8 +1313,8 @@ describe("SpaceStore", () => {
|
|||
callback: (...args: any[]) => void,
|
||||
): () => void {
|
||||
callback();
|
||||
emitter.addListener(eventName, callback);
|
||||
return () => emitter.removeListener(eventName, callback);
|
||||
emitter?.addListener(eventName, callback);
|
||||
return () => emitter?.removeListener(eventName, callback);
|
||||
}
|
||||
|
||||
let metaSpaces;
|
||||
|
|
|
@ -31,7 +31,7 @@ describe("VoiceRecordingStore", () => {
|
|||
const room1Recording = { destroy: jest.fn() } as unknown as VoiceMessageRecording;
|
||||
const room2Recording = { destroy: jest.fn() } as unknown as VoiceMessageRecording;
|
||||
|
||||
const state = {
|
||||
const state: Record<string, VoiceMessageRecording | undefined> = {
|
||||
[room1Id]: room1Recording,
|
||||
[room2Id]: room2Recording,
|
||||
[room3Id]: undefined,
|
||||
|
|
|
@ -13,7 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { mocked } from "jest-mock";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
|
||||
import { SpaceWatcher } from "../../../src/stores/room-list/SpaceWatcher";
|
||||
import type { RoomListStoreClass } from "../../../src/stores/room-list/RoomListStore";
|
||||
|
@ -30,8 +32,8 @@ import DMRoomMap from "../../../src/utils/DMRoomMap";
|
|||
let filter: SpaceFilterCondition = null;
|
||||
|
||||
const mockRoomListStore = {
|
||||
addFilter: (f) => (filter = f),
|
||||
removeFilter: () => (filter = null),
|
||||
addFilter: (f: SpaceFilterCondition) => (filter = f),
|
||||
removeFilter: (): void => (filter = null),
|
||||
} as unknown as RoomListStoreClass;
|
||||
|
||||
const getUserIdForRoomId = jest.fn();
|
||||
|
@ -47,7 +49,7 @@ describe("SpaceWatcher", () => {
|
|||
const store = SpaceStore.instance;
|
||||
const client = mocked(MatrixClientPeg.get());
|
||||
|
||||
let rooms = [];
|
||||
let rooms: Room[] = [];
|
||||
const mkSpaceForRooms = (spaceId: string, children: string[] = []) => mkSpace(client, spaceId, rooms, children);
|
||||
|
||||
const setShowAllRooms = async (value: boolean) => {
|
||||
|
|
|
@ -15,17 +15,20 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { stubClient, mkRoom, mkMessage } from "../../../test-utils";
|
||||
import { mkMessage, mkRoom, stubClient } from "../../../test-utils";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import "../../../../src/stores/room-list/RoomListStore";
|
||||
import { RecentAlgorithm } from "../../../../src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm";
|
||||
import { EffectiveMembership } from "../../../../src/utils/membership";
|
||||
import { makeThreadEvent, mkThread } from "../../../test-utils/threads";
|
||||
import { DefaultTagID } from "../../../../src/stores/room-list/models";
|
||||
|
||||
describe("RecentAlgorithm", () => {
|
||||
let algorithm;
|
||||
let cli;
|
||||
let algorithm: RecentAlgorithm;
|
||||
let cli: MatrixClient;
|
||||
|
||||
beforeEach(() => {
|
||||
stubClient();
|
||||
cli = MatrixClientPeg.get();
|
||||
|
@ -102,7 +105,7 @@ describe("RecentAlgorithm", () => {
|
|||
room1.addLiveEvents([evt]);
|
||||
room2.addLiveEvents([evt2]);
|
||||
|
||||
expect(algorithm.sortRooms([room2, room1])).toEqual([room1, room2]);
|
||||
expect(algorithm.sortRooms([room2, room1], DefaultTagID.Untagged)).toEqual([room1, room2]);
|
||||
});
|
||||
|
||||
it("orders rooms without messages first", () => {
|
||||
|
@ -122,7 +125,7 @@ describe("RecentAlgorithm", () => {
|
|||
|
||||
room1.addLiveEvents([evt]);
|
||||
|
||||
expect(algorithm.sortRooms([room2, room1])).toEqual([room2, room1]);
|
||||
expect(algorithm.sortRooms([room2, room1], DefaultTagID.Untagged)).toEqual([room2, room1]);
|
||||
|
||||
const { events } = mkThread({
|
||||
room: room1,
|
||||
|
@ -162,21 +165,21 @@ describe("RecentAlgorithm", () => {
|
|||
});
|
||||
room2.addLiveEvents(events2);
|
||||
|
||||
expect(algorithm.sortRooms([room1, room2])).toEqual([room2, room1]);
|
||||
expect(algorithm.sortRooms([room1, room2], DefaultTagID.Untagged)).toEqual([room2, room1]);
|
||||
|
||||
const threadReply = makeThreadEvent({
|
||||
user: "@bob:matrix.org",
|
||||
room: room1.roomId,
|
||||
event: true,
|
||||
msg: `hello world`,
|
||||
rootEventId: rootEvent.getId(),
|
||||
replyToEventId: rootEvent.getId(),
|
||||
rootEventId: rootEvent.getId()!,
|
||||
replyToEventId: rootEvent.getId()!,
|
||||
// replies are 1ms after each other
|
||||
ts: 50,
|
||||
});
|
||||
room1.addLiveEvents([threadReply]);
|
||||
|
||||
expect(algorithm.sortRooms([room1, room2])).toEqual([room1, room2]);
|
||||
expect(algorithm.sortRooms([room1, room2], DefaultTagID.Untagged)).toEqual([room1, room2]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -20,7 +20,7 @@ import { Room } from "matrix-js-sdk/src/matrix";
|
|||
import SettingsStore from "../../../../src/settings/SettingsStore";
|
||||
import { FILTER_CHANGED } from "../../../../src/stores/room-list/filters/IFilterCondition";
|
||||
import { SpaceFilterCondition } from "../../../../src/stores/room-list/filters/SpaceFilterCondition";
|
||||
import { MetaSpace } from "../../../../src/stores/spaces";
|
||||
import { MetaSpace, SpaceKey } from "../../../../src/stores/spaces";
|
||||
import SpaceStore from "../../../../src/stores/spaces/SpaceStore";
|
||||
|
||||
jest.mock("../../../../src/settings/SettingsStore");
|
||||
|
@ -50,8 +50,8 @@ describe("SpaceFilterCondition", () => {
|
|||
const user2Id = "@u2:server";
|
||||
const user3Id = "@u3:server";
|
||||
const makeMockGetValue =
|
||||
(settings = {}) =>
|
||||
(settingName, space) =>
|
||||
(settings: Record<string, any> = {}) =>
|
||||
(settingName: string, space: SpaceKey) =>
|
||||
settings[settingName]?.[space] || false;
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -61,7 +61,7 @@ describe("SpaceFilterCondition", () => {
|
|||
SpaceStoreInstanceMock.isRoomInSpace.mockReturnValue(true);
|
||||
});
|
||||
|
||||
const initFilter = (space): SpaceFilterCondition => {
|
||||
const initFilter = (space: SpaceKey): SpaceFilterCondition => {
|
||||
const filter = new SpaceFilterCondition();
|
||||
filter.updateSpace(space);
|
||||
jest.runOnlyPendingTimers();
|
||||
|
|
|
@ -130,7 +130,7 @@ describe("StopGapWidgetDriver", () => {
|
|||
const aliceMobile = new DeviceInfo("aliceMobile");
|
||||
const bobDesktop = new DeviceInfo("bobDesktop");
|
||||
|
||||
mocked(client.crypto.deviceList).downloadKeys.mockResolvedValue({
|
||||
mocked(client.crypto!.deviceList).downloadKeys.mockResolvedValue({
|
||||
"@alice:example.org": { aliceWeb, aliceMobile },
|
||||
"@bob:example.org": { bobDesktop },
|
||||
});
|
||||
|
|
|
@ -38,7 +38,7 @@ describe("WidgetPermissionStore", () => {
|
|||
type: "m.custom",
|
||||
url: "https://invalid.address.here",
|
||||
});
|
||||
let settings = {}; // key value store
|
||||
let settings: Record<string, any> = {}; // key value store
|
||||
|
||||
beforeEach(() => {
|
||||
settings = {}; // clear settings
|
||||
|
|
|
@ -165,7 +165,7 @@ export const mockGeolocation = (): MockedObject<Geolocation> => {
|
|||
* See for error codes: https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPositionError
|
||||
*/
|
||||
export const watchPositionMockImplementation = (delays: number[], errorCodes: number[] = []) => {
|
||||
return (callback: PositionCallback, error: PositionErrorCallback) => {
|
||||
return (callback: PositionCallback, error: PositionErrorCallback): number => {
|
||||
const position = makeGeolocationPosition({});
|
||||
|
||||
let totalDelay = 0;
|
||||
|
@ -180,6 +180,8 @@ export const watchPositionMockImplementation = (delays: number[], errorCodes: nu
|
|||
}, totalDelay);
|
||||
return timeout;
|
||||
});
|
||||
|
||||
return totalDelay;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -24,12 +24,12 @@ export const addTextToComposer = (container: HTMLElement, text: string) =>
|
|||
act(() => {
|
||||
// couldn't get input event on contenteditable to work
|
||||
// paste works without illegal private method access
|
||||
const pasteEvent = {
|
||||
const pasteEvent: Partial<ClipboardEvent> = {
|
||||
clipboardData: {
|
||||
types: [],
|
||||
files: [],
|
||||
getData: (type) => (type === "text/plain" ? text : undefined),
|
||||
},
|
||||
getData: (type: string) => (type === "text/plain" ? text : undefined),
|
||||
} as unknown as DataTransfer,
|
||||
};
|
||||
fireEvent.paste(container.querySelector('[role="textbox"]'), pasteEvent);
|
||||
});
|
||||
|
@ -38,12 +38,12 @@ export const addTextToComposerEnzyme = (wrapper: ReactWrapper, text: string) =>
|
|||
act(() => {
|
||||
// couldn't get input event on contenteditable to work
|
||||
// paste works without illegal private method access
|
||||
const pasteEvent = {
|
||||
const pasteEvent: Partial<ClipboardEvent> = {
|
||||
clipboardData: {
|
||||
types: [],
|
||||
files: [],
|
||||
getData: (type) => (type === "text/plain" ? text : undefined),
|
||||
},
|
||||
getData: (type: string) => (type === "text/plain" ? text : undefined),
|
||||
} as unknown as DataTransfer,
|
||||
};
|
||||
wrapper.find('[role="textbox"]').simulate("paste", pasteEvent);
|
||||
wrapper.update();
|
||||
|
|
|
@ -89,13 +89,14 @@ export const makePollEndEvent = (pollStartEventId: string, roomId: string, sende
|
|||
* @returns
|
||||
*/
|
||||
export const setupRoomWithPollEvents = async (
|
||||
mxEvent: MatrixEvent,
|
||||
pollStartEvents: MatrixEvent[],
|
||||
relationEvents: Array<MatrixEvent>,
|
||||
endEvents: Array<MatrixEvent> = [],
|
||||
mockClient: Mocked<MatrixClient>,
|
||||
existingRoom?: Room,
|
||||
): Promise<Room> => {
|
||||
const room = new Room(mxEvent.getRoomId()!, mockClient, mockClient.getSafeUserId());
|
||||
room.processPollEvents([mxEvent, ...relationEvents, ...endEvents]);
|
||||
const room = existingRoom || new Room(pollStartEvents[0].getRoomId()!, mockClient, mockClient.getSafeUserId());
|
||||
room.processPollEvents([...pollStartEvents, ...relationEvents, ...endEvents]);
|
||||
|
||||
// set redaction allowed for current user only
|
||||
// poll end events are validated against this
|
||||
|
@ -106,8 +107,10 @@ export const setupRoomWithPollEvents = async (
|
|||
// wait for events to process on room
|
||||
await flushPromises();
|
||||
mockClient.getRoom.mockReturnValue(room);
|
||||
mockClient.relations.mockResolvedValue({
|
||||
events: [...relationEvents, ...endEvents],
|
||||
mockClient.relations.mockImplementation(async (_roomId: string, eventId: string) => {
|
||||
return {
|
||||
events: [...relationEvents, ...endEvents].filter((event) => event.getRelation()?.event_id === eventId),
|
||||
};
|
||||
});
|
||||
return room;
|
||||
};
|
||||
|
|
|
@ -86,6 +86,7 @@ export function getRoomContext(room: Room, override: Partial<IRoomState>): IRoom
|
|||
resizing: false,
|
||||
narrow: false,
|
||||
activeCall: null,
|
||||
msc3946ProcessDynamicPredecessor: false,
|
||||
|
||||
...override,
|
||||
};
|
||||
|
|
|
@ -69,12 +69,12 @@ export const makeThreadEvents = ({
|
|||
ts,
|
||||
});
|
||||
|
||||
const rootEventId = rootEvent.getId();
|
||||
const rootEventId = rootEvent.getId()!;
|
||||
const events = [rootEvent];
|
||||
|
||||
for (let i = 1; i < length; i++) {
|
||||
const prevEvent = events[i - 1];
|
||||
const replyToEventId = prevEvent.getId();
|
||||
const replyToEventId = prevEvent.getId()!;
|
||||
const user = participantUserIds[i % participantUserIds.length];
|
||||
events.push(
|
||||
makeThreadEvent({
|
||||
|
@ -95,7 +95,7 @@ export const makeThreadEvents = ({
|
|||
[RelationType.Thread]: {
|
||||
latest_event: events[events.length - 1],
|
||||
count: length,
|
||||
current_user_participated: [...participantUserIds, authorId].includes(currentUserId),
|
||||
current_user_participated: [...participantUserIds, authorId].includes(currentUserId!),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -126,7 +126,7 @@ export const mkThread = ({
|
|||
participantUserIds,
|
||||
length,
|
||||
ts,
|
||||
currentUserId: client.getUserId(),
|
||||
currentUserId: client.getUserId()!,
|
||||
});
|
||||
expect(rootEvent).toBeTruthy();
|
||||
|
||||
|
@ -134,7 +134,7 @@ export const mkThread = ({
|
|||
room?.reEmitter.reEmit(evt, [MatrixEventEvent.BeforeRedaction]);
|
||||
}
|
||||
|
||||
const thread = room.createThread(rootEvent.getId(), rootEvent, events, true);
|
||||
const thread = room.createThread(rootEvent.getId()!, rootEvent, events, true);
|
||||
// So that we do not have to mock the thread loading
|
||||
thread.initialEventsFetched = true;
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ export function untilDispatch(
|
|||
const callback = waitForAction as (payload: ActionPayload) => boolean;
|
||||
return new Promise((resolve, reject) => {
|
||||
let fulfilled = false;
|
||||
let timeoutId;
|
||||
let timeoutId: number;
|
||||
// set a timeout handler if needed
|
||||
if (timeout > 0) {
|
||||
timeoutId = window.setTimeout(() => {
|
||||
|
@ -95,7 +95,7 @@ export function untilEmission(
|
|||
const callerLine = new Error().stack.toString().split("\n")[2];
|
||||
return new Promise((resolve, reject) => {
|
||||
let fulfilled = false;
|
||||
let timeoutId;
|
||||
let timeoutId: number;
|
||||
// set a timeout handler if needed
|
||||
if (timeout > 0) {
|
||||
timeoutId = window.setTimeout(() => {
|
||||
|
|
|
@ -26,7 +26,7 @@ type WrapperProps<T> = { wrappedRef?: RefCallback<ComponentType<T>> } & T;
|
|||
export function wrapInMatrixClientContext<T>(WrappedComponent: ComponentType<T>): ComponentType<WrapperProps<T>> {
|
||||
class Wrapper extends React.Component<WrapperProps<T>> {
|
||||
_matrixClient: MatrixClient;
|
||||
constructor(props) {
|
||||
constructor(props: WrapperProps<T>) {
|
||||
super(props);
|
||||
|
||||
this._matrixClient = peg.get();
|
||||
|
|
|
@ -18,33 +18,29 @@ import { setTheme } from "../src/theme";
|
|||
|
||||
describe("theme", () => {
|
||||
describe("setTheme", () => {
|
||||
let lightTheme;
|
||||
let darkTheme;
|
||||
let lightTheme: HTMLStyleElement;
|
||||
let darkTheme: HTMLStyleElement;
|
||||
|
||||
let spyQuerySelectorAll: jest.MockInstance<NodeListOf<Element>, [selectors: string]>;
|
||||
|
||||
beforeEach(() => {
|
||||
const styles = [
|
||||
{
|
||||
attributes: {
|
||||
"data-mx-theme": {
|
||||
value: "light",
|
||||
},
|
||||
dataset: {
|
||||
mxTheme: "light",
|
||||
},
|
||||
disabled: true,
|
||||
href: "urlLight",
|
||||
onload: () => void 0,
|
||||
},
|
||||
onload: (): void => void 0,
|
||||
} as unknown as HTMLStyleElement,
|
||||
{
|
||||
attributes: {
|
||||
"data-mx-theme": {
|
||||
value: "dark",
|
||||
},
|
||||
dataset: {
|
||||
mxTheme: "dark",
|
||||
},
|
||||
disabled: true,
|
||||
href: "urlDark",
|
||||
onload: () => void 0,
|
||||
},
|
||||
onload: (): void => void 0,
|
||||
} as unknown as HTMLStyleElement,
|
||||
];
|
||||
lightTheme = styles[0];
|
||||
darkTheme = styles[1];
|
||||
|
@ -62,7 +58,7 @@ describe("theme", () => {
|
|||
// When
|
||||
await new Promise((resolve) => {
|
||||
setTheme("light").then(resolve);
|
||||
lightTheme.onload();
|
||||
lightTheme.onload(void 0);
|
||||
});
|
||||
|
||||
// Then
|
||||
|
|
54
test/utils/DMRoomMap-test.ts
Normal file
54
test/utils/DMRoomMap-test.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { mocked, Mocked } from "jest-mock";
|
||||
import { EventType, IContent, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import DMRoomMap from "../../src/utils/DMRoomMap";
|
||||
import { mkEvent, stubClient } from "../test-utils";
|
||||
|
||||
describe("DMRoomMap", () => {
|
||||
const roomId1 = "!room1:example.com";
|
||||
const roomId2 = "!room2:example.com";
|
||||
const roomId3 = "!room3:example.com";
|
||||
const roomId4 = "!room4:example.com";
|
||||
|
||||
const mDirectContent = {
|
||||
"user@example.com": [roomId1, roomId2],
|
||||
"@user:example.com": [roomId1, roomId3, roomId4],
|
||||
"@user2:example.com": [] as string[],
|
||||
} satisfies IContent;
|
||||
|
||||
let client: Mocked<MatrixClient>;
|
||||
let dmRoomMap: DMRoomMap;
|
||||
|
||||
beforeEach(() => {
|
||||
client = mocked(stubClient());
|
||||
|
||||
const mDirectEvent = mkEvent({
|
||||
event: true,
|
||||
type: EventType.Direct,
|
||||
user: client.getSafeUserId(),
|
||||
content: mDirectContent,
|
||||
});
|
||||
client.getAccountData.mockReturnValue(mDirectEvent);
|
||||
dmRoomMap = new DMRoomMap(client);
|
||||
});
|
||||
|
||||
it("getRoomIds should return the room Ids", () => {
|
||||
expect(dmRoomMap.getRoomIds()).toEqual(new Set([roomId1, roomId2, roomId3, roomId4]));
|
||||
});
|
||||
});
|
|
@ -42,7 +42,7 @@ describe("formatSeconds", () => {
|
|||
});
|
||||
|
||||
describe("formatRelativeTime", () => {
|
||||
let dateSpy;
|
||||
let dateSpy: jest.SpyInstance<number, []>;
|
||||
beforeAll(() => {
|
||||
dateSpy = jest
|
||||
.spyOn(global.Date, "now")
|
||||
|
|
|
@ -432,7 +432,7 @@ describe("EventUtils", () => {
|
|||
stubClient();
|
||||
client = MatrixClientPeg.get();
|
||||
|
||||
room = new Room(ROOM_ID, client, client.getUserId(), {
|
||||
room = new Room(ROOM_ID, client, client.getUserId()!, {
|
||||
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||
});
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue