Add ESLint Jest (#10261)

This commit is contained in:
Michael Weimann 2023-03-01 16:23:35 +01:00 committed by GitHub
parent db7748b743
commit 5398db21ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 336 additions and 351 deletions

View file

@ -165,10 +165,31 @@ module.exports = {
}, },
{ {
files: ["test/**/*.{ts,tsx}", "cypress/**/*.ts"], files: ["test/**/*.{ts,tsx}", "cypress/**/*.ts"],
extends: ["plugin:matrix-org/jest"],
rules: { rules: {
// We don't need super strict typing in test utilities // We don't need super strict typing in test utilities
"@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-member-accessibility": "off", "@typescript-eslint/explicit-member-accessibility": "off",
// Jest/Cypress specific
// Disabled tests are a reality for now but as soon as all of the xits are
// eliminated, we should enforce this.
"jest/no-disabled-tests": "off",
// TODO: There are many tests with invalid expects that should be fixed,
// https://github.com/vector-im/element-web/issues/24709
"jest/valid-expect": "off",
// TODO: There are many cases to refactor away,
// https://github.com/vector-im/element-web/issues/24710
"jest/no-conditional-expect": "off",
// Also treat "oldBackendOnly" as a test function.
// Used in some crypto tests.
"jest/no-standalone-expect": [
"error",
{
additionalTestBlockFunctions: ["beforeAll", "beforeEach", "oldBackendOnly"],
},
],
}, },
}, },
{ {
@ -176,6 +197,11 @@ module.exports = {
parserOptions: { parserOptions: {
project: ["./cypress/tsconfig.json"], project: ["./cypress/tsconfig.json"],
}, },
rules: {
// Cypress "promises" work differently - disable some related rules
"jest/valid-expect-in-promise": "off",
"jest/no-done-callback": "off",
},
}, },
], ],
settings: { settings: {

View file

@ -356,7 +356,7 @@ describe("Sliding Sync", () => {
}); });
// Regression test for https://github.com/vector-im/element-web/issues/21462 // Regression test for https://github.com/vector-im/element-web/issues/21462
it("should not cancel replies when permalinks are clicked ", () => { it("should not cancel replies when permalinks are clicked", () => {
cy.get<string>("@roomId").then((roomId) => { cy.get<string>("@roomId").then((roomId) => {
// we require a first message as you cannot click the permalink text with the avatar in the way // we require a first message as you cannot click the permalink text with the avatar in the way
return cy return cy

View file

@ -24,7 +24,7 @@ import Timeoutable = Cypress.Timeoutable;
import Withinable = Cypress.Withinable; import Withinable = Cypress.Withinable;
import Shadow = Cypress.Shadow; import Shadow = Cypress.Shadow;
export enum Filter { enum Filter {
People = "people", People = "people",
PublicRooms = "public_rooms", PublicRooms = "public_rooms",
} }
@ -297,27 +297,28 @@ describe("Spotlight", () => {
// TODO: We currently cant test finding rooms on other homeservers/other protocols // TODO: We currently cant test finding rooms on other homeservers/other protocols
// We obviously dont have federation or bridges in cypress tests // We obviously dont have federation or bridges in cypress tests
/* it.skip("should find unknown public rooms on other homeservers", () => {
const room3Name = "Matrix HQ"; cy.openSpotlightDialog()
const room3Id = "#matrix:matrix.org"; .within(() => {
it("should find unknown public rooms on other homeservers", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.PublicRooms); cy.spotlightFilter(Filter.PublicRooms);
cy.spotlightSearch().clear().type(room3Name); cy.spotlightSearch().clear().type(room3Name);
cy.get("[aria-haspopup=true][role=button]").click(); cy.get("[aria-haspopup=true][role=button]").click();
}).then(() => { })
.then(() => {
cy.contains(".mx_GenericDropdownMenu_Option--header", "matrix.org") cy.contains(".mx_GenericDropdownMenu_Option--header", "matrix.org")
.next("[role=menuitemradio]") .next("[role=menuitemradio]")
.click(); .click();
cy.wait(3_600_000); cy.wait(3_600_000);
}).then(() => cy.spotlightDialog().within(() => { })
.then(() =>
cy.spotlightDialog().within(() => {
cy.spotlightResults().should("have.length", 1); cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", room3Name); cy.spotlightResults().eq(0).should("contain", room3Name);
cy.spotlightResults().eq(0).should("contain", room3Id); cy.spotlightResults().eq(0).should("contain", room3Id);
})); }),
);
}); });
*/
it("should find known people", () => { it("should find known people", () => {
cy.openSpotlightDialog() cy.openSpotlightDialog()
.within(() => { .within(() => {

View file

@ -194,6 +194,7 @@
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"eslint-plugin-deprecate": "^0.7.0", "eslint-plugin-deprecate": "^0.7.0",
"eslint-plugin-import": "^2.25.4", "eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-matrix-org": "1.0.0", "eslint-plugin-matrix-org": "1.0.0",
"eslint-plugin-react": "^7.28.0", "eslint-plugin-react": "^7.28.0",

View file

@ -327,6 +327,6 @@ describe("uploadFile", () => {
const prom = uploadFile(client, "!roomId:server", file); const prom = uploadFile(client, "!roomId:server", file);
mocked(client.uploadContent).mock.calls[0][1]!.abortController!.abort(); mocked(client.uploadContent).mock.calls[0][1]!.abortController!.abort();
deferred.resolve({ content_uri: "mxc://foo/bar" }); deferred.resolve({ content_uri: "mxc://foo/bar" });
await expect(prom).rejects.toThrowError(UploadCanceledError); await expect(prom).rejects.toThrow(UploadCanceledError);
}); });
}); });

View file

@ -38,7 +38,7 @@ function createFailedDecryptionEvent() {
} }
describe("DecryptionFailureTracker", function () { describe("DecryptionFailureTracker", function () {
it("tracks a failed decryption for a visible event", function (done) { it("tracks a failed decryption for a visible event", function () {
const failedDecryptionEvent = createFailedDecryptionEvent(); const failedDecryptionEvent = createFailedDecryptionEvent();
let count = 0; let count = 0;
@ -59,11 +59,9 @@ describe("DecryptionFailureTracker", function () {
tracker.trackFailures(); tracker.trackFailures();
expect(count).not.toBe(0, "should track a failure for an event that failed decryption"); expect(count).not.toBe(0, "should track a failure for an event that failed decryption");
done();
}); });
it("tracks a failed decryption with expected raw error for a visible event", function (done) { it("tracks a failed decryption with expected raw error for a visible event", function () {
const failedDecryptionEvent = createFailedDecryptionEvent(); const failedDecryptionEvent = createFailedDecryptionEvent();
let count = 0; let count = 0;
@ -89,11 +87,9 @@ describe("DecryptionFailureTracker", function () {
expect(count).not.toBe(0, "should track a failure for an event that failed decryption"); expect(count).not.toBe(0, "should track a failure for an event that failed decryption");
expect(reportedRawCode).toBe("INBOUND_SESSION_MISMATCH_ROOM_ID", "Should add the rawCode to the event context"); expect(reportedRawCode).toBe("INBOUND_SESSION_MISMATCH_ROOM_ID", "Should add the rawCode to the event context");
done();
}); });
it("tracks a failed decryption for an event that becomes visible later", function (done) { it("tracks a failed decryption for an event that becomes visible later", function () {
const failedDecryptionEvent = createFailedDecryptionEvent(); const failedDecryptionEvent = createFailedDecryptionEvent();
let count = 0; let count = 0;
@ -114,11 +110,9 @@ describe("DecryptionFailureTracker", function () {
tracker.trackFailures(); tracker.trackFailures();
expect(count).not.toBe(0, "should track a failure for an event that failed decryption"); expect(count).not.toBe(0, "should track a failure for an event that failed decryption");
done();
}); });
it("does not track a failed decryption for an event that never becomes visible", function (done) { it("does not track a failed decryption for an event that never becomes visible", function () {
const failedDecryptionEvent = createFailedDecryptionEvent(); const failedDecryptionEvent = createFailedDecryptionEvent();
let count = 0; let count = 0;
@ -137,11 +131,9 @@ describe("DecryptionFailureTracker", function () {
tracker.trackFailures(); tracker.trackFailures();
expect(count).toBe(0, "should not track a failure for an event that never became visible"); expect(count).toBe(0, "should not track a failure for an event that never became visible");
done();
}); });
it("does not track a failed decryption where the event is subsequently successfully decrypted", (done) => { it("does not track a failed decryption where the event is subsequently successfully decrypted", () => {
const decryptedEvent = createFailedDecryptionEvent(); const decryptedEvent = createFailedDecryptionEvent();
const tracker = new DecryptionFailureTracker( const tracker = new DecryptionFailureTracker(
(total) => { (total) => {
@ -164,13 +156,12 @@ describe("DecryptionFailureTracker", function () {
// Immediately track the newest failures // Immediately track the newest failures
tracker.trackFailures(); tracker.trackFailures();
done();
}); });
it( it(
"does not track a failed decryption where the event is subsequently successfully decrypted " + "does not track a failed decryption where the event is subsequently successfully decrypted " +
"and later becomes visible", "and later becomes visible",
(done) => { () => {
const decryptedEvent = createFailedDecryptionEvent(); const decryptedEvent = createFailedDecryptionEvent();
const tracker = new DecryptionFailureTracker( const tracker = new DecryptionFailureTracker(
(total) => { (total) => {
@ -193,11 +184,10 @@ describe("DecryptionFailureTracker", function () {
// Immediately track the newest failures // Immediately track the newest failures
tracker.trackFailures(); tracker.trackFailures();
done();
}, },
); );
it("only tracks a single failure per event, despite multiple failed decryptions for multiple events", (done) => { it("only tracks a single failure per event, despite multiple failed decryptions for multiple events", () => {
const decryptedEvent = createFailedDecryptionEvent(); const decryptedEvent = createFailedDecryptionEvent();
const decryptedEvent2 = createFailedDecryptionEvent(); const decryptedEvent2 = createFailedDecryptionEvent();
@ -231,11 +221,9 @@ describe("DecryptionFailureTracker", function () {
tracker.trackFailures(); tracker.trackFailures();
expect(count).toBe(2, count + " failures tracked, should only track a single failure per event"); expect(count).toBe(2, count + " failures tracked, should only track a single failure per event");
done();
}); });
it("should not track a failure for an event that was tracked previously", (done) => { it("should not track a failure for an event that was tracked previously", () => {
const decryptedEvent = createFailedDecryptionEvent(); const decryptedEvent = createFailedDecryptionEvent();
let count = 0; let count = 0;
@ -261,11 +249,9 @@ describe("DecryptionFailureTracker", function () {
tracker.trackFailures(); tracker.trackFailures();
expect(count).toBe(1, "should only track a single failure per event"); expect(count).toBe(1, "should only track a single failure per event");
done();
}); });
xit("should not track a failure for an event that was tracked in a previous session", (done) => { it.skip("should not track a failure for an event that was tracked in a previous session", () => {
// This test uses localStorage, clear it beforehand // This test uses localStorage, clear it beforehand
localStorage.clear(); localStorage.clear();
@ -304,8 +290,6 @@ describe("DecryptionFailureTracker", function () {
secondTracker.trackFailures(); secondTracker.trackFailures();
expect(count).toBe(1, count + " failures tracked, should only track a single failure per event"); expect(count).toBe(1, count + " failures tracked, should only track a single failure per event");
done();
}); });
it("should count different error codes separately for multiple failures with different error codes", () => { it("should count different error codes separately for multiple failures with different error codes", () => {

View file

@ -302,7 +302,7 @@ describe("Notifier", () => {
); );
}); });
it("should display the expected notification for a broadcast chunk with sequence = 1", () => { it("should display the expected notification for a broadcast chunk with sequence = 2", () => {
const audioEvent = mkAudioEvent({ sequence: 2 }); const audioEvent = mkAudioEvent({ sequence: 2 });
Notifier.displayPopupNotification(audioEvent, testRoom); Notifier.displayPopupNotification(audioEvent, testRoom);
expect(MockPlatform.displayNotification).not.toHaveBeenCalled(); expect(MockPlatform.displayNotification).not.toHaveBeenCalled();

View file

@ -35,7 +35,7 @@ const getFakePosthog = (): PostHog =>
register: jest.fn(), register: jest.fn(),
} as unknown as PostHog); } as unknown as PostHog);
export interface ITestEvent extends IPosthogEvent { interface ITestEvent extends IPosthogEvent {
eventName: "JestTestEvents"; eventName: "JestTestEvents";
foo?: string; foo?: string;
} }

View file

@ -218,7 +218,7 @@ describe("RoomNotifs test", () => {
expect(getUnreadNotificationCount(room, NotificationCountType.Highlight, THREAD_ID)).toBe(0); expect(getUnreadNotificationCount(room, NotificationCountType.Highlight, THREAD_ID)).toBe(0);
}); });
it("counts notifications type", () => { it("counts thread notifications type", () => {
room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Total, 2); room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Total, 2);
room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Highlight, 1); room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Highlight, 1);

View file

@ -58,7 +58,7 @@ describe("ScalarAuthClient", function () {
await sac.connect(); await sac.connect();
expect(sac.exchangeForScalarToken).toBeCalledWith(tokenObject); expect(sac.exchangeForScalarToken).toHaveBeenCalledWith(tokenObject);
expect(sac.hasCredentials).toBeTruthy(); expect(sac.hasCredentials).toBeTruthy();
// @ts-ignore private property // @ts-ignore private property
expect(sac.scalarToken).toEqual("wokentoken"); expect(sac.scalarToken).toEqual("wokentoken");

View file

@ -46,7 +46,7 @@ describe("SlidingSyncManager", () => {
mocked(slidingSync.getRoomSubscriptions).mockReturnValue(subs); mocked(slidingSync.getRoomSubscriptions).mockReturnValue(subs);
mocked(slidingSync.modifyRoomSubscriptions).mockResolvedValue("yep"); mocked(slidingSync.modifyRoomSubscriptions).mockResolvedValue("yep");
await manager.setRoomVisible(roomId, true); await manager.setRoomVisible(roomId, true);
expect(slidingSync.modifyRoomSubscriptions).toBeCalledWith(new Set<string>([roomId])); expect(slidingSync.modifyRoomSubscriptions).toHaveBeenCalledWith(new Set<string>([roomId]));
}); });
it("adds a custom subscription for a lazy-loadable room", async () => { it("adds a custom subscription for a lazy-loadable room", async () => {
const roomId = "!lazy:id"; const roomId = "!lazy:id";
@ -72,9 +72,9 @@ describe("SlidingSyncManager", () => {
mocked(slidingSync.getRoomSubscriptions).mockReturnValue(subs); mocked(slidingSync.getRoomSubscriptions).mockReturnValue(subs);
mocked(slidingSync.modifyRoomSubscriptions).mockResolvedValue("yep"); mocked(slidingSync.modifyRoomSubscriptions).mockResolvedValue("yep");
await manager.setRoomVisible(roomId, true); await manager.setRoomVisible(roomId, true);
expect(slidingSync.modifyRoomSubscriptions).toBeCalledWith(new Set<string>([roomId])); expect(slidingSync.modifyRoomSubscriptions).toHaveBeenCalledWith(new Set<string>([roomId]));
// we aren't prescriptive about what the sub name is. // we aren't prescriptive about what the sub name is.
expect(slidingSync.useCustomSubscription).toBeCalledWith(roomId, expect.anything()); expect(slidingSync.useCustomSubscription).toHaveBeenCalledWith(roomId, expect.anything());
}); });
}); });
@ -86,7 +86,7 @@ describe("SlidingSyncManager", () => {
await manager.ensureListRegistered(listKey, { await manager.ensureListRegistered(listKey, {
sort: ["by_recency"], sort: ["by_recency"],
}); });
expect(slidingSync.setList).toBeCalledWith( expect(slidingSync.setList).toHaveBeenCalledWith(
listKey, listKey,
expect.objectContaining({ expect.objectContaining({
sort: ["by_recency"], sort: ["by_recency"],
@ -103,7 +103,7 @@ describe("SlidingSyncManager", () => {
await manager.ensureListRegistered(listKey, { await manager.ensureListRegistered(listKey, {
sort: ["by_recency"], sort: ["by_recency"],
}); });
expect(slidingSync.setList).toBeCalledWith( expect(slidingSync.setList).toHaveBeenCalledWith(
listKey, listKey,
expect.objectContaining({ expect.objectContaining({
sort: ["by_recency"], sort: ["by_recency"],
@ -121,8 +121,8 @@ describe("SlidingSyncManager", () => {
await manager.ensureListRegistered(listKey, { await manager.ensureListRegistered(listKey, {
ranges: [[0, 52]], ranges: [[0, 52]],
}); });
expect(slidingSync.setList).not.toBeCalled(); expect(slidingSync.setList).not.toHaveBeenCalled();
expect(slidingSync.setListRanges).toBeCalledWith(listKey, [[0, 52]]); expect(slidingSync.setListRanges).toHaveBeenCalledWith(listKey, [[0, 52]]);
}); });
it("no-ops for idential changes", async () => { it("no-ops for idential changes", async () => {
@ -136,8 +136,8 @@ describe("SlidingSyncManager", () => {
ranges: [[0, 42]], ranges: [[0, 42]],
sort: ["by_recency"], sort: ["by_recency"],
}); });
expect(slidingSync.setList).not.toBeCalled(); expect(slidingSync.setList).not.toHaveBeenCalled();
expect(slidingSync.setListRanges).not.toBeCalled(); expect(slidingSync.setListRanges).not.toHaveBeenCalled();
}); });
}); });
@ -163,12 +163,12 @@ describe("SlidingSyncManager", () => {
[50, 59], [50, 59],
[60, 69], [60, 69],
]; ];
expect(slidingSync.getListData).toBeCalledTimes(wantWindows.length); expect(slidingSync.getListData).toHaveBeenCalledTimes(wantWindows.length);
expect(slidingSync.setList).toBeCalledTimes(1); expect(slidingSync.setList).toHaveBeenCalledTimes(1);
expect(slidingSync.setListRanges).toBeCalledTimes(wantWindows.length - 1); expect(slidingSync.setListRanges).toHaveBeenCalledTimes(wantWindows.length - 1);
wantWindows.forEach((range, i) => { wantWindows.forEach((range, i) => {
if (i === 0) { if (i === 0) {
expect(slidingSync.setList).toBeCalledWith( expect(slidingSync.setList).toHaveBeenCalledWith(
SlidingSyncManager.ListSearch, SlidingSyncManager.ListSearch,
expect.objectContaining({ expect.objectContaining({
ranges: [[0, batchSize - 1], range], ranges: [[0, batchSize - 1], range],
@ -176,7 +176,7 @@ describe("SlidingSyncManager", () => {
); );
return; return;
} }
expect(slidingSync.setListRanges).toBeCalledWith(SlidingSyncManager.ListSearch, [ expect(slidingSync.setListRanges).toHaveBeenCalledWith(SlidingSyncManager.ListSearch, [
[0, batchSize - 1], [0, batchSize - 1],
range, range,
]); ]);
@ -193,9 +193,9 @@ describe("SlidingSyncManager", () => {
}; };
}); });
await manager.startSpidering(batchSize, gapMs); await manager.startSpidering(batchSize, gapMs);
expect(slidingSync.getListData).toBeCalledTimes(1); expect(slidingSync.getListData).toHaveBeenCalledTimes(1);
expect(slidingSync.setList).toBeCalledTimes(1); expect(slidingSync.setList).toHaveBeenCalledTimes(1);
expect(slidingSync.setList).toBeCalledWith( expect(slidingSync.setList).toHaveBeenCalledWith(
SlidingSyncManager.ListSearch, SlidingSyncManager.ListSearch,
expect.objectContaining({ expect.objectContaining({
ranges: [ ranges: [
@ -216,9 +216,9 @@ describe("SlidingSyncManager", () => {
}; };
}); });
await manager.startSpidering(batchSize, gapMs); await manager.startSpidering(batchSize, gapMs);
expect(slidingSync.getListData).toBeCalledTimes(1); expect(slidingSync.getListData).toHaveBeenCalledTimes(1);
expect(slidingSync.setList).toBeCalledTimes(1); expect(slidingSync.setList).toHaveBeenCalledTimes(1);
expect(slidingSync.setList).toBeCalledWith( expect(slidingSync.setList).toHaveBeenCalledWith(
SlidingSyncManager.ListSearch, SlidingSyncManager.ListSearch,
expect.objectContaining({ expect.objectContaining({
ranges: [ ranges: [

View file

@ -68,7 +68,7 @@ describe("Terms", function () {
const interactionCallback = jest.fn().mockResolvedValue([]); const interactionCallback = jest.fn().mockResolvedValue([]);
await startTermsFlow([IM_SERVICE_ONE], interactionCallback); await startTermsFlow([IM_SERVICE_ONE], interactionCallback);
expect(interactionCallback).toBeCalledWith( expect(interactionCallback).toHaveBeenCalledWith(
[ [
{ {
service: IM_SERVICE_ONE, service: IM_SERVICE_ONE,
@ -100,7 +100,7 @@ describe("Terms", function () {
await startTermsFlow([IM_SERVICE_ONE], interactionCallback); await startTermsFlow([IM_SERVICE_ONE], interactionCallback);
expect(interactionCallback).not.toHaveBeenCalled(); expect(interactionCallback).not.toHaveBeenCalled();
expect(mockClient.agreeToTerms).toBeCalledWith(SERVICE_TYPES.IM, "https://imone.test", "a token token", [ expect(mockClient.agreeToTerms).toHaveBeenCalledWith(SERVICE_TYPES.IM, "https://imone.test", "a token token", [
"http://example.com/one", "http://example.com/one",
]); ]);
}); });
@ -124,7 +124,7 @@ describe("Terms", function () {
const interactionCallback = jest.fn().mockResolvedValue(["http://example.com/one", "http://example.com/two"]); const interactionCallback = jest.fn().mockResolvedValue(["http://example.com/one", "http://example.com/two"]);
await startTermsFlow([IM_SERVICE_ONE], interactionCallback); await startTermsFlow([IM_SERVICE_ONE], interactionCallback);
expect(interactionCallback).toBeCalledWith( expect(interactionCallback).toHaveBeenCalledWith(
[ [
{ {
service: IM_SERVICE_ONE, service: IM_SERVICE_ONE,
@ -135,7 +135,7 @@ describe("Terms", function () {
], ],
["http://example.com/one"], ["http://example.com/one"],
); );
expect(mockClient.agreeToTerms).toBeCalledWith(SERVICE_TYPES.IM, "https://imone.test", "a token token", [ expect(mockClient.agreeToTerms).toHaveBeenCalledWith(SERVICE_TYPES.IM, "https://imone.test", "a token token", [
"http://example.com/one", "http://example.com/one",
"http://example.com/two", "http://example.com/two",
]); ]);
@ -170,7 +170,7 @@ describe("Terms", function () {
const interactionCallback = jest.fn().mockResolvedValue(["http://example.com/one", "http://example.com/two"]); const interactionCallback = jest.fn().mockResolvedValue(["http://example.com/one", "http://example.com/two"]);
await startTermsFlow([IM_SERVICE_ONE, IM_SERVICE_TWO], interactionCallback); await startTermsFlow([IM_SERVICE_ONE, IM_SERVICE_TWO], interactionCallback);
expect(interactionCallback).toBeCalledWith( expect(interactionCallback).toHaveBeenCalledWith(
[ [
{ {
service: IM_SERVICE_TWO, service: IM_SERVICE_TWO,
@ -181,10 +181,10 @@ describe("Terms", function () {
], ],
["http://example.com/one"], ["http://example.com/one"],
); );
expect(mockClient.agreeToTerms).toBeCalledWith(SERVICE_TYPES.IM, "https://imone.test", "a token token", [ expect(mockClient.agreeToTerms).toHaveBeenCalledWith(SERVICE_TYPES.IM, "https://imone.test", "a token token", [
"http://example.com/one", "http://example.com/one",
]); ]);
expect(mockClient.agreeToTerms).toBeCalledWith(SERVICE_TYPES.IM, "https://imtwo.test", "a token token", [ expect(mockClient.agreeToTerms).toHaveBeenCalledWith(SERVICE_TYPES.IM, "https://imtwo.test", "a token token", [
"http://example.com/two", "http://example.com/two",
]); ]);
}); });

View file

@ -471,7 +471,7 @@ describe("TextForEvent", () => {
expect(textForEvent(callEvent)).toEqual("Video call started in Test room."); expect(textForEvent(callEvent)).toEqual("Video call started in Test room.");
}); });
it("returns correct message for call event when supported", () => { it("returns correct message for call event when not supported", () => {
mocked(mockClient).supportsVoip.mockReturnValue(false); mocked(mockClient).supportsVoip.mockReturnValue(false);
expect(textForEvent(callEvent)).toEqual( expect(textForEvent(callEvent)).toEqual(

View file

@ -59,7 +59,7 @@ describe("KeyboardShortcutUtils", () => {
}); });
describe("correctly filters shortcuts", () => { describe("correctly filters shortcuts", () => {
it("when on web and not on macOS ", async () => { it("when on web and not on macOS", async () => {
mockKeyboardShortcuts({ mockKeyboardShortcuts({
KEYBOARD_SHORTCUTS: { KEYBOARD_SHORTCUTS: {
Keybind1: {}, Keybind1: {},

View file

@ -46,7 +46,6 @@ const roomId = "!roomId:server_name";
describe("MessagePanel", function () { describe("MessagePanel", function () {
let clock: FakeTimers.InstalledClock; let clock: FakeTimers.InstalledClock;
const realSetTimeout = window.setTimeout;
const events = mkEvents(); const events = mkEvents();
const userId = "@me:here"; const userId = "@me:here";
const client = getMockClientWithEventEmitter({ const client = getMockClientWithEventEmitter({
@ -404,7 +403,7 @@ describe("MessagePanel", function () {
expect(isReadMarkerVisible(rm)).toBeFalsy(); expect(isReadMarkerVisible(rm)).toBeFalsy();
}); });
it("shows a ghost read-marker when the read-marker moves", function (done) { it("shows a ghost read-marker when the read-marker moves", function () {
// fake the clock so that we can test the velocity animation. // fake the clock so that we can test the velocity animation.
clock = FakeTimers.install(); clock = FakeTimers.install();
@ -446,19 +445,9 @@ describe("MessagePanel", function () {
// the second should be the real thing // the second should be the real thing
expect(readMarkers[1].previousSibling).toEqual(tiles[6]); expect(readMarkers[1].previousSibling).toEqual(tiles[6]);
// advance the clock, and then let the browser run an animation frame, // advance the clock, and then let the browser run an animation frame to let the animation start
// to let the animation start
clock.tick(1500); clock.tick(1500);
realSetTimeout(() => {
// then advance it again to let it complete
clock.tick(1000);
realSetTimeout(() => {
// the ghost should now have finished
expect(hr.style.opacity).toEqual("0"); expect(hr.style.opacity).toEqual("0");
done();
}, 100);
}, 100);
}); });
it("should collapse creation events", function () { it("should collapse creation events", function () {

View file

@ -147,7 +147,7 @@ describe("ThreadView", () => {
); );
}); });
it("sends a message with the correct fallback", async () => { it("sends a thread message with the correct fallback", async () => {
const { container } = await getComponent(); const { container } = await getComponent();
const { rootEvent: rootEvent2 } = mkThread({ const { rootEvent: rootEvent2 } = mkThread({

View file

@ -84,7 +84,7 @@ describe("InteractiveAuthComponent", function () {
await flushPromises(); await flushPromises();
expect(makeRequest).toHaveBeenCalledTimes(1); expect(makeRequest).toHaveBeenCalledTimes(1);
expect(makeRequest).toBeCalledWith( expect(makeRequest).toHaveBeenCalledWith(
expect.objectContaining({ expect.objectContaining({
session: "sess", session: "sess",
type: "m.login.registration_token", type: "m.login.registration_token",
@ -92,8 +92,8 @@ describe("InteractiveAuthComponent", function () {
}), }),
); );
expect(onAuthFinished).toBeCalledTimes(1); expect(onAuthFinished).toHaveBeenCalledTimes(1);
expect(onAuthFinished).toBeCalledWith( expect(onAuthFinished).toHaveBeenCalledWith(
true, true,
{ a: 1 }, { a: 1 },
{ clientSecret: "t35tcl1Ent5ECr3T", emailSid: undefined }, { clientSecret: "t35tcl1Ent5ECr3T", emailSid: undefined },

View file

@ -79,7 +79,7 @@ describe("InteractiveAuthDialog", function () {
await flushPromises(); await flushPromises();
expect(makeRequest).toHaveBeenCalledTimes(1); expect(makeRequest).toHaveBeenCalledTimes(1);
expect(makeRequest).toBeCalledWith( expect(makeRequest).toHaveBeenCalledWith(
expect.objectContaining({ expect.objectContaining({
session: "sess", session: "sess",
type: "m.login.password", type: "m.login.password",
@ -91,7 +91,7 @@ describe("InteractiveAuthDialog", function () {
}), }),
); );
expect(onFinished).toBeCalledTimes(1); expect(onFinished).toHaveBeenCalledTimes(1);
expect(onFinished).toBeCalledWith(true, { a: 1 }); expect(onFinished).toHaveBeenCalledWith(true, { a: 1 });
}); });
}); });

View file

@ -69,7 +69,7 @@ describe("<MessageEditHistory />", () => {
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();
}); });
it("should support events with ", async () => { it("should support events with", async () => {
mockEdits( mockEdits(
{ msg: "My Great Massage", ts: undefined }, { msg: "My Great Massage", ts: undefined },
{ msg: "My Great Massage?", ts: undefined }, { msg: "My Great Massage?", ts: undefined },

View file

@ -431,30 +431,5 @@ describe("<PollHistoryDialog />", () => {
`https://matrix.to/#/!room:domain.org/${pollEnd3.getId()!}`, `https://matrix.to/#/!room:domain.org/${pollEnd3.getId()!}`,
); );
}); });
it("navigates back to poll list from detail view on header click", async () => {
await setupRoomWithPollEvents([pollStart1, pollStart2, pollStart3], [], [pollEnd3], mockClient, room);
const { getByText, queryByText, getByTestId, container } = getComponent();
await flushPromises();
fireEvent.click(getByText("Question?"));
// detail view
expect(getByText("Question?")).toBeInTheDocument();
// header not shown
expect(queryByText("Polls history")).not.toBeInTheDocument();
expect(getByText("Active polls")).toMatchSnapshot();
fireEvent.click(getByText("Active polls"));
// main list header displayed again
expect(getByText("Polls history")).toBeInTheDocument();
// active filter still active
expect(getByTestId("filter-tab-PollHistoryDialog_filter-ACTIVE").firstElementChild).toBeChecked();
// list displayed
expect(container.getElementsByClassName("mx_PollHistoryList_list").length).toBeTruthy();
});
}); });
}); });

View file

@ -29,19 +29,6 @@ exports[`<PollHistoryDialog /> Poll detail navigates back to poll list from deta
</div> </div>
`; `;
exports[`<PollHistoryDialog /> Poll detail navigates back to poll list from detail view on header click 2`] = `
<div
class="mx_AccessibleButton mx_PollDetailHeader mx_AccessibleButton_hasKind mx_AccessibleButton_kind_content_inline"
role="button"
tabindex="0"
>
<div
class="mx_PollDetailHeader_icon"
/>
Active polls
</div>
`;
exports[`<PollHistoryDialog /> renders a list of active polls when there are polls in the room 1`] = ` exports[`<PollHistoryDialog /> renders a list of active polls when there are polls in the room 1`] = `
<div> <div>
<div <div

View file

@ -156,7 +156,7 @@ describe("EventListSummary", function () {
expect(children[0]).toHaveTextContent("Expanded membership"); expect(children[0]).toHaveTextContent("Expanded membership");
}); });
it("renders expanded events if there are less than props.threshold", function () { it("renders expanded events if there are less than props.threshold for join and leave", function () {
const events = generateEvents([ const events = generateEvents([
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" }, { userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" }, { userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },

View file

@ -252,15 +252,6 @@ describe("<MBeaconBody />", () => {
expect(modalSpy).toHaveBeenCalled(); expect(modalSpy).toHaveBeenCalled();
}); });
it("does nothing on click when a beacon has no location", () => {
makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
const component = getComponent({ mxEvent: aliceBeaconInfo });
fireEvent.click(component.container.querySelector(".mx_MBeaconBody_map")!);
expect(modalSpy).not.toHaveBeenCalled();
});
it("updates latest location", () => { it("updates latest location", () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient }); const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
getComponent({ mxEvent: aliceBeaconInfo }); getComponent({ mxEvent: aliceBeaconInfo });

View file

@ -958,7 +958,7 @@ function endedVotesCount(renderResult: RenderResult, value: string): string {
return votesCount(renderResult, value); return votesCount(renderResult, value);
} }
export function newPollStart(answers?: PollAnswer[], question?: string, disclosed = true): PollStartEventContent { function newPollStart(answers?: PollAnswer[], question?: string, disclosed = true): PollStartEventContent {
if (!answers) { if (!answers) {
answers = [ answers = [
{ id: "pizza", [M_TEXT.name]: "Pizza" }, { id: "pizza", [M_TEXT.name]: "Pizza" },
@ -1033,7 +1033,7 @@ function expectedResponseEventCall(answer: string) {
return [roomId, eventType, content]; return [roomId, eventType, content];
} }
export function newPollEndEvent(sender = "@me:example.com", ts = 0): MatrixEvent { function newPollEndEvent(sender = "@me:example.com", ts = 0): MatrixEvent {
return makePollEndEvent("$mypoll", "#myroom:example.com", sender, ts); return makePollEndEvent("$mypoll", "#myroom:example.com", sender, ts);
} }

View file

@ -195,7 +195,7 @@ describe("<MessageActionBar />", () => {
// because beforeRedaction event is fired... before redaction // because beforeRedaction event is fired... before redaction
// event is unchanged at point when this component updates // event is unchanged at point when this component updates
// TODO file bug // TODO file bug
xit("updates component on before redaction event", () => { it.skip("updates component on before redaction event", () => {
const event = new MatrixEvent({ const event = new MatrixEvent({
type: EventType.RoomMessage, type: EventType.RoomMessage,
sender: userId, sender: userId,

View file

@ -420,7 +420,7 @@ describe("<UserOptionsSection />", () => {
expect(screen.getByRole("button", { name: /share link to user/i })).toBeInTheDocument(); expect(screen.getByRole("button", { name: /share link to user/i })).toBeInTheDocument();
}); });
it("does not show ignore or direct message buttons when member userId matches client userId ", () => { it("does not show ignore or direct message buttons when member userId matches client userId", () => {
mockClient.getUserId.mockReturnValueOnce(member.userId); mockClient.getUserId.mockReturnValueOnce(member.userId);
renderComponent(); renderComponent();
@ -428,7 +428,7 @@ describe("<UserOptionsSection />", () => {
expect(screen.queryByRole("button", { name: /message/i })).not.toBeInTheDocument(); expect(screen.queryByRole("button", { name: /message/i })).not.toBeInTheDocument();
}); });
it("shows ignore, direct message and mention buttons when member userId does not match client userId ", () => { it("shows ignore, direct message and mention buttons when member userId does not match client userId", () => {
// call to client.getUserId returns undefined, which will not match member.userId // call to client.getUserId returns undefined, which will not match member.userId
renderComponent(); renderComponent();

View file

@ -137,13 +137,11 @@ describe("MemberList", () => {
) as unknown as Component; ) as unknown as Component;
}); });
afterEach((done) => { afterEach(() => {
if (parentDiv) { if (parentDiv) {
ReactDOM.unmountComponentAtNode(parentDiv); ReactDOM.unmountComponentAtNode(parentDiv);
parentDiv.remove(); parentDiv.remove();
} }
done();
}); });
function expectOrderedByPresenceAndPowerLevel(memberTiles: MemberTile[], isPresenceEnabled: boolean) { function expectOrderedByPresenceAndPowerLevel(memberTiles: MemberTile[], isPresenceEnabled: boolean) {

View file

@ -177,12 +177,12 @@ describe("EditWysiwygComposer", () => {
screen.getByText("Cancel").click(); screen.getByText("Cancel").click();
// Then // Then
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: Action.EditEvent, action: Action.EditEvent,
event: null, event: null,
timelineRenderingType: defaultRoomContext.timelineRenderingType, timelineRenderingType: defaultRoomContext.timelineRenderingType,
}); });
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: Action.FocusSendMessageComposer, action: Action.FocusSendMessageComposer,
context: defaultRoomContext.timelineRenderingType, context: defaultRoomContext.timelineRenderingType,
}); });
@ -215,10 +215,10 @@ describe("EditWysiwygComposer", () => {
"msgtype": "m.text", "msgtype": "m.text",
}; };
await waitFor(() => await waitFor(() =>
expect(mockClient.sendMessage).toBeCalledWith(mockEvent.getRoomId(), null, expectedContent), expect(mockClient.sendMessage).toHaveBeenCalledWith(mockEvent.getRoomId(), null, expectedContent),
); );
expect(spyDispatcher).toBeCalledWith({ action: "message_sent" }); expect(spyDispatcher).toHaveBeenCalledWith({ action: "message_sent" });
}); });
}); });

View file

@ -84,7 +84,7 @@ describe("LinkModal", () => {
// Then // Then
await waitFor(() => { await waitFor(() => {
expect(selectionSpy).toHaveBeenCalledWith(defaultValue); expect(selectionSpy).toHaveBeenCalledWith(defaultValue);
expect(onFinished).toBeCalledTimes(1); expect(onFinished).toHaveBeenCalledTimes(1);
}); });
// Then // Then
@ -127,7 +127,7 @@ describe("LinkModal", () => {
// Then // Then
await waitFor(() => { await waitFor(() => {
expect(selectionSpy).toHaveBeenCalledWith(defaultValue); expect(selectionSpy).toHaveBeenCalledWith(defaultValue);
expect(onFinished).toBeCalledTimes(1); expect(onFinished).toHaveBeenCalledTimes(1);
}); });
// Then // Then
@ -142,7 +142,7 @@ describe("LinkModal", () => {
// Then // Then
expect(formattingFunctions.removeLinks).toHaveBeenCalledTimes(1); expect(formattingFunctions.removeLinks).toHaveBeenCalledTimes(1);
expect(onFinished).toBeCalledTimes(1); expect(onFinished).toHaveBeenCalledTimes(1);
}); });
it("Should display the link in editing", async () => { it("Should display the link in editing", async () => {

View file

@ -74,7 +74,7 @@ describe("PlainTextComposer", () => {
await userEvent.type(screen.getByRole("textbox"), content); await userEvent.type(screen.getByRole("textbox"), content);
// Then // Then
expect(onChange).toBeCalledWith(content); expect(onChange).toHaveBeenCalledWith(content);
}); });
it("Should call onSend when Enter is pressed when ctrlEnterToSend is false", async () => { it("Should call onSend when Enter is pressed when ctrlEnterToSend is false", async () => {
@ -84,7 +84,7 @@ describe("PlainTextComposer", () => {
await userEvent.type(screen.getByRole("textbox"), "{enter}"); await userEvent.type(screen.getByRole("textbox"), "{enter}");
// Then it sends a message // Then it sends a message
expect(onSend).toBeCalledTimes(1); expect(onSend).toHaveBeenCalledTimes(1);
}); });
it("Should not call onSend when Enter is pressed when ctrlEnterToSend is true", async () => { it("Should not call onSend when Enter is pressed when ctrlEnterToSend is true", async () => {
@ -95,7 +95,7 @@ describe("PlainTextComposer", () => {
await userEvent.type(screen.getByRole("textbox"), "{enter}"); await userEvent.type(screen.getByRole("textbox"), "{enter}");
// Then it does not send a message // Then it does not send a message
expect(onSend).toBeCalledTimes(0); expect(onSend).toHaveBeenCalledTimes(0);
}); });
it("Should only call onSend when ctrl+enter is pressed when ctrlEnterToSend is true on windows", async () => { it("Should only call onSend when ctrl+enter is pressed when ctrlEnterToSend is true on windows", async () => {
@ -109,15 +109,15 @@ describe("PlainTextComposer", () => {
// Then it does NOT send a message on enter // Then it does NOT send a message on enter
await userEvent.type(textBox, "{enter}"); await userEvent.type(textBox, "{enter}");
expect(onSend).toBeCalledTimes(0); expect(onSend).toHaveBeenCalledTimes(0);
// Then it does NOT send a message on windows+enter // Then it does NOT send a message on windows+enter
await userEvent.type(textBox, "{meta>}{enter}{meta/}"); await userEvent.type(textBox, "{meta>}{enter}{meta/}");
expect(onSend).toBeCalledTimes(0); expect(onSend).toHaveBeenCalledTimes(0);
// Then it does send a message on ctrl+enter // Then it does send a message on ctrl+enter
await userEvent.type(textBox, "{control>}{enter}{control/}"); await userEvent.type(textBox, "{control>}{enter}{control/}");
expect(onSend).toBeCalledTimes(1); expect(onSend).toHaveBeenCalledTimes(1);
}); });
it("Should only call onSend when cmd+enter is pressed when ctrlEnterToSend is true on mac", async () => { it("Should only call onSend when cmd+enter is pressed when ctrlEnterToSend is true on mac", async () => {
@ -132,15 +132,15 @@ describe("PlainTextComposer", () => {
// Then it does NOT send a message on enter // Then it does NOT send a message on enter
await userEvent.type(textBox, "{enter}"); await userEvent.type(textBox, "{enter}");
expect(onSend).toBeCalledTimes(0); expect(onSend).toHaveBeenCalledTimes(0);
// Then it does NOT send a message on ctrl+enter // Then it does NOT send a message on ctrl+enter
await userEvent.type(textBox, "{control>}{enter}{control/}"); await userEvent.type(textBox, "{control>}{enter}{control/}");
expect(onSend).toBeCalledTimes(0); expect(onSend).toHaveBeenCalledTimes(0);
// Then it does send a message on cmd+enter // Then it does send a message on cmd+enter
await userEvent.type(textBox, "{meta>}{enter}{meta/}"); await userEvent.type(textBox, "{meta>}{enter}{meta/}");
expect(onSend).toBeCalledTimes(1); expect(onSend).toHaveBeenCalledTimes(1);
}); });
it("Should insert a newline character when shift enter is pressed when ctrlEnterToSend is false", async () => { it("Should insert a newline character when shift enter is pressed when ctrlEnterToSend is false", async () => {
@ -155,7 +155,7 @@ describe("PlainTextComposer", () => {
await userEvent.type(textBox, inputWithShiftEnter); await userEvent.type(textBox, inputWithShiftEnter);
// Then it does not send a message, but inserts a newline character // Then it does not send a message, but inserts a newline character
expect(onSend).toBeCalledTimes(0); expect(onSend).toHaveBeenCalledTimes(0);
expect(textBox.innerHTML).toBe(expectedInnerHtml); expect(textBox.innerHTML).toBe(expectedInnerHtml);
}); });
@ -172,7 +172,7 @@ describe("PlainTextComposer", () => {
await userEvent.type(textBox, keyboardInput); await userEvent.type(textBox, keyboardInput);
// Then it does not send a message, but inserts a newline character // Then it does not send a message, but inserts a newline character
expect(onSend).toBeCalledTimes(0); expect(onSend).toHaveBeenCalledTimes(0);
expect(textBox.innerHTML).toBe(expectedInnerHtml); expect(textBox.innerHTML).toBe(expectedInnerHtml);
}); });
@ -188,7 +188,7 @@ describe("PlainTextComposer", () => {
await userEvent.type(textBox, "{enter}hello"); await userEvent.type(textBox, "{enter}hello");
// Then it does not send a message, but inserts a newline character // Then it does not send a message, but inserts a newline character
expect(onSend).toBeCalledTimes(0); expect(onSend).toHaveBeenCalledTimes(0);
expect(textBox).not.toContainHTML(enterThenTypeHtml); expect(textBox).not.toContainHTML(enterThenTypeHtml);
}); });
@ -204,7 +204,7 @@ describe("PlainTextComposer", () => {
await userEvent.type(textBox, "{enter}"); await userEvent.type(textBox, "{enter}");
// Then it does not send a message, but inserts a newline character // Then it does not send a message, but inserts a newline character
expect(onSend).toBeCalledTimes(0); expect(onSend).toHaveBeenCalledTimes(0);
expect(textBox).not.toContainHTML(defaultEnterHtml); expect(textBox).not.toContainHTML(defaultEnterHtml);
}); });

View file

@ -88,10 +88,10 @@ describe("WysiwygComposer", () => {
}); });
// Then // Then
await waitFor(() => expect(onChange).toBeCalledWith("foo bar")); await waitFor(() => expect(onChange).toHaveBeenCalledWith("foo bar"));
}); });
it("Should call onSend when Enter is pressed ", async () => { it("Should call onSend when Enter is pressed", async () => {
//When //When
fireEvent( fireEvent(
screen.getByRole("textbox"), screen.getByRole("textbox"),
@ -101,18 +101,18 @@ describe("WysiwygComposer", () => {
); );
// Then it sends a message // Then it sends a message
await waitFor(() => expect(onSend).toBeCalledTimes(1)); await waitFor(() => expect(onSend).toHaveBeenCalledTimes(1));
}); });
it("Should not call onSend when Shift+Enter is pressed ", async () => { it("Should not call onSend when Shift+Enter is pressed", async () => {
//When //When
await userEvent.type(screen.getByRole("textbox"), "{shift>}{enter}"); await userEvent.type(screen.getByRole("textbox"), "{shift>}{enter}");
// Then it sends a message // Then it sends a message
await waitFor(() => expect(onSend).toBeCalledTimes(0)); await waitFor(() => expect(onSend).toHaveBeenCalledTimes(0));
}); });
it("Should not call onSend when ctrl+Enter is pressed ", async () => { it("Should not call onSend when ctrl+Enter is pressed", async () => {
//When //When
// Using userEvent.type or .keyboard wasn't working as expected in the case of ctrl+enter // Using userEvent.type or .keyboard wasn't working as expected in the case of ctrl+enter
fireEvent( fireEvent(
@ -124,23 +124,23 @@ describe("WysiwygComposer", () => {
); );
// Then it sends a message // Then it sends a message
await waitFor(() => expect(onSend).toBeCalledTimes(0)); await waitFor(() => expect(onSend).toHaveBeenCalledTimes(0));
}); });
it("Should not call onSend when alt+Enter is pressed ", async () => { it("Should not call onSend when alt+Enter is pressed", async () => {
//When //When
await userEvent.type(screen.getByRole("textbox"), "{alt>}{enter}"); await userEvent.type(screen.getByRole("textbox"), "{alt>}{enter}");
// Then it sends a message // Then it sends a message
await waitFor(() => expect(onSend).toBeCalledTimes(0)); await waitFor(() => expect(onSend).toHaveBeenCalledTimes(0));
}); });
it("Should not call onSend when meta+Enter is pressed ", async () => { it("Should not call onSend when meta+Enter is pressed", async () => {
//When //When
await userEvent.type(screen.getByRole("textbox"), "{meta>}{enter}"); await userEvent.type(screen.getByRole("textbox"), "{meta>}{enter}");
// Then it sends a message // Then it sends a message
await waitFor(() => expect(onSend).toBeCalledTimes(0)); await waitFor(() => expect(onSend).toHaveBeenCalledTimes(0));
}); });
}); });
@ -172,7 +172,7 @@ describe("WysiwygComposer", () => {
); );
// Then it does not send a message // Then it does not send a message
await waitFor(() => expect(onSend).toBeCalledTimes(0)); await waitFor(() => expect(onSend).toHaveBeenCalledTimes(0));
fireEvent( fireEvent(
textbox, textbox,
@ -201,7 +201,7 @@ describe("WysiwygComposer", () => {
); );
// Then it sends a message // Then it sends a message
await waitFor(() => expect(onSend).toBeCalledTimes(1)); await waitFor(() => expect(onSend).toHaveBeenCalledTimes(1));
}); });
}); });
@ -269,7 +269,7 @@ describe("WysiwygComposer", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledTimes(0); expect(spyDispatcher).toHaveBeenCalledTimes(0);
}); });
it("Should moving when the composer is empty", async () => { it("Should moving when the composer is empty", async () => {
@ -281,7 +281,7 @@ describe("WysiwygComposer", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: Action.EditEvent, action: Action.EditEvent,
event: mockEvent, event: mockEvent,
timelineRenderingType: defaultRoomContext.timelineRenderingType, timelineRenderingType: defaultRoomContext.timelineRenderingType,
@ -316,7 +316,7 @@ describe("WysiwygComposer", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledTimes(0); expect(spyDispatcher).toHaveBeenCalledTimes(0);
}); });
it("Should not moving when the content has changed", async () => { it("Should not moving when the content has changed", async () => {
@ -340,7 +340,7 @@ describe("WysiwygComposer", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledTimes(0); expect(spyDispatcher).toHaveBeenCalledTimes(0);
}); });
it("Should moving up", async () => { it("Should moving up", async () => {
@ -366,7 +366,7 @@ describe("WysiwygComposer", () => {
// Then // Then
await waitFor(() => await waitFor(() =>
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: Action.EditEvent, action: Action.EditEvent,
event: mockEvent, event: mockEvent,
timelineRenderingType: defaultRoomContext.timelineRenderingType, timelineRenderingType: defaultRoomContext.timelineRenderingType,
@ -401,7 +401,7 @@ describe("WysiwygComposer", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: Action.EditEvent, action: Action.EditEvent,
event: mockEvent, event: mockEvent,
timelineRenderingType: defaultRoomContext.timelineRenderingType, timelineRenderingType: defaultRoomContext.timelineRenderingType,
@ -427,7 +427,7 @@ describe("WysiwygComposer", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledTimes(0); expect(spyDispatcher).toHaveBeenCalledTimes(0);
}); });
it("Should not moving when the content has changed", async () => { it("Should not moving when the content has changed", async () => {
@ -451,7 +451,7 @@ describe("WysiwygComposer", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledTimes(0); expect(spyDispatcher).toHaveBeenCalledTimes(0);
}); });
it("Should moving down", async () => { it("Should moving down", async () => {
@ -479,7 +479,7 @@ describe("WysiwygComposer", () => {
// Then // Then
await waitFor(() => await waitFor(() =>
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: Action.EditEvent, action: Action.EditEvent,
event: mockEvent, event: mockEvent,
timelineRenderingType: defaultRoomContext.timelineRenderingType, timelineRenderingType: defaultRoomContext.timelineRenderingType,
@ -516,7 +516,7 @@ describe("WysiwygComposer", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: Action.EditEvent, action: Action.EditEvent,
event: mockEvent, event: mockEvent,
timelineRenderingType: defaultRoomContext.timelineRenderingType, timelineRenderingType: defaultRoomContext.timelineRenderingType,
@ -549,7 +549,7 @@ describe("WysiwygComposer", () => {
// Then // Then
await waitFor(() => await waitFor(() =>
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: Action.EditEvent, action: Action.EditEvent,
event: null, event: null,
timelineRenderingType: defaultRoomContext.timelineRenderingType, timelineRenderingType: defaultRoomContext.timelineRenderingType,

View file

@ -66,8 +66,8 @@ describe("message", () => {
await sendMessage("", true, { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator }); await sendMessage("", true, { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });
// Then // Then
expect(mockClient.sendMessage).toBeCalledTimes(0); expect(mockClient.sendMessage).toHaveBeenCalledTimes(0);
expect(spyDispatcher).toBeCalledTimes(0); expect(spyDispatcher).toHaveBeenCalledTimes(0);
}); });
it("Should not send message when there is no roomId", async () => { it("Should not send message when there is no roomId", async () => {
@ -82,8 +82,8 @@ describe("message", () => {
}); });
// Then // Then
expect(mockClient.sendMessage).toBeCalledTimes(0); expect(mockClient.sendMessage).toHaveBeenCalledTimes(0);
expect(spyDispatcher).toBeCalledTimes(0); expect(spyDispatcher).toHaveBeenCalledTimes(0);
}); });
describe("calls client.sendMessage with", () => { describe("calls client.sendMessage with", () => {
@ -108,7 +108,7 @@ describe("message", () => {
}); });
// Then // Then
expect(mockClient.sendMessage).toBeCalledWith(expect.anything(), null, expect.anything()); expect(mockClient.sendMessage).toHaveBeenCalledWith(expect.anything(), null, expect.anything());
}); });
it("a null argument if SendMessageParams has relation but rel_type does not match THREAD_RELATION_TYPE.name", async () => { it("a null argument if SendMessageParams has relation but rel_type does not match THREAD_RELATION_TYPE.name", async () => {
// When // When
@ -123,7 +123,7 @@ describe("message", () => {
}); });
// Then // Then
expect(mockClient.sendMessage).toBeCalledWith(expect.anything(), null, expect.anything()); expect(mockClient.sendMessage).toHaveBeenCalledWith(expect.anything(), null, expect.anything());
}); });
it("the event_id if SendMessageParams has relation and rel_type matches THREAD_RELATION_TYPE.name", async () => { it("the event_id if SendMessageParams has relation and rel_type matches THREAD_RELATION_TYPE.name", async () => {
@ -139,7 +139,7 @@ describe("message", () => {
}); });
// Then // Then
expect(mockClient.sendMessage).toBeCalledWith(expect.anything(), "valid_id", expect.anything()); expect(mockClient.sendMessage).toHaveBeenCalledWith(expect.anything(), "valid_id", expect.anything());
}); });
}); });
@ -158,8 +158,8 @@ describe("message", () => {
formatted_body: "<i><b>hello</b> world</i>", formatted_body: "<i><b>hello</b> world</i>",
msgtype: "m.text", msgtype: "m.text",
}; };
expect(mockClient.sendMessage).toBeCalledWith("myfakeroom", null, expectedContent); expect(mockClient.sendMessage).toHaveBeenCalledWith("myfakeroom", null, expectedContent);
expect(spyDispatcher).toBeCalledWith({ action: "message_sent" }); expect(spyDispatcher).toHaveBeenCalledWith({ action: "message_sent" });
}); });
it("Should send reply to html message", async () => { it("Should send reply to html message", async () => {
@ -180,7 +180,7 @@ describe("message", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: "reply_to_event", action: "reply_to_event",
event: null, event: null,
context: defaultRoomContext.timelineRenderingType, context: defaultRoomContext.timelineRenderingType,
@ -200,7 +200,7 @@ describe("message", () => {
}, },
}, },
}; };
expect(mockClient.sendMessage).toBeCalledWith("myfakeroom", null, expectedContent); expect(mockClient.sendMessage).toHaveBeenCalledWith("myfakeroom", null, expectedContent);
}); });
it("Should scroll to bottom after sending a html message", async () => { it("Should scroll to bottom after sending a html message", async () => {
@ -213,7 +213,7 @@ describe("message", () => {
}); });
// Then // Then
expect(spyDispatcher).toBeCalledWith({ expect(spyDispatcher).toHaveBeenCalledWith({
action: "scroll_to_bottom", action: "scroll_to_bottom",
timelineRenderingType: defaultRoomContext.timelineRenderingType, timelineRenderingType: defaultRoomContext.timelineRenderingType,
}); });
@ -224,7 +224,7 @@ describe("message", () => {
await sendMessage("🎉", false, { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator }); await sendMessage("🎉", false, { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });
// Then // Then
expect(spyDispatcher).toBeCalledWith({ action: "effects.confetti" }); expect(spyDispatcher).toHaveBeenCalledWith({ action: "effects.confetti" });
}); });
}); });
@ -256,10 +256,10 @@ describe("message", () => {
await editMessage("", { roomContext: defaultRoomContext, mxClient: mockClient, editorStateTransfer }); await editMessage("", { roomContext: defaultRoomContext, mxClient: mockClient, editorStateTransfer });
// Then // Then
expect(mockClient.sendMessage).toBeCalledTimes(0); expect(mockClient.sendMessage).toHaveBeenCalledTimes(0);
expect(mockClient.cancelPendingEvent).toBeCalledTimes(1); expect(mockClient.cancelPendingEvent).toHaveBeenCalledTimes(1);
expect(mockCreateRedactEventDialog).toBeCalledTimes(1); expect(mockCreateRedactEventDialog).toHaveBeenCalledTimes(1);
expect(spyDispatcher).toBeCalledTimes(0); expect(spyDispatcher).toHaveBeenCalledTimes(0);
}); });
it("Should do nothing if the content is unmodified", async () => { it("Should do nothing if the content is unmodified", async () => {
@ -271,7 +271,7 @@ describe("message", () => {
}); });
// Then // Then
expect(mockClient.sendMessage).toBeCalledTimes(0); expect(mockClient.sendMessage).toHaveBeenCalledTimes(0);
}); });
it("Should send a message when the content is modified", async () => { it("Should send a message when the content is modified", async () => {
@ -301,8 +301,8 @@ describe("message", () => {
msgtype, msgtype,
format, format,
}; };
expect(mockClient.sendMessage).toBeCalledWith(mockEvent.getRoomId(), null, expectedContent); expect(mockClient.sendMessage).toHaveBeenCalledWith(mockEvent.getRoomId(), null, expectedContent);
expect(spyDispatcher).toBeCalledWith({ action: "message_sent" }); expect(spyDispatcher).toHaveBeenCalledWith({ action: "message_sent" });
}); });
}); });
}); });

View file

@ -47,7 +47,7 @@ describe("<DeviceDetailHeading />", () => {
expect({ container }).toMatchSnapshot(); expect({ container }).toMatchSnapshot();
}); });
it("renders device id as fallback when device has no display name ", () => { it("renders device id as fallback when device has no display name", () => {
const { getByText } = render( const { getByText } = render(
getComponent({ getComponent({
device: { ...device, display_name: undefined }, device: { ...device, display_name: undefined },

View file

@ -207,17 +207,6 @@ describe("<SessionManagerTab />", () => {
expect(container.getElementsByClassName("mx_Spinner").length).toBeTruthy(); expect(container.getElementsByClassName("mx_Spinner").length).toBeTruthy();
}); });
it("removes spinner when device fetch fails", async () => {
mockClient.getDevices.mockRejectedValue({ httpStatus: 404 });
const { container } = render(getComponent());
expect(mockClient.getDevices).toHaveBeenCalled();
await act(async () => {
await flushPromises();
});
expect(container.getElementsByClassName("mx_Spinner").length).toBeFalsy();
});
it("removes spinner when device fetch fails", async () => { it("removes spinner when device fetch fails", async () => {
// eat the expected error log // eat the expected error log
jest.spyOn(logger, "error").mockImplementation(() => {}); jest.spyOn(logger, "error").mockImplementation(() => {});
@ -760,7 +749,7 @@ describe("<SessionManagerTab />", () => {
expect(mockClient.getDevices).toHaveBeenCalled(); expect(mockClient.getDevices).toHaveBeenCalled();
}); });
it("deletes a device when interactive auth is not required", async () => { it("does not delete a device when interactive auth is not required", async () => {
const { getByTestId } = render(getComponent()); const { getByTestId } = render(getComponent());
await act(async () => { await act(async () => {

View file

@ -215,7 +215,7 @@ describe("editor/deserialize", function () {
expect(parts[4]).toStrictEqual({ type: "plain", text: "```" }); expect(parts[4]).toStrictEqual({ type: "plain", text: "```" });
}); });
// failing likely because of https://github.com/vector-im/element-web/issues/10316 // failing likely because of https://github.com/vector-im/element-web/issues/10316
xit("code block with no trailing text and no newlines", function () { it.skip("code block with no trailing text and no newlines", function () {
const html = "<pre><code>0xDEADBEEF</code></pre>"; const html = "<pre><code>0xDEADBEEF</code></pre>";
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator())); const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
expect(parts.length).toBe(5); expect(parts.length).toBe(5);
@ -412,7 +412,7 @@ describe("editor/deserialize", function () {
text: "> <del>no formatting here</del>", text: "> <del>no formatting here</del>",
}); });
}); });
it("it strips plaintext replies", () => { it("strips plaintext replies", () => {
const body = "> Sender: foo\n\nMessage"; const body = "> Sender: foo\n\nMessage";
const parts = normalize(parseEvent(textMessageReply(body), createPartCreator(), { shouldEscape: false })); const parts = normalize(parseEvent(textMessageReply(body), createPartCreator(), { shouldEscape: false }));
expect(parts.length).toBe(1); expect(parts.length).toBe(1);

View file

@ -95,7 +95,7 @@ describe("RelationsHelper", () => {
expect(() => { expect(() => {
new RelationsHelper(event, RelationType.Reference, EventType.RoomMessage, client); new RelationsHelper(event, RelationType.Reference, EventType.RoomMessage, client);
}).toThrowError("unable to create RelationsHelper: missing event ID"); }).toThrow("unable to create RelationsHelper: missing event ID");
}); });
}); });
@ -105,7 +105,7 @@ describe("RelationsHelper", () => {
expect(() => { expect(() => {
new RelationsHelper(event, RelationType.Reference, EventType.RoomMessage, client); new RelationsHelper(event, RelationType.Reference, EventType.RoomMessage, client);
}).toThrowError("unable to create RelationsHelper: missing room ID"); }).toThrow("unable to create RelationsHelper: missing room ID");
}); });
}); });

View file

@ -93,20 +93,17 @@ describe("languageHandler", function () {
}); });
describe("when translations exist in language", () => { describe("when translations exist in language", () => {
beforeEach(function (done) { beforeEach(function () {
stubClient(); stubClient();
setLanguage("en").then(done); setLanguage("en");
setMissingEntryGenerator((key) => key.split("|", 2)[1]); setMissingEntryGenerator((key) => key.split("|", 2)[1]);
}); });
it("translates a string to german", function (done) { it("translates a string to german", async () => {
setLanguage("de") await setLanguage("de");
.then(function () {
const translated = _t(basicString); const translated = _t(basicString);
expect(translated).toBe("Räume"); expect(translated).toBe("Räume");
})
.then(done);
}); });
it.each(testCasesEn)("%s", (_d, translationString, variables, tags, result) => { it.each(testCasesEn)("%s", (_d, translationString, variables, tags, result) => {

View file

@ -74,7 +74,8 @@ describe("AutoRageshakeStore", () => {
}); });
it("should send a rageshake", () => { it("should send a rageshake", () => {
expect(mocked(client).sendToDevice.mock.calls).toMatchInlineSnapshot(` expect(mocked(client).sendToDevice.mock.calls).toMatchInlineSnapshot(
`
[ [
[ [
"im.vector.auto_rs_request", "im.vector.auto_rs_request",
@ -82,7 +83,7 @@ describe("AutoRageshakeStore", () => {
"@userId:matrix.org": { "@userId:matrix.org": {
"undefined": { "undefined": {
"device_id": undefined, "device_id": undefined,
"event_id": "${utdEvent.getId()}", "event_id": "utd_event_id",
"recipient_rageshake": undefined, "recipient_rageshake": undefined,
"room_id": "!room:example.com", "room_id": "!room:example.com",
"sender_key": undefined, "sender_key": undefined,
@ -93,7 +94,8 @@ describe("AutoRageshakeStore", () => {
}, },
], ],
] ]
`); `.replace("utd_event_id", utdEvent.getId()!),
);
}); });
}); });
}); });

View file

@ -1179,34 +1179,34 @@ describe("SpaceStore", () => {
const fn = jest.fn(); const fn = jest.fn();
store.traverseSpace("!b:server", fn); store.traverseSpace("!b:server", fn);
expect(fn).toBeCalledTimes(3); expect(fn).toHaveBeenCalledTimes(3);
expect(fn).toBeCalledWith("!a:server"); expect(fn).toHaveBeenCalledWith("!a:server");
expect(fn).toBeCalledWith("!b:server"); expect(fn).toHaveBeenCalledWith("!b:server");
expect(fn).toBeCalledWith("!c:server"); expect(fn).toHaveBeenCalledWith("!c:server");
}); });
it("including rooms", () => { it("including rooms", () => {
const fn = jest.fn(); const fn = jest.fn();
store.traverseSpace("!b:server", fn, true); store.traverseSpace("!b:server", fn, true);
expect(fn).toBeCalledTimes(8); // twice for shared-child expect(fn).toHaveBeenCalledTimes(8); // twice for shared-child
expect(fn).toBeCalledWith("!a:server"); expect(fn).toHaveBeenCalledWith("!a:server");
expect(fn).toBeCalledWith("!a-child:server"); expect(fn).toHaveBeenCalledWith("!a-child:server");
expect(fn).toBeCalledWith("!b:server"); expect(fn).toHaveBeenCalledWith("!b:server");
expect(fn).toBeCalledWith("!b-child:server"); expect(fn).toHaveBeenCalledWith("!b-child:server");
expect(fn).toBeCalledWith("!c:server"); expect(fn).toHaveBeenCalledWith("!c:server");
expect(fn).toBeCalledWith("!c-child:server"); expect(fn).toHaveBeenCalledWith("!c-child:server");
expect(fn).toBeCalledWith("!shared-child:server"); expect(fn).toHaveBeenCalledWith("!shared-child:server");
}); });
it("excluding rooms", () => { it("excluding rooms", () => {
const fn = jest.fn(); const fn = jest.fn();
store.traverseSpace("!b:server", fn, false); store.traverseSpace("!b:server", fn, false);
expect(fn).toBeCalledTimes(3); expect(fn).toHaveBeenCalledTimes(3);
expect(fn).toBeCalledWith("!a:server"); expect(fn).toHaveBeenCalledWith("!a:server");
expect(fn).toBeCalledWith("!b:server"); expect(fn).toHaveBeenCalledWith("!b:server");
expect(fn).toBeCalledWith("!c:server"); expect(fn).toHaveBeenCalledWith("!c:server");
}); });
}); });

View file

@ -163,13 +163,13 @@ describe("SlidingRoomListStore", () => {
it("setTagSorting alters the 'sort' option in the list", async () => { it("setTagSorting alters the 'sort' option in the list", async () => {
const tagId: TagID = "foo"; const tagId: TagID = "foo";
await store.setTagSorting(tagId, SortAlgorithm.Alphabetic); await store.setTagSorting(tagId, SortAlgorithm.Alphabetic);
expect(context._SlidingSyncManager!.ensureListRegistered).toBeCalledWith(tagId, { expect(context._SlidingSyncManager!.ensureListRegistered).toHaveBeenCalledWith(tagId, {
sort: SlidingSyncSortToFilter[SortAlgorithm.Alphabetic], sort: SlidingSyncSortToFilter[SortAlgorithm.Alphabetic],
}); });
expect(store.getTagSorting(tagId)).toEqual(SortAlgorithm.Alphabetic); expect(store.getTagSorting(tagId)).toEqual(SortAlgorithm.Alphabetic);
await store.setTagSorting(tagId, SortAlgorithm.Recent); await store.setTagSorting(tagId, SortAlgorithm.Recent);
expect(context._SlidingSyncManager!.ensureListRegistered).toBeCalledWith(tagId, { expect(context._SlidingSyncManager!.ensureListRegistered).toHaveBeenCalledWith(tagId, {
sort: SlidingSyncSortToFilter[SortAlgorithm.Recent], sort: SlidingSyncSortToFilter[SortAlgorithm.Recent],
}); });
expect(store.getTagSorting(tagId)).toEqual(SortAlgorithm.Recent); expect(store.getTagSorting(tagId)).toEqual(SortAlgorithm.Recent);

View file

@ -151,7 +151,7 @@ describe("StopGapWidgetDriver", () => {
state: OpenIDRequestState.Allowed, state: OpenIDRequestState.Allowed,
token: await client.getOpenIdToken(), token: await client.getOpenIdToken(),
}; };
expect(listener).toBeCalledWith(openIdUpdate); expect(listener).toHaveBeenCalledWith(openIdUpdate);
}); });
describe("sendToDevice", () => { describe("sendToDevice", () => {
@ -276,7 +276,7 @@ describe("StopGapWidgetDriver", () => {
prevBatch: undefined, prevBatch: undefined,
}); });
expect(client.relations).toBeCalledWith("!this-room-id", "$event", null, null, {}); expect(client.relations).toHaveBeenCalledWith("!this-room-id", "$event", null, null, {});
}); });
it("reads related events from a selected room", async () => { it("reads related events from a selected room", async () => {
@ -292,7 +292,7 @@ describe("StopGapWidgetDriver", () => {
prevBatch: undefined, prevBatch: undefined,
}); });
expect(client.relations).toBeCalledWith("!room-id", "$event", null, null, {}); expect(client.relations).toHaveBeenCalledWith("!room-id", "$event", null, null, {});
}); });
it("reads related events with custom parameters", async () => { it("reads related events with custom parameters", async () => {
@ -318,7 +318,7 @@ describe("StopGapWidgetDriver", () => {
prevBatch: undefined, prevBatch: undefined,
}); });
expect(client.relations).toBeCalledWith("!room-id", "$event", "m.reference", "m.room.message", { expect(client.relations).toHaveBeenCalledWith("!room-id", "$event", "m.reference", "m.room.message", {
limit: 25, limit: 25,
from: "from-token", from: "from-token",
to: "to-token", to: "to-token",

View file

@ -63,7 +63,7 @@ describe("theme", () => {
// Then // Then
expect(spyQuerySelectorAll).toHaveBeenCalledWith("[data-mx-theme]"); expect(spyQuerySelectorAll).toHaveBeenCalledWith("[data-mx-theme]");
expect(spyQuerySelectorAll).toBeCalledTimes(1); expect(spyQuerySelectorAll).toHaveBeenCalledTimes(1);
expect(lightTheme.disabled).toBe(false); expect(lightTheme.disabled).toBe(false);
expect(darkTheme.disabled).toBe(true); expect(darkTheme.disabled).toBe(true);
}); });

View file

@ -35,7 +35,7 @@ describe("createReconnectedListener", () => {
].forEach(([from, to]) => { ].forEach(([from, to]) => {
it(`should invoke the callback on a transition from ${from} to ${to}`, () => { it(`should invoke the callback on a transition from ${from} to ${to}`, () => {
reconnectedListener(to, from); reconnectedListener(to, from);
expect(onReconnect).toBeCalled(); expect(onReconnect).toHaveBeenCalled();
}); });
}); });
@ -46,7 +46,7 @@ describe("createReconnectedListener", () => {
].forEach(([from, to]) => { ].forEach(([from, to]) => {
it(`should not invoke the callback on a transition from ${from} to ${to}`, () => { it(`should not invoke the callback on a transition from ${from} to ${to}`, () => {
reconnectedListener(to, from); reconnectedListener(to, from);
expect(onReconnect).not.toBeCalled(); expect(onReconnect).not.toHaveBeenCalled();
}); });
}); });
}); });

View file

@ -130,8 +130,8 @@ describe("parseUserAgent()", () => {
const testPlatform = (platform: string, userAgents: string[], results: ExtendedDeviceInformation[]): void => { const testPlatform = (platform: string, userAgents: string[], results: ExtendedDeviceInformation[]): void => {
const testCases: TestCase[] = userAgents.map((userAgent, index) => [userAgent, results[index]]); const testCases: TestCase[] = userAgents.map((userAgent, index) => [userAgent, results[index]]);
describe(platform, () => { describe(`on platform ${platform}`, () => {
it.each(testCases)("Parses user agent correctly - %s", (userAgent, expectedResult) => { it.each(testCases)("should parse the user agent correctly - %s", (userAgent, expectedResult) => {
expect(parseUserAgent(userAgent)).toEqual(expectedResult); expect(parseUserAgent(userAgent)).toEqual(expectedResult);
}); });
}); });

View file

@ -290,7 +290,7 @@ describe("export", function () {
], ],
]; ];
it.each(invalidExportOptions)("%s", (_d, options) => { it.each(invalidExportOptions)("%s", (_d, options) => {
expect(() => new PlainTextExporter(mockRoom, ExportType.Beginning, options, setProgressText)).toThrowError( expect(() => new PlainTextExporter(mockRoom, ExportType.Beginning, options, setProgressText)).toThrow(
"Invalid export options", "Invalid export options",
); );
}); });

View file

@ -329,31 +329,28 @@ describe("HTMLExport", () => {
// test link to the first page // test link to the first page
//@ts-ignore private access //@ts-ignore private access
exporter.wrapHTML("", 0, 3).then((res) => { let result = await exporter.wrapHTML("", 0, 3);
expect(res).not.toContain("Previous group of messages"); expect(result).not.toContain("Previous group of messages");
expect(res).toContain( expect(result).toContain(
'<div style="text-align:center;margin:10px"><a href="./messages2.html" style="font-weight:bold">Next group of messages</a></div>', '<div style="text-align:center;margin:10px"><a href="./messages2.html" style="font-weight:bold">Next group of messages</a></div>',
); );
});
// test link for a middle page // test link for a middle page
//@ts-ignore private access //@ts-ignore private access
exporter.wrapHTML("", 1, 3).then((res) => { result = await exporter.wrapHTML("", 1, 3);
expect(res).toContain( expect(result).toContain(
'<div style="text-align:center"><a href="./messages.html" style="font-weight:bold">Previous group of messages</a></div>', '<div style="text-align:center"><a href="./messages.html" style="font-weight:bold">Previous group of messages</a></div>',
); );
expect(res).toContain( expect(result).toContain(
'<div style="text-align:center;margin:10px"><a href="./messages3.html" style="font-weight:bold">Next group of messages</a></div>', '<div style="text-align:center;margin:10px"><a href="./messages3.html" style="font-weight:bold">Next group of messages</a></div>',
); );
});
// test link for last page // test link for last page
//@ts-ignore private access //@ts-ignore private access
exporter.wrapHTML("", 2, 3).then((res) => { result = await exporter.wrapHTML("", 2, 3);
expect(res).toContain( expect(result).toContain(
'<div style="text-align:center"><a href="./messages2.html" style="font-weight:bold">Previous group of messages</a></div>', '<div style="text-align:center"><a href="./messages2.html" style="font-weight:bold">Previous group of messages</a></div>',
); );
expect(res).not.toContain("Next group of messages"); expect(result).not.toContain("Next group of messages");
});
}); });
}); });

View file

@ -120,16 +120,14 @@ describe("local-room", () => {
mocked(isRoomReady).mockReturnValue(false); mocked(isRoomReady).mockReturnValue(false);
}); });
it("should invoke the callbacks, set the room state to created and return the actual room id", (done) => { it("should invoke the callbacks, set the room state to created and return the actual room id", async () => {
const prom = localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks(client, localRoom); const prom = localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks(client, localRoom);
jest.advanceTimersByTime(5000); jest.advanceTimersByTime(5000);
prom.then((roomId: string) => { const roomId = await prom;
expect(localRoom.state).toBe(LocalRoomState.CREATED); expect(localRoom.state).toBe(LocalRoomState.CREATED);
expect(localRoomCallbackRoomId).toBe(room1.roomId); expect(localRoomCallbackRoomId).toBe(room1.roomId);
expect(roomId).toBe(room1.roomId); expect(roomId).toBe(room1.roomId);
expect(jest.getTimerCount()).toBe(0); expect(jest.getTimerCount()).toBe(0);
done();
});
}); });
}); });
@ -138,17 +136,15 @@ describe("local-room", () => {
mocked(isRoomReady).mockReturnValue(false); mocked(isRoomReady).mockReturnValue(false);
}); });
it("should invoke the callbacks, set the room state to created and return the actual room id", (done) => { it("should invoke the callbacks, set the room state to created and return the actual room id", async () => {
const prom = localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks(client, localRoom); const prom = localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks(client, localRoom);
mocked(isRoomReady).mockReturnValue(true); mocked(isRoomReady).mockReturnValue(true);
jest.advanceTimersByTime(500); jest.advanceTimersByTime(500);
prom.then((roomId: string) => { const roomId = await prom;
expect(localRoom.state).toBe(LocalRoomState.CREATED); expect(localRoom.state).toBe(LocalRoomState.CREATED);
expect(localRoomCallbackRoomId).toBe(room1.roomId); expect(localRoomCallbackRoomId).toBe(room1.roomId);
expect(roomId).toBe(room1.roomId); expect(roomId).toBe(room1.roomId);
expect(jest.getTimerCount()).toBe(0); expect(jest.getTimerCount()).toBe(0);
done();
});
}); });
}); });
}); });

View file

@ -51,7 +51,7 @@ describe("isRoomReady", () => {
mocked(client.getRoom).mockReturnValue(null); mocked(client.getRoom).mockReturnValue(null);
}); });
it("it should return false", () => { it("should return false", () => {
expect(isRoomReady(client, localRoom)).toBe(false); expect(isRoomReady(client, localRoom)).toBe(false);
}); });
@ -63,7 +63,7 @@ describe("isRoomReady", () => {
}); });
}); });
it("it should return false", () => { it("should return false", () => {
expect(isRoomReady(client, localRoom)).toBe(false); expect(isRoomReady(client, localRoom)).toBe(false);
}); });
@ -75,7 +75,7 @@ describe("isRoomReady", () => {
]); ]);
}); });
it("it should return false", () => { it("should return false", () => {
expect(isRoomReady(client, localRoom)).toBe(false); expect(isRoomReady(client, localRoom)).toBe(false);
}); });
@ -92,7 +92,7 @@ describe("isRoomReady", () => {
]); ]);
}); });
it("it should return true", () => { it("should return true", () => {
expect(isRoomReady(client, localRoom)).toBe(true); expect(isRoomReady(client, localRoom)).toBe(true);
}); });
@ -101,7 +101,7 @@ describe("isRoomReady", () => {
localRoom.encrypted = true; localRoom.encrypted = true;
}); });
it("it should return false", () => { it("should return false", () => {
expect(isRoomReady(client, localRoom)).toBe(false); expect(isRoomReady(client, localRoom)).toBe(false);
}); });
@ -118,7 +118,7 @@ describe("isRoomReady", () => {
]); ]);
}); });
it("it should return true", () => { it("should return true", () => {
expect(isRoomReady(client, localRoom)).toBe(true); expect(isRoomReady(client, localRoom)).toBe(true);
}); });
}); });

View file

@ -29,31 +29,32 @@ describe("waitForMember", () => {
client = new EventEmitter(); client = new EventEmitter();
}); });
it("resolves with false if the timeout is reached", (done) => { afterEach(() => {
waitForMember(<MatrixClient>client, "", "", { timeout: 0 }).then((r) => { jest.useRealTimers();
expect(r).toBe(false);
done();
});
}); });
it("resolves with false if the timeout is reached, even if other RoomState.newMember events fire", (done) => { it("resolves with false if the timeout is reached", async () => {
const result = await waitForMember(<MatrixClient>client, "", "", { timeout: 0 });
expect(result).toBe(false);
});
it("resolves with false if the timeout is reached, even if other RoomState.newMember events fire", async () => {
jest.useFakeTimers();
const roomId = "!roomId:domain"; const roomId = "!roomId:domain";
const userId = "@clientId:domain"; const userId = "@clientId:domain";
waitForMember(<MatrixClient>client, roomId, userId, { timeout }).then((r) => { const resultProm = waitForMember(<MatrixClient>client, roomId, userId, { timeout });
expect(r).toBe(false); jest.advanceTimersByTime(50);
done(); expect(await resultProm).toBe(false);
});
client.emit("RoomState.newMember", undefined, undefined, { roomId, userId: "@anotherClient:domain" }); client.emit("RoomState.newMember", undefined, undefined, { roomId, userId: "@anotherClient:domain" });
jest.useRealTimers();
}); });
it("resolves with true if RoomState.newMember fires", (done) => { it("resolves with true if RoomState.newMember fires", async () => {
const roomId = "!roomId:domain"; const roomId = "!roomId:domain";
const userId = "@clientId:domain"; const userId = "@clientId:domain";
waitForMember(<MatrixClient>client, roomId, userId, { timeout }).then((r) => {
expect(r).toBe(true);
expect((<MatrixClient>client).listeners(RoomStateEvent.NewMember).length).toBe(0); expect((<MatrixClient>client).listeners(RoomStateEvent.NewMember).length).toBe(0);
done(); const resultProm = waitForMember(<MatrixClient>client, roomId, userId, { timeout });
});
client.emit("RoomState.newMember", undefined, undefined, { roomId, userId }); client.emit("RoomState.newMember", undefined, undefined, { roomId, userId });
expect(await resultProm).toBe(true);
}); });
}); });

View file

@ -128,7 +128,7 @@ describe("notifications", () => {
it("sends a request even if everything has been read", () => { it("sends a request even if everything has been read", () => {
clearRoomNotification(room, client); clearRoomNotification(room, client);
expect(sendReadReceiptSpy).not.toBeCalled(); expect(sendReadReceiptSpy).not.toHaveBeenCalled();
}); });
it("marks the room as read even if the receipt failed", async () => { it("marks the room as read even if the receipt failed", async () => {
@ -163,7 +163,7 @@ describe("notifications", () => {
it("does not send any requests if everything has been read", () => { it("does not send any requests if everything has been read", () => {
clearAllNotifications(client); clearAllNotifications(client);
expect(sendReadReceiptSpy).not.toBeCalled(); expect(sendReadReceiptSpy).not.toHaveBeenCalled();
}); });
it("sends unthreaded receipt requests", () => { it("sends unthreaded receipt requests", () => {
@ -178,7 +178,7 @@ describe("notifications", () => {
clearAllNotifications(client); clearAllNotifications(client);
expect(sendReadReceiptSpy).toBeCalledWith(message, ReceiptType.Read, true); expect(sendReadReceiptSpy).toHaveBeenCalledWith(message, ReceiptType.Read, true);
}); });
it("sends private read receipts", () => { it("sends private read receipts", () => {
@ -195,7 +195,7 @@ describe("notifications", () => {
clearAllNotifications(client); clearAllNotifications(client);
expect(sendReadReceiptSpy).toBeCalledWith(message, ReceiptType.ReadPrivate, true); expect(sendReadReceiptSpy).toHaveBeenCalledWith(message, ReceiptType.ReadPrivate, true);
}); });
}); });
}); });

View file

@ -269,7 +269,7 @@ describe("VoiceBroadcastRecording", () => {
it("should raise an error when creating a broadcast", () => { it("should raise an error when creating a broadcast", () => {
expect(() => { expect(() => {
setUpVoiceBroadcastRecording(); setUpVoiceBroadcastRecording();
}).toThrowError("Cannot create broadcast for info event without Id."); }).toThrow("Cannot create broadcast for info event without Id.");
}); });
}); });
@ -285,7 +285,7 @@ describe("VoiceBroadcastRecording", () => {
it("should raise an error when creating a broadcast", () => { it("should raise an error when creating a broadcast", () => {
expect(() => { expect(() => {
setUpVoiceBroadcastRecording(); setUpVoiceBroadcastRecording();
}).toThrowError(`Cannot create broadcast for unknown room (info event ${infoEvent.getId()})`); }).toThrow(`Cannot create broadcast for unknown room (info event ${infoEvent.getId()})`);
}); });
}); });

View file

@ -74,7 +74,7 @@ describe("VoiceBroadcastRecordingsStore", () => {
infoEvent.event.event_id = undefined; infoEvent.event.event_id = undefined;
expect(() => { expect(() => {
recordings.setCurrent(recording); recordings.setCurrent(recording);
}).toThrowError("Got broadcast info event without Id"); }).toThrow("Got broadcast info event without Id");
}); });
describe("when setting a current Voice Broadcast recording", () => { describe("when setting a current Voice Broadcast recording", () => {

View file

@ -67,11 +67,7 @@ describe("setUpVoiceBroadcastPreRecording", () => {
beforeEach(() => { beforeEach(() => {
client = stubClient(); client = stubClient();
userId = client.getSafeUserId();
const clientUserId = client.getUserId();
if (!clientUserId) fail("empty userId");
userId = clientUserId;
room = new Room(roomId, client, userId); room = new Room(roomId, client, userId);
infoEvent = mkVoiceBroadcastInfoStateEvent( infoEvent = mkVoiceBroadcastInfoStateEvent(
roomId, roomId,

View file

@ -2528,6 +2528,14 @@
"@typescript-eslint/types" "5.53.0" "@typescript-eslint/types" "5.53.0"
"@typescript-eslint/visitor-keys" "5.53.0" "@typescript-eslint/visitor-keys" "5.53.0"
"@typescript-eslint/scope-manager@5.54.0":
version "5.54.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.54.0.tgz#74b28ac9a3fc8166f04e806c957adb8c1fd00536"
integrity sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg==
dependencies:
"@typescript-eslint/types" "5.54.0"
"@typescript-eslint/visitor-keys" "5.54.0"
"@typescript-eslint/type-utils@5.53.0": "@typescript-eslint/type-utils@5.53.0":
version "5.53.0" version "5.53.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.53.0.tgz#41665449935ba9b4e6a1ba6e2a3f4b2c31d6cf97" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.53.0.tgz#41665449935ba9b4e6a1ba6e2a3f4b2c31d6cf97"
@ -2543,6 +2551,11 @@
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.53.0.tgz#f79eca62b97e518ee124086a21a24f3be267026f" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.53.0.tgz#f79eca62b97e518ee124086a21a24f3be267026f"
integrity sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A== integrity sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==
"@typescript-eslint/types@5.54.0":
version "5.54.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.54.0.tgz#7d519df01f50739254d89378e0dcac504cab2740"
integrity sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ==
"@typescript-eslint/typescript-estree@5.53.0": "@typescript-eslint/typescript-estree@5.53.0":
version "5.53.0" version "5.53.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz#bc651dc28cf18ab248ecd18a4c886c744aebd690" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz#bc651dc28cf18ab248ecd18a4c886c744aebd690"
@ -2556,6 +2569,19 @@
semver "^7.3.7" semver "^7.3.7"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/typescript-estree@5.54.0":
version "5.54.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.0.tgz#f6f3440cabee8a43a0b25fa498213ebb61fdfe99"
integrity sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ==
dependencies:
"@typescript-eslint/types" "5.54.0"
"@typescript-eslint/visitor-keys" "5.54.0"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.53.0": "@typescript-eslint/utils@5.53.0":
version "5.53.0" version "5.53.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.53.0.tgz#e55eaad9d6fffa120575ffaa530c7e802f13bce8" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.53.0.tgz#e55eaad9d6fffa120575ffaa530c7e802f13bce8"
@ -2570,6 +2596,20 @@
eslint-utils "^3.0.0" eslint-utils "^3.0.0"
semver "^7.3.7" semver "^7.3.7"
"@typescript-eslint/utils@^5.10.0":
version "5.54.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.54.0.tgz#3db758aae078be7b54b8ea8ea4537ff6cd3fbc21"
integrity sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw==
dependencies:
"@types/json-schema" "^7.0.9"
"@types/semver" "^7.3.12"
"@typescript-eslint/scope-manager" "5.54.0"
"@typescript-eslint/types" "5.54.0"
"@typescript-eslint/typescript-estree" "5.54.0"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
semver "^7.3.7"
"@typescript-eslint/visitor-keys@5.53.0": "@typescript-eslint/visitor-keys@5.53.0":
version "5.53.0" version "5.53.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz#8a5126623937cdd909c30d8fa72f79fa56cc1a9f" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz#8a5126623937cdd909c30d8fa72f79fa56cc1a9f"
@ -2578,6 +2618,14 @@
"@typescript-eslint/types" "5.53.0" "@typescript-eslint/types" "5.53.0"
eslint-visitor-keys "^3.3.0" eslint-visitor-keys "^3.3.0"
"@typescript-eslint/visitor-keys@5.54.0":
version "5.54.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.0.tgz#846878afbf0cd67c19cfa8d75947383d4490db8f"
integrity sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA==
dependencies:
"@typescript-eslint/types" "5.54.0"
eslint-visitor-keys "^3.3.0"
"@wojtekmaj/enzyme-adapter-react-17@^0.8.0": "@wojtekmaj/enzyme-adapter-react-17@^0.8.0":
version "0.8.0" version "0.8.0"
resolved "https://registry.yarnpkg.com/@wojtekmaj/enzyme-adapter-react-17/-/enzyme-adapter-react-17-0.8.0.tgz#138f404f82f502d152242c049e87d9621dcda4bd" resolved "https://registry.yarnpkg.com/@wojtekmaj/enzyme-adapter-react-17/-/enzyme-adapter-react-17-0.8.0.tgz#138f404f82f502d152242c049e87d9621dcda4bd"
@ -4264,6 +4312,13 @@ eslint-plugin-import@^2.25.4:
resolve "^1.22.0" resolve "^1.22.0"
tsconfig-paths "^3.14.1" tsconfig-paths "^3.14.1"
eslint-plugin-jest@^27.2.1:
version "27.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz#b85b4adf41c682ea29f1f01c8b11ccc39b5c672c"
integrity sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==
dependencies:
"@typescript-eslint/utils" "^5.10.0"
eslint-plugin-jsx-a11y@^6.5.1: eslint-plugin-jsx-a11y@^6.5.1:
version "6.6.1" version "6.6.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff"