From 12eedad3ccf0aad8c51c08c1af78387acbe1127a Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 17:20:18 -0600 Subject: [PATCH 01/18] Add eslint jest --- .eslintrc.js | 2 +- package.json | 1 + yarn.lock | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index fd77e6c5e42..de90f681775 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,6 @@ module.exports = { plugins: ["matrix-org", "import", "jsdoc"], - extends: ["plugin:matrix-org/babel", "plugin:import/typescript"], + extends: ["plugin:matrix-org/babel", "plugin:matrix-org/jest", "plugin:import/typescript"], env: { browser: true, node: true, diff --git a/package.json b/package.json index 128de735ea3..5e457278a31 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.5.1", "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jest": "^27.1.6", "eslint-plugin-jsdoc": "^39.6.4", "eslint-plugin-matrix-org": "^0.9.0", "eslint-plugin-tsdoc": "^0.2.17", diff --git a/yarn.lock b/yarn.lock index c4d494579ad..60ab2e5394a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1838,6 +1838,14 @@ "@typescript-eslint/types" "5.45.0" "@typescript-eslint/visitor-keys" "5.45.0" +"@typescript-eslint/scope-manager@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz#70af8425c79bbc1178b5a63fb51102ddf48e104a" + integrity sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA== + dependencies: + "@typescript-eslint/types" "5.46.1" + "@typescript-eslint/visitor-keys" "5.46.1" + "@typescript-eslint/type-utils@5.45.0": version "5.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz#aefbc954c40878fcebeabfb77d20d84a3da3a8b2" @@ -1853,6 +1861,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.45.0.tgz#794760b9037ee4154c09549ef5a96599621109c5" integrity sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA== +"@typescript-eslint/types@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.46.1.tgz#4e9db2107b9a88441c4d5ecacde3bb7a5ebbd47e" + integrity sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w== + "@typescript-eslint/typescript-estree@5.45.0": version "5.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz#f70a0d646d7f38c0dfd6936a5e171a77f1e5291d" @@ -1866,6 +1879,19 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz#5358088f98a8f9939355e0996f9c8f41c25eced2" + integrity sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg== + dependencies: + "@typescript-eslint/types" "5.46.1" + "@typescript-eslint/visitor-keys" "5.46.1" + 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.45.0": version "5.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.45.0.tgz#9cca2996eee1b8615485a6918a5c763629c7acf5" @@ -1880,6 +1906,20 @@ eslint-utils "^3.0.0" semver "^7.3.7" +"@typescript-eslint/utils@^5.10.0": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.46.1.tgz#7da3c934d9fd0eb4002a6bb3429f33298b469b4a" + integrity sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA== + dependencies: + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.46.1" + "@typescript-eslint/types" "5.46.1" + "@typescript-eslint/typescript-estree" "5.46.1" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + semver "^7.3.7" + "@typescript-eslint/visitor-keys@5.45.0": version "5.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz#e0d160e9e7fdb7f8da697a5b78e7a14a22a70528" @@ -1888,6 +1928,14 @@ "@typescript-eslint/types" "5.45.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz#126cc6fe3c0f83608b2b125c5d9daced61394242" + integrity sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg== + dependencies: + "@typescript-eslint/types" "5.46.1" + eslint-visitor-keys "^3.3.0" + JSONStream@^1.0.3: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -3372,6 +3420,13 @@ eslint-plugin-import@^2.26.0: resolve "^1.22.0" tsconfig-paths "^3.14.1" +eslint-plugin-jest@^27.1.6: + version "27.1.6" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.1.6.tgz#361d943f07d1978838e6b852c44a579f3879e332" + integrity sha512-XA7RFLSrlQF9IGtAmhddkUkBuICCTuryfOTfCSWcZHiHb69OilIH05oozH2XA6CEOtztnOd0vgXyvxZodkxGjg== + dependencies: + "@typescript-eslint/utils" "^5.10.0" + eslint-plugin-jsdoc@^39.6.4: version "39.6.4" resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.6.4.tgz#b940aebd3eea26884a0d341785d2dc3aba6a38a7" From d24bfec2953b0486ec7f5f28576c373e3f57ec19 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 17:20:40 -0600 Subject: [PATCH 02/18] Fix jest/no-standalone-expect --- spec/TestClient.ts | 3 +++ spec/unit/utils.spec.ts | 2 ++ 2 files changed, 5 insertions(+) diff --git a/spec/TestClient.ts b/spec/TestClient.ts index 19a8d42c5e5..7c0533c2cc6 100644 --- a/spec/TestClient.ts +++ b/spec/TestClient.ts @@ -16,6 +16,9 @@ See the License for the specific language governing permissions and limitations under the License. */ +// `expect` is allowed in helper functions which are called within `test`/`it` blocks +/* eslint-disable jest/no-standalone-expect */ + // load olm before the sdk if possible import "./olm-loader"; diff --git a/spec/unit/utils.spec.ts b/spec/unit/utils.spec.ts index 8104cba0815..445d6ff9b27 100644 --- a/spec/unit/utils.spec.ts +++ b/spec/unit/utils.spec.ts @@ -129,9 +129,11 @@ describe("utils", function () { describe("deepCompare", function () { const assert = { isTrue: function (x: any) { + // eslint-disable-next-line jest/no-standalone-expect expect(x).toBe(true); }, isFalse: function (x: any) { + // eslint-disable-next-line jest/no-standalone-expect expect(x).toBe(false); }, }; From eb0e0c8caa2e91da5311a7bbaab29dff0ec51cb7 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 17:26:09 -0600 Subject: [PATCH 03/18] We have some disabled tests in the codebase for now --- .eslintrc.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index de90f681775..070dbdb6472 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -60,6 +60,9 @@ module.exports = { ], }, ], + // 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", }, overrides: [ { From 9d8f0c24a856a3c078c22ad573475f2ec839a768 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 17:27:59 -0600 Subject: [PATCH 04/18] Autofix --- spec/integ/matrix-client-retrying.spec.ts | 12 ++++---- spec/integ/matrix-client-syncing.spec.ts | 10 +++---- spec/integ/megolm-integ.spec.ts | 8 ++--- spec/integ/sliding-sync-sdk.spec.ts | 8 ++--- spec/unit/crypto.spec.ts | 4 +-- spec/unit/crypto/DeviceList.spec.ts | 2 +- spec/unit/crypto/algorithms/megolm.spec.ts | 2 +- spec/unit/crypto/cross-signing.spec.ts | 2 +- spec/unit/event-timeline-set.spec.ts | 4 +-- spec/unit/interactive-auth.spec.ts | 30 +++++++++---------- spec/unit/matrix-client.spec.ts | 10 +++---- spec/unit/rendezvous/ecdh.spec.ts | 4 +-- spec/unit/rendezvous/rendezvous.spec.ts | 6 ++-- .../rendezvous/simpleHttpTransport.spec.ts | 12 ++++---- spec/unit/webrtc/call.spec.ts | 2 +- spec/unit/webrtc/callFeed.spec.ts | 2 +- spec/unit/webrtc/groupCall.spec.ts | 2 +- spec/unit/webrtc/mediaHandler.spec.ts | 2 +- 18 files changed, 61 insertions(+), 61 deletions(-) diff --git a/spec/integ/matrix-client-retrying.spec.ts b/spec/integ/matrix-client-retrying.spec.ts index c890230b816..d62e968a0f7 100644 --- a/spec/integ/matrix-client-retrying.spec.ts +++ b/spec/integ/matrix-client-retrying.spec.ts @@ -48,13 +48,13 @@ describe("MatrixClient retrying", function () { return httpBackend!.stop(); }); - xit("should retry according to MatrixScheduler.retryFn", function () {}); + it.skip("should retry according to MatrixScheduler.retryFn", function () {}); - xit("should queue according to MatrixScheduler.queueFn", function () {}); + it.skip("should queue according to MatrixScheduler.queueFn", function () {}); - xit("should mark events as EventStatus.NOT_SENT when giving up", function () {}); + it.skip("should mark events as EventStatus.NOT_SENT when giving up", function () {}); - xit("should mark events as EventStatus.QUEUED when queued", function () {}); + it.skip("should mark events as EventStatus.QUEUED when queued", function () {}); it("should mark events as EventStatus.CANCELLED when cancelled", function () { // send a couple of events; the second will be queued @@ -130,7 +130,7 @@ describe("MatrixClient retrying", function () { }); describe("resending", function () { - xit("should be able to resend a NOT_SENT event", function () {}); - xit("should be able to resend a sent event", function () {}); + it.skip("should be able to resend a NOT_SENT event", function () {}); + it.skip("should be able to resend a sent event", function () {}); }); }); diff --git a/spec/integ/matrix-client-syncing.spec.ts b/spec/integ/matrix-client-syncing.spec.ts index 0f92dc60d95..51ae9180b49 100644 --- a/spec/integ/matrix-client-syncing.spec.ts +++ b/spec/integ/matrix-client-syncing.spec.ts @@ -724,7 +724,7 @@ describe("MatrixClient syncing", () => { // events that arrive in the incremental sync as if they preceeded the // timeline events, however this breaks peeking, so it's disabled // (see sync.js) - xit("should correctly interpret state in incremental sync.", () => { + it.skip("should correctly interpret state in incremental sync.", () => { httpBackend!.when("GET", "/sync").respond(200, syncData); httpBackend!.when("GET", "/sync").respond(200, nextSyncData); @@ -741,9 +741,9 @@ describe("MatrixClient syncing", () => { }); }); - xit("should update power levels for users in a room", () => {}); + it.skip("should update power levels for users in a room", () => {}); - xit("should update the room topic", () => {}); + it.skip("should update the room topic", () => {}); describe("onMarkerStateEvent", () => { const normalMessageEvent = utils.mkMessage({ @@ -1546,13 +1546,13 @@ describe("MatrixClient syncing", () => { }); describe("of a room", () => { - xit( + it.skip( "should sync when a join event (which changes state) for the user" + " arrives down the event stream (e.g. join from another device)", () => {}, ); - xit("should sync when the user explicitly calls joinRoom", () => {}); + it.skip("should sync when the user explicitly calls joinRoom", () => {}); }); describe("syncLeftRooms", () => { diff --git a/spec/integ/megolm-integ.spec.ts b/spec/integ/megolm-integ.spec.ts index 334800333a6..e8727560682 100644 --- a/spec/integ/megolm-integ.spec.ts +++ b/spec/integ/megolm-integ.spec.ts @@ -653,10 +653,10 @@ describe("megolm", () => { describe("get|setGlobalErrorOnUnknownDevices", () => { it("should raise an error if crypto is disabled", () => { aliceTestClient.client["cryptoBackend"] = undefined; - expect(() => aliceTestClient.client.setGlobalErrorOnUnknownDevices(true)).toThrowError( + expect(() => aliceTestClient.client.setGlobalErrorOnUnknownDevices(true)).toThrow( "encryption disabled", ); - expect(() => aliceTestClient.client.getGlobalErrorOnUnknownDevices()).toThrowError("encryption disabled"); + expect(() => aliceTestClient.client.getGlobalErrorOnUnknownDevices()).toThrow("encryption disabled"); }); it("should permit sending to unknown devices", async () => { @@ -709,10 +709,10 @@ describe("megolm", () => { describe("get|setGlobalBlacklistUnverifiedDevices", () => { it("should raise an error if crypto is disabled", () => { aliceTestClient.client["cryptoBackend"] = undefined; - expect(() => aliceTestClient.client.setGlobalBlacklistUnverifiedDevices(true)).toThrowError( + expect(() => aliceTestClient.client.setGlobalBlacklistUnverifiedDevices(true)).toThrow( "encryption disabled", ); - expect(() => aliceTestClient.client.getGlobalBlacklistUnverifiedDevices()).toThrowError( + expect(() => aliceTestClient.client.getGlobalBlacklistUnverifiedDevices()).toThrow( "encryption disabled", ); }); diff --git a/spec/integ/sliding-sync-sdk.spec.ts b/spec/integ/sliding-sync-sdk.spec.ts index 165e3142012..db8f716fa8a 100644 --- a/spec/integ/sliding-sync-sdk.spec.ts +++ b/spec/integ/sliding-sync-sdk.spec.ts @@ -153,11 +153,11 @@ describe("SlidingSyncSdk", () => { const hasSynced = sdk!.sync(); await httpBackend!.flushAllExpected(); await hasSynced; - expect(mockSlidingSync!.start).toBeCalled(); + expect(mockSlidingSync!.start).toHaveBeenCalled(); }); it("can stop()", async () => { sdk!.stop(); - expect(mockSlidingSync!.stop).toBeCalled(); + expect(mockSlidingSync!.stop).toHaveBeenCalled(); }); }); @@ -584,7 +584,7 @@ describe("SlidingSyncSdk", () => { }); it("emits SyncState.Error immediately when receiving M_UNKNOWN_TOKEN and stops syncing", async () => { - expect(mockSlidingSync!.stop).not.toBeCalled(); + expect(mockSlidingSync!.stop).not.toHaveBeenCalled(); mockSlidingSync!.emit( SlidingSyncEvent.Lifecycle, SlidingSyncState.RequestFinished, @@ -595,7 +595,7 @@ describe("SlidingSyncSdk", () => { }), ); expect(sdk!.getSyncState()).toEqual(SyncState.Error); - expect(mockSlidingSync!.stop).toBeCalled(); + expect(mockSlidingSync!.stop).toHaveBeenCalled(); }); }); diff --git a/spec/unit/crypto.spec.ts b/spec/unit/crypto.spec.ts index 3b7689ca0ce..ab8050f6e89 100644 --- a/spec/unit/crypto.spec.ts +++ b/spec/unit/crypto.spec.ts @@ -517,7 +517,7 @@ describe("Crypto", function () { aliceClient.crypto!.outgoingRoomKeyRequestManager.sendQueuedRequests(); jest.runAllTimers(); await Promise.resolve(); - expect(aliceSendToDevice).toBeCalledTimes(1); + expect(aliceSendToDevice).toHaveBeenCalledTimes(1); const txnId = aliceSendToDevice.mock.calls[0][2]; // give the room key request manager time to update the state @@ -531,7 +531,7 @@ describe("Crypto", function () { // cancelAndResend will call sendToDevice twice: // the first call to sendToDevice will be the cancellation // the second call to sendToDevice will be the key request - expect(aliceSendToDevice).toBeCalledTimes(3); + expect(aliceSendToDevice).toHaveBeenCalledTimes(3); expect(aliceSendToDevice.mock.calls[2][2]).not.toBe(txnId); }); diff --git a/spec/unit/crypto/DeviceList.spec.ts b/spec/unit/crypto/DeviceList.spec.ts index 39ba036a252..eeea1e76953 100644 --- a/spec/unit/crypto/DeviceList.spec.ts +++ b/spec/unit/crypto/DeviceList.spec.ts @@ -196,7 +196,7 @@ describe("DeviceList", function () { downloadSpy.mockReturnValueOnce(queryDefer2.promise); const prom1 = dl.refreshOutdatedDeviceLists(); - expect(downloadSpy).toBeCalledTimes(2); + expect(downloadSpy).toHaveBeenCalledTimes(2); expect(downloadSpy).toHaveBeenNthCalledWith(1, ["@test1:sw1v.org"], {}); expect(downloadSpy).toHaveBeenNthCalledWith(2, ["@test2:sw1v.org"], {}); queryDefer1.resolve(utils.deepCopy(signedDeviceList)); diff --git a/spec/unit/crypto/algorithms/megolm.spec.ts b/spec/unit/crypto/algorithms/megolm.spec.ts index 2dca6765d1c..c75b5acba05 100644 --- a/spec/unit/crypto/algorithms/megolm.spec.ts +++ b/spec/unit/crypto/algorithms/megolm.spec.ts @@ -203,7 +203,7 @@ describe("MegolmDecryption", function () { .then(() => { // check that it called encryptMessageForDevice with // appropriate args. - expect(mockOlmLib.encryptMessageForDevice).toBeCalledTimes(1); + expect(mockOlmLib.encryptMessageForDevice).toHaveBeenCalledTimes(1); const call = mockOlmLib.encryptMessageForDevice.mock.calls[0]; const payload = call[6]; diff --git a/spec/unit/crypto/cross-signing.spec.ts b/spec/unit/crypto/cross-signing.spec.ts index eddaf43ba4a..eeee27566d1 100644 --- a/spec/unit/crypto/cross-signing.spec.ts +++ b/spec/unit/crypto/cross-signing.spec.ts @@ -1148,6 +1148,6 @@ describe("userHasCrossSigningKeys", function () { it("throws an error if crypto is disabled", () => { aliceClient["cryptoBackend"] = undefined; - expect(() => aliceClient.userHasCrossSigningKeys()).toThrowError("encryption disabled"); + expect(() => aliceClient.userHasCrossSigningKeys()).toThrow("encryption disabled"); }); }); diff --git a/spec/unit/event-timeline-set.spec.ts b/spec/unit/event-timeline-set.spec.ts index 2831b6ca608..295bdf8c654 100644 --- a/spec/unit/event-timeline-set.spec.ts +++ b/spec/unit/event-timeline-set.spec.ts @@ -176,7 +176,7 @@ describe("EventTimelineSet", () => { eventTimelineSet.addEventToTimeline(messageEvent, liveTimeline2, { toStartOfTimeline: true, }); - }).toThrowError(); + }).toThrow(); }); it("should not add a threaded reply to the main room timeline", () => { @@ -314,7 +314,7 @@ describe("EventTimelineSet", () => { it("should throw if timeline set has no room", () => { const eventTimelineSet = new EventTimelineSet(undefined, {}, client); - expect(() => eventTimelineSet.canContain(messageEvent)).toThrowError(); + expect(() => eventTimelineSet.canContain(messageEvent)).toThrow(); }); it("should return false if timeline set is for thread but event is not threaded", () => { diff --git a/spec/unit/interactive-auth.spec.ts b/spec/unit/interactive-auth.spec.ts index 366a9a710c8..b301c49fc61 100644 --- a/spec/unit/interactive-auth.spec.ts +++ b/spec/unit/interactive-auth.spec.ts @@ -78,11 +78,11 @@ describe("InteractiveAuth", () => { const res = await ia.attemptAuth(); expect(res).toBe(requestRes); - expect(doRequest).toBeCalledTimes(1); - expect(stateUpdated).toBeCalledTimes(1); + expect(doRequest).toHaveBeenCalledTimes(1); + expect(stateUpdated).toHaveBeenCalledTimes(1); }); - it("should handle auth errcode presence ", async () => { + it("should handle auth errcode presence", async () => { const doRequest = jest.fn(); const stateUpdated = jest.fn(); @@ -128,8 +128,8 @@ describe("InteractiveAuth", () => { const res = await ia.attemptAuth(); expect(res).toBe(requestRes); - expect(doRequest).toBeCalledTimes(1); - expect(stateUpdated).toBeCalledTimes(1); + expect(doRequest).toHaveBeenCalledTimes(1); + expect(stateUpdated).toHaveBeenCalledTimes(1); }); it("should handle set emailSid for email flow", async () => { @@ -180,9 +180,9 @@ describe("InteractiveAuth", () => { const res = await ia.attemptAuth(); expect(res).toBe(requestRes); - expect(doRequest).toBeCalledTimes(1); - expect(stateUpdated).toBeCalledTimes(1); - expect(requestEmailToken).toBeCalledTimes(0); + expect(doRequest).toHaveBeenCalledTimes(1); + expect(stateUpdated).toHaveBeenCalledTimes(1); + expect(requestEmailToken).toHaveBeenCalledTimes(0); expect(ia.getEmailSid()).toBe("myEmailSid"); }); @@ -244,8 +244,8 @@ describe("InteractiveAuth", () => { const res = await ia.attemptAuth(); expect(res).toBe(requestRes); - expect(doRequest).toBeCalledTimes(2); - expect(stateUpdated).toBeCalledTimes(1); + expect(doRequest).toHaveBeenCalledTimes(2); + expect(stateUpdated).toHaveBeenCalledTimes(1); }); it("should make a request if authdata is null", async () => { @@ -306,8 +306,8 @@ describe("InteractiveAuth", () => { const res = await ia.attemptAuth(); expect(res).toBe(requestRes); - expect(doRequest).toBeCalledTimes(2); - expect(stateUpdated).toBeCalledTimes(1); + expect(doRequest).toHaveBeenCalledTimes(2); + expect(stateUpdated).toHaveBeenCalledTimes(1); }); it("should start an auth stage and reject if no auth flow", async () => { @@ -430,8 +430,8 @@ describe("InteractiveAuth", () => { const res = await ia.attemptAuth(); expect(res).toBe(requestRes); - expect(doRequest).toBeCalledTimes(1); - expect(stateUpdated).toBeCalledTimes(0); + expect(doRequest).toHaveBeenCalledTimes(1); + expect(stateUpdated).toHaveBeenCalledTimes(0); }); describe("requestEmailToken", () => { @@ -508,7 +508,7 @@ describe("InteractiveAuth", () => { requestEmailToken, }); - await expect(ia.requestEmailToken.bind(ia)).rejects.toThrowError("unspecific network error"); + await expect(ia.requestEmailToken.bind(ia)).rejects.toThrow("unspecific network error"); }); it("only starts one request at a time", async () => { diff --git a/spec/unit/matrix-client.spec.ts b/spec/unit/matrix-client.spec.ts index b13dfc125be..a5ed53159c2 100644 --- a/spec/unit/matrix-client.spec.ts +++ b/spec/unit/matrix-client.spec.ts @@ -806,7 +806,7 @@ describe("MatrixClient", function () { // Disabled because now `startClient` makes a legit call to `/versions` // And those tests are really unhappy about it... Not possible to figure // out what a good resolution would look like - xit("should transition ERROR -> CATCHUP after /sync if prev failed", function (done) { + it.skip("should transition ERROR -> CATCHUP after /sync if prev failed", function (done) { const expectedStates: [string, string | null][] = []; acceptKeepalives = false; httpLookups = []; @@ -848,7 +848,7 @@ describe("MatrixClient", function () { client.startClient(); }); - xit("should transition SYNCING -> ERROR after a failed /sync", function (done) { + it.skip("should transition SYNCING -> ERROR after a failed /sync", function (done) { acceptKeepalives = false; const expectedStates: [string, string | null][] = []; httpLookups.push({ @@ -870,7 +870,7 @@ describe("MatrixClient", function () { client.startClient(); }); - xit("should transition ERROR -> SYNCING after /sync if prev failed", function (done) { + it.skip("should transition ERROR -> SYNCING after /sync if prev failed", function (done) { const expectedStates: [string, string | null][] = []; httpLookups.push({ method: "GET", @@ -898,7 +898,7 @@ describe("MatrixClient", function () { client.startClient(); }); - xit("should transition ERROR -> ERROR if keepalive keeps failing", function (done) { + it.skip("should transition ERROR -> ERROR if keepalive keeps failing", function (done) { acceptKeepalives = false; const expectedStates: [string, string | null][] = []; httpLookups.push({ @@ -961,7 +961,7 @@ describe("MatrixClient", function () { expect(httpLookups.length).toBe(0); }); - xit("should be able to peek into a room using peekInRoom", function (done) {}); + it.skip("should be able to peek into a room using peekInRoom", function (done) {}); }); describe("getPresence", function () { diff --git a/spec/unit/rendezvous/ecdh.spec.ts b/spec/unit/rendezvous/ecdh.spec.ts index f0b2daa1da3..f088977f056 100644 --- a/spec/unit/rendezvous/ecdh.spec.ts +++ b/spec/unit/rendezvous/ecdh.spec.ts @@ -146,7 +146,7 @@ describe("ECDHv1", function () { // send a message without encryption await aliceTransport.send({ iv: "dummy", ciphertext: "dummy" }); - expect(bob.receive()).rejects.toThrowError(); + expect(bob.receive()).rejects.toThrow(); await alice.cancel(RendezvousFailureReason.Unknown); await bob.cancel(RendezvousFailureReason.Unknown); @@ -164,7 +164,7 @@ describe("ECDHv1", function () { await bobTransport.send({ iv: "dummy", ciphertext: "dummy" }); - expect(alice.receive()).rejects.toThrowError(); + expect(alice.receive()).rejects.toThrow(); await alice.cancel(RendezvousFailureReason.Unknown); }); diff --git a/spec/unit/rendezvous/rendezvous.spec.ts b/spec/unit/rendezvous/rendezvous.spec.ts index 8586040a626..1362335d5ac 100644 --- a/spec/unit/rendezvous/rendezvous.spec.ts +++ b/spec/unit/rendezvous/rendezvous.spec.ts @@ -570,7 +570,7 @@ describe("Rendezvous", function () { it("device not online within timeout", async function () { const { aliceRz } = await completeLogin({}); - expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrowError(); + expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrow(); }); it("device appears online within timeout", async function () { @@ -594,7 +594,7 @@ describe("Rendezvous", function () { getFingerprint: () => "bbbb", }; }, 1500); - expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrowError(); + expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrow(); }); it("mismatched device key", async function () { @@ -603,6 +603,6 @@ describe("Rendezvous", function () { getFingerprint: () => "XXXX", }, }); - expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrowError(/different key/); + expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrow(/different key/); }); }); diff --git a/spec/unit/rendezvous/simpleHttpTransport.spec.ts b/spec/unit/rendezvous/simpleHttpTransport.spec.ts index 69a38cbdeb5..36595e8a5d8 100644 --- a/spec/unit/rendezvous/simpleHttpTransport.spec.ts +++ b/spec/unit/rendezvous/simpleHttpTransport.spec.ts @@ -98,7 +98,7 @@ describe("SimpleHttpRendezvousTransport", function () { it("should throw an error when no server available", function () { const client = makeMockClient({ userId: "@alice:example.com", deviceId: "DEVICEID", msc3886Enabled: false }); const simpleHttpTransport = new MSC3886SimpleHttpRendezvousTransport({ client, fetchFn }); - expect(simpleHttpTransport.send({})).rejects.toThrowError("Invalid rendezvous URI"); + expect(simpleHttpTransport.send({})).rejects.toThrow("Invalid rendezvous URI"); }); it("POST to fallback server", async function () { @@ -130,7 +130,7 @@ describe("SimpleHttpRendezvousTransport", function () { fetchFn, }); const prom = simpleHttpTransport.send({}); - expect(prom).rejects.toThrowError(); + expect(prom).rejects.toThrow(); httpBackend.when("POST", "https://fallbackserver/rz").response = { body: null, response: { @@ -373,7 +373,7 @@ describe("SimpleHttpRendezvousTransport", function () { fallbackRzServer: "https://fallbackserver/rz", fetchFn, }); - expect(simpleHttpTransport.details()).rejects.toThrowError(); + expect(simpleHttpTransport.details()).rejects.toThrow(); }); it("send after cancelled", async function () { @@ -394,7 +394,7 @@ describe("SimpleHttpRendezvousTransport", function () { fallbackRzServer: "https://fallbackserver/rz", fetchFn, }); - expect(simpleHttpTransport.receive()).rejects.toThrowError(); + expect(simpleHttpTransport.receive()).rejects.toThrow(); }); it("404 failure callback", async function () { @@ -416,7 +416,7 @@ describe("SimpleHttpRendezvousTransport", function () { }, }; await httpBackend.flush("", 1); - expect(onFailure).toBeCalledWith(RendezvousFailureReason.Unknown); + expect(onFailure).toHaveBeenCalledWith(RendezvousFailureReason.Unknown); }); it("404 failure callback mapped to expired", async function () { @@ -456,7 +456,7 @@ describe("SimpleHttpRendezvousTransport", function () { }, }; await httpBackend.flush(""); - expect(onFailure).toBeCalledWith(RendezvousFailureReason.Expired); + expect(onFailure).toHaveBeenCalledWith(RendezvousFailureReason.Expired); } }); }); diff --git a/spec/unit/webrtc/call.spec.ts b/spec/unit/webrtc/call.spec.ts index 9ddf880aba9..dc1895b6559 100644 --- a/spec/unit/webrtc/call.spec.ts +++ b/spec/unit/webrtc/call.spec.ts @@ -1521,7 +1521,7 @@ describe("Call", function () { hasAdvancedBy += advanceBy; expect(lengthChangedListener).toHaveBeenCalledTimes(hasAdvancedBy); - expect(lengthChangedListener).toBeCalledWith(hasAdvancedBy); + expect(lengthChangedListener).toHaveBeenCalledWith(hasAdvancedBy); } }); diff --git a/spec/unit/webrtc/callFeed.spec.ts b/spec/unit/webrtc/callFeed.spec.ts index e14a1a0c56b..803e4648ed6 100644 --- a/spec/unit/webrtc/callFeed.spec.ts +++ b/spec/unit/webrtc/callFeed.spec.ts @@ -73,7 +73,7 @@ describe("CallFeed", () => { }); describe("muting after calling setAudioVideoMuted()", () => { - it("should mute audio by default ", () => { + it("should mute audio by default", () => { // @ts-ignore Mock feed.stream.addTrack(new MockMediaStreamTrack("track", "audio", true)); feed.setAudioVideoMuted(true, false); diff --git a/spec/unit/webrtc/groupCall.spec.ts b/spec/unit/webrtc/groupCall.spec.ts index 59cdbac129d..5fd117e4125 100644 --- a/spec/unit/webrtc/groupCall.spec.ts +++ b/spec/unit/webrtc/groupCall.spec.ts @@ -329,7 +329,7 @@ describe("Group Call", function () { jest.spyOn(call, "getOpponentMember").mockReturnValue({ userId: undefined }); // @ts-ignore Mock - expect(() => groupCall.onCallFeedsChanged(call)).toThrowError(); + expect(() => groupCall.onCallFeedsChanged(call)).toThrow(); }); describe("usermedia feeds", () => { diff --git a/spec/unit/webrtc/mediaHandler.spec.ts b/spec/unit/webrtc/mediaHandler.spec.ts index 8a595cdc0a9..aa9cb047362 100644 --- a/spec/unit/webrtc/mediaHandler.spec.ts +++ b/spec/unit/webrtc/mediaHandler.spec.ts @@ -48,7 +48,7 @@ describe("Media Handler", function () { } as unknown as MatrixClient); }); - it("does not trigger update after restore media settings ", () => { + it("does not trigger update after restore media settings", () => { mediaHandler.restoreMediaSettings(FAKE_AUDIO_INPUT_ID, FAKE_VIDEO_INPUT_ID); expect(mockMediaDevices.getUserMedia).not.toHaveBeenCalled(); From 11fc920e7300dd335d403578c63eb91fa1d6163f Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 19:06:01 -0600 Subject: [PATCH 05/18] Fix jest/no-done-callback --- .../integ/matrix-client-event-emitter.spec.ts | 8 +- spec/integ/matrix-client-methods.spec.ts | 42 ++-- spec/integ/matrix-client-opts.spec.ts | 54 +++-- .../integ/matrix-client-room-timeline.spec.ts | 211 +++++++++--------- spec/integ/matrix-client-syncing.spec.ts | 27 +-- spec/unit/matrix-client.spec.ts | 173 ++++++++------ spec/unit/scheduler.spec.ts | 19 +- 7 files changed, 272 insertions(+), 262 deletions(-) diff --git a/spec/integ/matrix-client-event-emitter.spec.ts b/spec/integ/matrix-client-event-emitter.spec.ts index 7e949f08a77..397ebd824b1 100644 --- a/spec/integ/matrix-client-event-emitter.spec.ts +++ b/spec/integ/matrix-client-event-emitter.spec.ts @@ -175,7 +175,7 @@ describe("MatrixClient events", function () { }); }); - it("should emit User events", function (done) { + it("should emit User events", async () => { httpBackend!.when("GET", "/sync").respond(200, SYNC_DATA); httpBackend!.when("GET", "/sync").respond(200, NEXT_SYNC_DATA); let fired = false; @@ -192,10 +192,8 @@ describe("MatrixClient events", function () { }); client!.startClient(); - httpBackend!.flushAllExpected().then(function () { - expect(fired).toBe(true); - done(); - }); + await httpBackend!.flushAllExpected(); + expect(fired).toBe(true); }); it("should emit Room events", function () { diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index c83ada2d597..6e52545ae96 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -207,19 +207,17 @@ describe("MatrixClient", function () { describe("getFilter", function () { const filterId = "f1lt3r1d"; - it("should return a filter from the store if allowCached", function (done) { + it("should return a filter from the store if allowCached", async () => { const filter = Filter.fromJson(userId, filterId, { event_format: "client", }); store!.storeFilter(filter); - client!.getFilter(userId, filterId, true).then(function (gotFilter) { - expect(gotFilter).toEqual(filter); - done(); - }); + const gotFilter = await client!.getFilter(userId, filterId, true); + expect(gotFilter).toEqual(filter); httpBackend!.verifyNoOutstandingRequests(); }); - it("should do an HTTP request if !allowCached even if one exists", function (done) { + it("should do an HTTP request if !allowCached even if one exists", async () => { const httpFilterDefinition = { event_format: "federation", }; @@ -232,15 +230,11 @@ describe("MatrixClient", function () { event_format: "client", }); store!.storeFilter(storeFilter); - client!.getFilter(userId, filterId, false).then(function (gotFilter) { - expect(gotFilter.getDefinition()).toEqual(httpFilterDefinition); - done(); - }); - - httpBackend!.flush(""); + const [gotFilter] = await Promise.all([client!.getFilter(userId, filterId, false), httpBackend!.flush("")]); + expect(gotFilter.getDefinition()).toEqual(httpFilterDefinition); }); - it("should do an HTTP request if nothing is in the cache and then store it", function (done) { + it("should do an HTTP request if nothing is in the cache and then store it", async () => { const httpFilterDefinition = { event_format: "federation", }; @@ -249,20 +243,16 @@ describe("MatrixClient", function () { httpBackend! .when("GET", "/user/" + encodeURIComponent(userId) + "/filter/" + filterId) .respond(200, httpFilterDefinition); - client!.getFilter(userId, filterId, true).then(function (gotFilter) { - expect(gotFilter.getDefinition()).toEqual(httpFilterDefinition); - expect(store!.getFilter(userId, filterId)).toBeTruthy(); - done(); - }); - - httpBackend!.flush(""); + const [gotFilter] = await Promise.all([client!.getFilter(userId, filterId, true), httpBackend!.flush("")]); + expect(gotFilter.getDefinition()).toEqual(httpFilterDefinition); + expect(store!.getFilter(userId, filterId)).toBeTruthy(); }); }); describe("createFilter", function () { const filterId = "f1llllllerid"; - it("should do an HTTP request and then store the filter", function (done) { + it("should do an HTTP request and then store the filter", async () => { expect(store!.getFilter(userId, filterId)).toBe(null); const filterDefinition = { @@ -278,13 +268,9 @@ describe("MatrixClient", function () { filter_id: filterId, }); - client!.createFilter(filterDefinition).then(function (gotFilter) { - expect(gotFilter.getDefinition()).toEqual(filterDefinition); - expect(store!.getFilter(userId, filterId)).toEqual(gotFilter); - done(); - }); - - httpBackend!.flush(""); + const [gotFilter] = await Promise.all([client!.createFilter(filterDefinition), httpBackend!.flush("")]); + expect(gotFilter.getDefinition()).toEqual(filterDefinition); + expect(store!.getFilter(userId, filterId)).toEqual(gotFilter); }); }); diff --git a/spec/integ/matrix-client-opts.spec.ts b/spec/integ/matrix-client-opts.spec.ts index 328152a208e..eb381cabcb0 100644 --- a/spec/integ/matrix-client-opts.spec.ts +++ b/spec/integ/matrix-client-opts.spec.ts @@ -94,16 +94,16 @@ describe("MatrixClient opts", function () { client.stopClient(); }); - it("should be able to send messages", function (done) { + it("should be able to send messages", async () => { const eventId = "$flibble:wibble"; httpBackend.when("PUT", "/txn1").respond(200, { event_id: eventId, }); - client.sendTextMessage("!foo:bar", "a body", "txn1").then(function (res) { - expect(res.event_id).toEqual(eventId); - done(); - }); - httpBackend.flush("/txn1", 1); + const [res] = await Promise.all([ + client.sendTextMessage("!foo:bar", "a body", "txn1"), + httpBackend.flush("/txn1", 1), + ]); + expect(res.event_id).toEqual(eventId); }); it("should be able to sync / get new events", async function () { @@ -149,7 +149,7 @@ describe("MatrixClient opts", function () { client.stopClient(); }); - it("shouldn't retry sending events", function (done) { + it("shouldn't retry sending events", async () => { httpBackend.when("PUT", "/txn1").respond( 500, new MatrixError({ @@ -157,19 +157,17 @@ describe("MatrixClient opts", function () { error: "Ruh roh", }), ); - client.sendTextMessage("!foo:bar", "a body", "txn1").then( - function (res) { - expect(false).toBe(true); - }, - function (err) { - expect(err.errcode).toEqual("M_SOMETHING"); - done(); - }, - ); - httpBackend.flush("/txn1", 1); + try { + await Promise.all([ + expect(client.sendTextMessage("!foo:bar", "a body", "txn1")).rejects.toThrow(), + httpBackend.flush("/txn1", 1), + ]); + } catch (err) { + expect((err).errcode).toEqual("M_SOMETHING"); + } }); - it("shouldn't queue events", function (done) { + it("shouldn't queue events", async () => { httpBackend.when("PUT", "/txn1").respond(200, { event_id: "AAA", }); @@ -186,22 +184,20 @@ describe("MatrixClient opts", function () { sentB = true; expect(sentA).toBe(false); }); - httpBackend.flush("/txn2", 1).then(function () { - httpBackend.flush("/txn1", 1).then(function () { - done(); - }); - }); + await httpBackend.flush("/txn2", 1); + await httpBackend.flush("/txn1", 1); }); - it("should be able to send messages", function (done) { + it("should be able to send messages", async () => { httpBackend.when("PUT", "/txn1").respond(200, { event_id: "foo", }); - client.sendTextMessage("!foo:bar", "a body", "txn1").then(function (res) { - expect(res.event_id).toEqual("foo"); - done(); - }); - httpBackend.flush("/txn1", 1); + const [res] = await Promise.all([ + client.sendTextMessage("!foo:bar", "a body", "txn1"), + httpBackend.flush("/txn1", 1), + ]); + + expect(res.event_id).toEqual("foo"); }); }); }); diff --git a/spec/integ/matrix-client-room-timeline.spec.ts b/spec/integ/matrix-client-room-timeline.spec.ts index 8d7bcba2e23..e3f62457c24 100644 --- a/spec/integ/matrix-client-room-timeline.spec.ts +++ b/spec/integ/matrix-client-room-timeline.spec.ts @@ -163,36 +163,38 @@ describe("MatrixClient room timelines", function () { it( "should be added immediately after calling MatrixClient.sendEvent " + "with EventStatus.SENDING and the right event.sender", - function (done) { - client!.on(ClientEvent.Sync, function (state) { - if (state !== "PREPARED") { - return; - } - const room = client!.getRoom(roomId)!; - expect(room.timeline.length).toEqual(1); - - client!.sendTextMessage(roomId, "I am a fish", "txn1"); - // check it was added - expect(room.timeline.length).toEqual(2); - // check status - expect(room.timeline[1].status).toEqual(EventStatus.SENDING); - // check member - const member = room.timeline[1].sender; - expect(member?.userId).toEqual(userId); - expect(member?.name).toEqual(userName); - - httpBackend!.flush("/sync", 1).then(function () { - done(); + async () => { + const wasMessageAddedPromise = new Promise((resolve) => { + client!.on(ClientEvent.Sync, async (state) => { + if (state !== "PREPARED") { + return; + } + const room = client!.getRoom(roomId)!; + expect(room.timeline.length).toEqual(1); + + client!.sendTextMessage(roomId, "I am a fish", "txn1"); + // check it was added + expect(room.timeline.length).toEqual(2); + // check status + expect(room.timeline[1].status).toEqual(EventStatus.SENDING); + // check member + const member = room.timeline[1].sender; + expect(member?.userId).toEqual(userId); + expect(member?.name).toEqual(userName); + + await httpBackend!.flush("/sync", 1); + resolve(null); }); }); - httpBackend!.flush("/sync", 1); + await httpBackend!.flush("/sync", 1); + await wasMessageAddedPromise; }, ); it( "should be updated correctly when the send request finishes " + "BEFORE the event comes down the event stream", - function (done) { + async () => { const eventId = "$foo:bar"; httpBackend!.when("PUT", "/txn1").respond(200, { event_id: eventId, @@ -207,28 +209,30 @@ describe("MatrixClient room timelines", function () { ev.unsigned = { transaction_id: "txn1" }; setNextSyncData([ev]); - client!.on(ClientEvent.Sync, function (state) { - if (state !== "PREPARED") { - return; - } - const room = client!.getRoom(roomId)!; - client!.sendTextMessage(roomId, "I am a fish", "txn1").then(function () { - expect(room.timeline[1].getId()).toEqual(eventId); - httpBackend!.flush("/sync", 1).then(function () { + const wasMessageAddedPromise = new Promise((resolve) => { + client!.on(ClientEvent.Sync, function (state) { + if (state !== "PREPARED") { + return; + } + const room = client!.getRoom(roomId)!; + client!.sendTextMessage(roomId, "I am a fish", "txn1").then(async () => { expect(room.timeline[1].getId()).toEqual(eventId); - done(); + await httpBackend!.flush("/sync", 1); + expect(room.timeline[1].getId()).toEqual(eventId); + resolve(null); }); + httpBackend!.flush("/txn1", 1); }); - httpBackend!.flush("/txn1", 1); }); - httpBackend!.flush("/sync", 1); + await httpBackend!.flush("/sync", 1); + await wasMessageAddedPromise; }, ); it( "should be updated correctly when the send request finishes " + "AFTER the event comes down the event stream", - function (done) { + async () => { const eventId = "$foo:bar"; httpBackend!.when("PUT", "/txn1").respond(200, { event_id: eventId, @@ -243,23 +247,24 @@ describe("MatrixClient room timelines", function () { ev.unsigned = { transaction_id: "txn1" }; setNextSyncData([ev]); - client!.on(ClientEvent.Sync, function (state) { - if (state !== "PREPARED") { - return; - } - const room = client!.getRoom(roomId)!; - const promise = client!.sendTextMessage(roomId, "I am a fish", "txn1"); - httpBackend!.flush("/sync", 1).then(function () { + const wasMessageAddedPromise = new Promise((resolve) => { + client!.on(ClientEvent.Sync, async (state) => { + if (state !== "PREPARED") { + return; + } + const room = client!.getRoom(roomId)!; + const messageSendPromise = client!.sendTextMessage(roomId, "I am a fish", "txn1"); + await httpBackend!.flush("/sync", 1); expect(room.timeline.length).toEqual(2); httpBackend!.flush("/txn1", 1); - promise.then(function () { - expect(room.timeline.length).toEqual(2); - expect(room.timeline[1].getId()).toEqual(eventId); - done(); - }); + await messageSendPromise; + expect(room.timeline.length).toEqual(2); + expect(room.timeline[1].getId()).toEqual(eventId); + resolve(null); }); }); - httpBackend!.flush("/sync", 1); + await httpBackend!.flush("/sync", 1); + await wasMessageAddedPromise; }, ); }); @@ -279,30 +284,29 @@ describe("MatrixClient room timelines", function () { }); }); - it("should set Room.oldState.paginationToken to null at the start" + " of the timeline.", function (done) { - client!.on(ClientEvent.Sync, function (state) { - if (state !== "PREPARED") { - return; - } - const room = client!.getRoom(roomId)!; - expect(room.timeline.length).toEqual(1); + it("should set Room.oldState.paginationToken to null at the start of the timeline.", async () => { + const didPaginatePromise = new Promise((resolve) => { + client!.on(ClientEvent.Sync, async (state) => { + if (state !== "PREPARED") { + return; + } + const room = client!.getRoom(roomId)!; + expect(room.timeline.length).toEqual(1); - client!.scrollback(room).then(function () { + await Promise.all([client!.scrollback(room), httpBackend!.flush("/messages", 1)]); expect(room.timeline.length).toEqual(1); expect(room.oldState.paginationToken).toBe(null); // still have a sync to flush - httpBackend!.flush("/sync", 1).then(() => { - done(); - }); + await httpBackend!.flush("/sync", 1); + resolve(null); }); - - httpBackend!.flush("/messages", 1); }); - httpBackend!.flush("/sync", 1); + await httpBackend!.flush("/sync", 1); + await didPaginatePromise; }); - it("should set the right event.sender values", function (done) { + it("should set the right event.sender values", async () => { // We're aiming for an eventual timeline of: // // 'Old Alice' joined the room @@ -353,15 +357,17 @@ describe("MatrixClient room timelines", function () { joinMshipEvent, ]; - client!.on(ClientEvent.Sync, function (state) { - if (state !== "PREPARED") { - return; - } - const room = client!.getRoom(roomId)!; - // sync response - expect(room.timeline.length).toEqual(1); + const didPaginatePromise = new Promise((resolve) => { + client!.on(ClientEvent.Sync, async (state) => { + if (state !== "PREPARED") { + return; + } + const room = client!.getRoom(roomId)!; + // sync response + expect(room.timeline.length).toEqual(1); + + await Promise.all([client!.scrollback(room), httpBackend!.flush("/messages", 1)]); - client!.scrollback(room).then(function () { expect(room.timeline.length).toEqual(5); const joinMsg = room.timeline[0]; expect(joinMsg.sender?.name).toEqual("Old Alice"); @@ -371,17 +377,15 @@ describe("MatrixClient room timelines", function () { expect(newMsg.sender?.name).toEqual(userName); // still have a sync to flush - httpBackend!.flush("/sync", 1).then(() => { - done(); - }); + await httpBackend!.flush("/sync", 1); + resolve(null); }); - - httpBackend!.flush("/messages", 1); }); - httpBackend!.flush("/sync", 1); + await httpBackend!.flush("/sync", 1); + await didPaginatePromise; }); - it("should add it them to the right place in the timeline", function (done) { + it("should add it them to the right place in the timeline", async () => { // set the list of events to return on scrollback sbEvents = [ utils.mkMessage({ @@ -396,30 +400,30 @@ describe("MatrixClient room timelines", function () { }), ]; - client!.on(ClientEvent.Sync, function (state) { - if (state !== "PREPARED") { - return; - } - const room = client!.getRoom(roomId)!; - expect(room.timeline.length).toEqual(1); + const didPaginatePromise = new Promise((resolve) => { + client!.on(ClientEvent.Sync, async (state) => { + if (state !== "PREPARED") { + return; + } + const room = client!.getRoom(roomId)!; + expect(room.timeline.length).toEqual(1); + + await Promise.all([client!.scrollback(room), httpBackend!.flush("/messages", 1)]); - client!.scrollback(room).then(function () { expect(room.timeline.length).toEqual(3); expect(room.timeline[0].event).toEqual(sbEvents[1]); expect(room.timeline[1].event).toEqual(sbEvents[0]); // still have a sync to flush - httpBackend!.flush("/sync", 1).then(() => { - done(); - }); + await httpBackend!.flush("/sync", 1); + resolve(null); }); - - httpBackend!.flush("/messages", 1); }); - httpBackend!.flush("/sync", 1); + await httpBackend!.flush("/sync", 1); + await didPaginatePromise; }); - it("should use 'end' as the next pagination token", function (done) { + it("should use 'end' as the next pagination token", async () => { // set the list of events to return on scrollback sbEvents = [ utils.mkMessage({ @@ -429,25 +433,24 @@ describe("MatrixClient room timelines", function () { }), ]; - client!.on(ClientEvent.Sync, function (state) { - if (state !== "PREPARED") { - return; - } - const room = client!.getRoom(roomId)!; - expect(room.oldState.paginationToken).toBeTruthy(); + const didPaginatePromise = new Promise((resolve) => { + client!.on(ClientEvent.Sync, async (state) => { + if (state !== "PREPARED") { + return; + } + const room = client!.getRoom(roomId)!; + expect(room.oldState.paginationToken).toBeTruthy(); - client!.scrollback(room, 1).then(function () { + await Promise.all([client!.scrollback(room, 1), httpBackend!.flush("/messages", 1)]); expect(room.oldState.paginationToken).toEqual(sbEndTok); - }); - httpBackend!.flush("/messages", 1).then(function () { // still have a sync to flush - httpBackend!.flush("/sync", 1).then(() => { - done(); - }); + await httpBackend!.flush("/sync", 1); + resolve(null); }); }); - httpBackend!.flush("/sync", 1); + await httpBackend!.flush("/sync", 1); + await didPaginatePromise; }); }); diff --git a/spec/integ/matrix-client-syncing.spec.ts b/spec/integ/matrix-client-syncing.spec.ts index 51ae9180b49..b932985b104 100644 --- a/spec/integ/matrix-client-syncing.spec.ts +++ b/spec/integ/matrix-client-syncing.spec.ts @@ -81,17 +81,15 @@ describe("MatrixClient syncing", () => { presence: {}, }; - it("should /sync after /pushrules and /filter.", (done) => { + it("should /sync after /pushrules and /filter.", async () => { httpBackend!.when("GET", "/sync").respond(200, syncData); client!.startClient(); - httpBackend!.flushAllExpected().then(() => { - done(); - }); + await httpBackend!.flushAllExpected(); }); - it("should pass the 'next_batch' token from /sync to the since= param of the next /sync", (done) => { + it("should pass the 'next_batch' token from /sync to the since= param of the next /sync", async () => { httpBackend!.when("GET", "/sync").respond(200, syncData); httpBackend! .when("GET", "/sync") @@ -102,9 +100,7 @@ describe("MatrixClient syncing", () => { client!.startClient(); - httpBackend!.flushAllExpected().then(() => { - done(); - }); + await httpBackend!.flushAllExpected(); }); it("should emit RoomEvent.MyMembership for invite->leave->invite cycles", async () => { @@ -1556,17 +1552,14 @@ describe("MatrixClient syncing", () => { }); describe("syncLeftRooms", () => { - beforeEach((done) => { + beforeEach(async () => { client!.startClient(); - httpBackend!.flushAllExpected().then(() => { - // the /sync call from syncLeftRooms ends up in the request - // queue behind the call from the running client; add a response - // to flush the client's one out. - httpBackend!.when("GET", "/sync").respond(200, {}); - - done(); - }); + await httpBackend!.flushAllExpected(); + // the /sync call from syncLeftRooms ends up in the request + // queue behind the call from the running client; add a response + // to flush the client's one out. + await httpBackend!.when("GET", "/sync").respond(200, {}); }); it("should create and use an appropriate filter", () => { diff --git a/spec/unit/matrix-client.spec.ts b/spec/unit/matrix-client.spec.ts index a5ed53159c2..ebc8a6a21c7 100644 --- a/spec/unit/matrix-client.spec.ts +++ b/spec/unit/matrix-client.spec.ts @@ -640,7 +640,7 @@ describe("MatrixClient", function () { describe("getOrCreateFilter", function () { it("should POST createFilter if no id is present in localStorage", function () {}); it("should use an existing filter if id is present in localStorage", function () {}); - it("should handle localStorage filterId missing from the server", function (done) { + it("should handle localStorage filterId missing from the server", async () => { function getFilterName(userId: string, suffix?: string) { // scope this on the user ID because people may login on many accounts // and they all need to be stored! @@ -666,10 +666,8 @@ describe("MatrixClient", function () { client.store.setFilterIdByName(filterName, invalidFilterId); const filter = new Filter(client.credentials.userId); - client.getOrCreateFilter(filterName, filter).then(function (filterId) { - expect(filterId).toEqual(FILTER_RESPONSE.data?.filter_id); - done(); - }); + const filterId = await client.getOrCreateFilter(filterName, filter); + expect(filterId).toEqual(FILTER_RESPONSE.data?.filter_id); }); }); @@ -680,7 +678,7 @@ describe("MatrixClient", function () { expect(client.retryImmediately()).toBe(false); }); - it("should work on /filter", function (done) { + it("should work on /filter", async () => { httpLookups = []; httpLookups.push(PUSH_RULES_RESPONSE); httpLookups.push({ @@ -691,23 +689,26 @@ describe("MatrixClient", function () { httpLookups.push(FILTER_RESPONSE); httpLookups.push(SYNC_RESPONSE); - client.on(ClientEvent.Sync, function syncListener(state) { - if (state === "ERROR" && httpLookups.length > 0) { - expect(httpLookups.length).toEqual(2); - expect(client.retryImmediately()).toBe(true); - jest.advanceTimersByTime(1); - } else if (state === "PREPARED" && httpLookups.length === 0) { - client.removeListener(ClientEvent.Sync, syncListener); - done(); - } else { - // unexpected state transition! - expect(state).toEqual(null); - } + const wasPreparedPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, function syncListener(state) { + if (state === "ERROR" && httpLookups.length > 0) { + expect(httpLookups.length).toEqual(2); + expect(client.retryImmediately()).toBe(true); + jest.advanceTimersByTime(1); + } else if (state === "PREPARED" && httpLookups.length === 0) { + client.removeListener(ClientEvent.Sync, syncListener); + resolve(null); + } else { + // unexpected state transition! + expect(state).toEqual(null); + } + }); }); - client.startClient(); + await client.startClient(); + await wasPreparedPromise; }); - it("should work on /sync", function (done) { + it("should work on /sync", async () => { httpLookups.push({ method: "GET", path: "/sync", @@ -719,22 +720,25 @@ describe("MatrixClient", function () { data: SYNC_DATA, }); - client.on(ClientEvent.Sync, function syncListener(state) { - if (state === "ERROR" && httpLookups.length > 0) { - expect(httpLookups.length).toEqual(1); - expect(client.retryImmediately()).toBe(true); - jest.advanceTimersByTime(1); - } else if (state === "RECONNECTING" && httpLookups.length > 0) { - jest.advanceTimersByTime(10000); - } else if (state === "SYNCING" && httpLookups.length === 0) { - client.removeListener(ClientEvent.Sync, syncListener); - done(); - } + const isSyncingPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, function syncListener(state) { + if (state === "ERROR" && httpLookups.length > 0) { + expect(httpLookups.length).toEqual(1); + expect(client.retryImmediately()).toBe(true); + jest.advanceTimersByTime(1); + } else if (state === "RECONNECTING" && httpLookups.length > 0) { + jest.advanceTimersByTime(10000); + } else if (state === "SYNCING" && httpLookups.length === 0) { + client.removeListener(ClientEvent.Sync, syncListener); + resolve(null); + } + }); }); - client.startClient(); + await client.startClient(); + await isSyncingPromise; }); - it("should work on /pushrules", function (done) { + it("should work on /pushrules", async () => { httpLookups = []; httpLookups.push({ method: "GET", @@ -745,20 +749,23 @@ describe("MatrixClient", function () { httpLookups.push(FILTER_RESPONSE); httpLookups.push(SYNC_RESPONSE); - client.on(ClientEvent.Sync, function syncListener(state) { - if (state === "ERROR" && httpLookups.length > 0) { - expect(httpLookups.length).toEqual(3); - expect(client.retryImmediately()).toBe(true); - jest.advanceTimersByTime(1); - } else if (state === "PREPARED" && httpLookups.length === 0) { - client.removeListener(ClientEvent.Sync, syncListener); - done(); - } else { - // unexpected state transition! - expect(state).toEqual(null); - } + const wasPreparedPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, function syncListener(state) { + if (state === "ERROR" && httpLookups.length > 0) { + expect(httpLookups.length).toEqual(3); + expect(client.retryImmediately()).toBe(true); + jest.advanceTimersByTime(1); + } else if (state === "PREPARED" && httpLookups.length === 0) { + client.removeListener(ClientEvent.Sync, syncListener); + resolve(null); + } else { + // unexpected state transition! + expect(state).toEqual(null); + } + }); }); - client.startClient(); + await client.startClient(); + await wasPreparedPromise; }); }); @@ -782,14 +789,17 @@ describe("MatrixClient", function () { }; } - it("should transition null -> PREPARED after the first /sync", function (done) { + it("should transition null -> PREPARED after the first /sync", async () => { const expectedStates: [string, string | null][] = []; expectedStates.push(["PREPARED", null]); - client.on(ClientEvent.Sync, syncChecker(expectedStates, done)); - client.startClient(); + const didSyncPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, syncChecker(expectedStates, resolve)); + }); + await client.startClient(); + await didSyncPromise; }); - it("should transition null -> ERROR after a failed /filter", function (done) { + it("should transition null -> ERROR after a failed /filter", async () => { const expectedStates: [string, string | null][] = []; httpLookups = []; httpLookups.push(PUSH_RULES_RESPONSE); @@ -799,14 +809,17 @@ describe("MatrixClient", function () { error: { errcode: "NOPE_NOPE_NOPE" }, }); expectedStates.push(["ERROR", null]); - client.on(ClientEvent.Sync, syncChecker(expectedStates, done)); - client.startClient(); + const didSyncPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, syncChecker(expectedStates, resolve)); + }); + await client.startClient(); + await didSyncPromise; }); // Disabled because now `startClient` makes a legit call to `/versions` // And those tests are really unhappy about it... Not possible to figure // out what a good resolution would look like - it.skip("should transition ERROR -> CATCHUP after /sync if prev failed", function (done) { + it.skip("should transition ERROR -> CATCHUP after /sync if prev failed", async () => { const expectedStates: [string, string | null][] = []; acceptKeepalives = false; httpLookups = []; @@ -836,19 +849,25 @@ describe("MatrixClient", function () { expectedStates.push(["RECONNECTING", null]); expectedStates.push(["ERROR", "RECONNECTING"]); expectedStates.push(["CATCHUP", "ERROR"]); - client.on(ClientEvent.Sync, syncChecker(expectedStates, done)); - client.startClient(); + const didSyncPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, syncChecker(expectedStates, resolve)); + }); + await client.startClient(); + await didSyncPromise; }); - it("should transition PREPARED -> SYNCING after /sync", function (done) { + it("should transition PREPARED -> SYNCING after /sync", async () => { const expectedStates: [string, string | null][] = []; expectedStates.push(["PREPARED", null]); expectedStates.push(["SYNCING", "PREPARED"]); - client.on(ClientEvent.Sync, syncChecker(expectedStates, done)); - client.startClient(); + const didSyncPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, syncChecker(expectedStates, resolve)); + }); + await client.startClient(); + await didSyncPromise; }); - it.skip("should transition SYNCING -> ERROR after a failed /sync", function (done) { + it.skip("should transition SYNCING -> ERROR after a failed /sync", async () => { acceptKeepalives = false; const expectedStates: [string, string | null][] = []; httpLookups.push({ @@ -866,11 +885,14 @@ describe("MatrixClient", function () { expectedStates.push(["SYNCING", "PREPARED"]); expectedStates.push(["RECONNECTING", "SYNCING"]); expectedStates.push(["ERROR", "RECONNECTING"]); - client.on(ClientEvent.Sync, syncChecker(expectedStates, done)); - client.startClient(); + const didSyncPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, syncChecker(expectedStates, resolve)); + }); + await client.startClient(); + await didSyncPromise; }); - it.skip("should transition ERROR -> SYNCING after /sync if prev failed", function (done) { + it.skip("should transition ERROR -> SYNCING after /sync if prev failed", async () => { const expectedStates: [string, string | null][] = []; httpLookups.push({ method: "GET", @@ -882,11 +904,14 @@ describe("MatrixClient", function () { expectedStates.push(["PREPARED", null]); expectedStates.push(["SYNCING", "PREPARED"]); expectedStates.push(["ERROR", "SYNCING"]); - client.on(ClientEvent.Sync, syncChecker(expectedStates, done)); - client.startClient(); + const didSyncPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, syncChecker(expectedStates, resolve)); + }); + await client.startClient(); + await didSyncPromise; }); - it("should transition SYNCING -> SYNCING on subsequent /sync successes", function (done) { + it("should transition SYNCING -> SYNCING on subsequent /sync successes", async () => { const expectedStates: [string, string | null][] = []; httpLookups.push(SYNC_RESPONSE); httpLookups.push(SYNC_RESPONSE); @@ -894,11 +919,14 @@ describe("MatrixClient", function () { expectedStates.push(["PREPARED", null]); expectedStates.push(["SYNCING", "PREPARED"]); expectedStates.push(["SYNCING", "SYNCING"]); - client.on(ClientEvent.Sync, syncChecker(expectedStates, done)); - client.startClient(); + const didSyncPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, syncChecker(expectedStates, resolve)); + }); + await client.startClient(); + await didSyncPromise; }); - it.skip("should transition ERROR -> ERROR if keepalive keeps failing", function (done) { + it.skip("should transition ERROR -> ERROR if keepalive keeps failing", async () => { acceptKeepalives = false; const expectedStates: [string, string | null][] = []; httpLookups.push({ @@ -922,8 +950,11 @@ describe("MatrixClient", function () { expectedStates.push(["RECONNECTING", "SYNCING"]); expectedStates.push(["ERROR", "RECONNECTING"]); expectedStates.push(["ERROR", "ERROR"]); - client.on(ClientEvent.Sync, syncChecker(expectedStates, done)); - client.startClient(); + const didSyncPromise = new Promise((resolve) => { + client.on(ClientEvent.Sync, syncChecker(expectedStates, resolve)); + }); + await client.startClient(); + await didSyncPromise; }); }); @@ -961,7 +992,7 @@ describe("MatrixClient", function () { expect(httpLookups.length).toBe(0); }); - it.skip("should be able to peek into a room using peekInRoom", function (done) {}); + it.skip("should be able to peek into a room using peekInRoom", function () {}); }); describe("getPresence", function () { diff --git a/spec/unit/scheduler.spec.ts b/spec/unit/scheduler.spec.ts index 122b71fde1d..ecc27b633f4 100644 --- a/spec/unit/scheduler.spec.ts +++ b/spec/unit/scheduler.spec.ts @@ -154,7 +154,7 @@ describe("MatrixScheduler", function () { } }); - it("should treat each queue separately", function (done) { + it("should treat each queue separately", async () => { // Queue messages A B C D. // Bucket A&D into queue_A // Bucket B&C into queue_B @@ -179,13 +179,15 @@ describe("MatrixScheduler", function () { const expectOrder = [eventA.getId(), eventB.getId(), eventD.getId()]; const deferA = defer>(); - scheduler.setProcessFunction(function (event) { - const id = expectOrder.shift(); - expect(id).toEqual(event.getId()); - if (expectOrder.length === 0) { - done(); - } - return id === eventA.getId() ? deferA.promise : deferred.promise; + const allExpectedEventsSeenInOrderPromise = new Promise((resolve) => { + scheduler.setProcessFunction(function (event) { + const id = expectOrder.shift(); + expect(id).toEqual(event.getId()); + if (expectOrder.length === 0) { + resolve(null); + } + return id === eventA.getId() ? deferA.promise : deferred.promise; + }); }); scheduler.queueEvent(eventA); scheduler.queueEvent(eventB); @@ -197,6 +199,7 @@ describe("MatrixScheduler", function () { deferA.resolve({}); }, 1000); jest.advanceTimersByTime(1000); + await allExpectedEventsSeenInOrderPromise; }); describe("queueEvent", function () { From 938a2baf67b06f55d86456ff1a6d62cdcfd65fae Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 19:36:47 -0600 Subject: [PATCH 06/18] Ignore jest/valid-expect for now Pushing this out to a follow-up task, https://github.com/matrix-org/matrix-js-sdk/issues/2976 --- .eslintrc.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index 070dbdb6472..772be7c2e75 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -63,6 +63,9 @@ module.exports = { // 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/matrix-org/matrix-js-sdk/issues/2976 + "jest/valid-expect": "off", }, overrides: [ { From 8b58c1f25f1a6c334f8dcc6168e8b4faf85ac4bf Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 19:56:17 -0600 Subject: [PATCH 07/18] Fix jest/valid-expect-in-promise --- spec/integ/matrix-client-opts.spec.ts | 14 ++++++++++++-- spec/unit/crypto/DeviceList.spec.ts | 6 +++++- spec/unit/scheduler.spec.ts | 7 +++---- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/spec/integ/matrix-client-opts.spec.ts b/spec/integ/matrix-client-opts.spec.ts index eb381cabcb0..a14912c4a02 100644 --- a/spec/integ/matrix-client-opts.spec.ts +++ b/spec/integ/matrix-client-opts.spec.ts @@ -176,16 +176,26 @@ describe("MatrixClient opts", function () { }); let sentA = false; let sentB = false; - client.sendTextMessage("!foo:bar", "a body", "txn1").then(function (res) { + const messageASendPromise = client.sendTextMessage("!foo:bar", "a body", "txn1").then(function (res) { sentA = true; + // We expect messageB to be sent before messageA to ensure as we're + // testing that there is no queueing that blocks each other expect(sentB).toBe(true); }); - client.sendTextMessage("!foo:bar", "b body", "txn2").then(function (res) { + const messageBSendPromise = client.sendTextMessage("!foo:bar", "b body", "txn2").then(function (res) { sentB = true; + // We expect messageB to be sent before messageA to ensure as we're + // testing that there is no queueing that blocks each other expect(sentA).toBe(false); }); + // Allow messageB to succeed first await httpBackend.flush("/txn2", 1); + // Then allow messageA to succeed await httpBackend.flush("/txn1", 1); + + // Now await the message send promises to + await messageBSendPromise; + await messageASendPromise; }); it("should be able to send messages", async () => { diff --git a/spec/unit/crypto/DeviceList.spec.ts b/spec/unit/crypto/DeviceList.spec.ts index eeea1e76953..deb9b072f04 100644 --- a/spec/unit/crypto/DeviceList.spec.ts +++ b/spec/unit/crypto/DeviceList.spec.ts @@ -148,6 +148,10 @@ describe("DeviceList", function () { dl.invalidateUserDeviceList("@test1:sw1v.org"); dl.refreshOutdatedDeviceLists(); + // TODO: Fix this test so we actually await the call and assertions and remove + // the eslint disable, https://github.com/matrix-org/matrix-js-sdk/issues/2977 + // + // eslint-disable-next-line jest/valid-expect-in-promise dl.saveIfDirty() .then(() => { // the first request completes @@ -196,7 +200,7 @@ describe("DeviceList", function () { downloadSpy.mockReturnValueOnce(queryDefer2.promise); const prom1 = dl.refreshOutdatedDeviceLists(); - expect(downloadSpy).toHaveBeenCalledTimes(2); + expect(downloadSpy).toBeCalledTimes(2); expect(downloadSpy).toHaveBeenNthCalledWith(1, ["@test1:sw1v.org"], {}); expect(downloadSpy).toHaveBeenNthCalledWith(2, ["@test2:sw1v.org"], {}); queryDefer1.resolve(utils.deepCopy(signedDeviceList)); diff --git a/spec/unit/scheduler.spec.ts b/spec/unit/scheduler.spec.ts index ecc27b633f4..f0cb7280b07 100644 --- a/spec/unit/scheduler.spec.ts +++ b/spec/unit/scheduler.spec.ts @@ -297,7 +297,7 @@ describe("MatrixScheduler", function () { }); describe("setProcessFunction", function () { - it("should call the processFn if there are queued events", function () { + it("should call the processFn if there are queued events", async () => { queueFn = function () { return "yep"; }; @@ -310,9 +310,8 @@ describe("MatrixScheduler", function () { }); // as queueing doesn't start processing synchronously anymore (see commit bbdb5ac) // wait just long enough before it does - Promise.resolve().then(() => { - expect(procCount).toEqual(1); - }); + await Promise.resolve(); + expect(procCount).toEqual(1); }); it("should not call the processFn if there are no queued events", function () { From 63c7ff89bf8291db68cd229122efa0ac7e29de5d Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 20:07:17 -0600 Subject: [PATCH 08/18] Fix jest/no-identical-title --- spec/unit/interactive-auth.spec.ts | 29 ------------------- spec/unit/notifications.spec.ts | 2 +- spec/unit/rendezvous/rendezvous.spec.ts | 2 +- .../rendezvous/simpleHttpTransport.spec.ts | 9 ------ spec/unit/webrtc/mediaHandler.spec.ts | 2 +- 5 files changed, 3 insertions(+), 41 deletions(-) diff --git a/spec/unit/interactive-auth.spec.ts b/spec/unit/interactive-auth.spec.ts index b301c49fc61..48279530289 100644 --- a/spec/unit/interactive-auth.spec.ts +++ b/spec/unit/interactive-auth.spec.ts @@ -464,35 +464,6 @@ describe("InteractiveAuth", () => { expect(requestEmailToken).toHaveBeenLastCalledWith(undefined, ia.getClientSecret(), 5, undefined); }); - it("increases auth attempts", async () => { - const doRequest = jest.fn(); - const stateUpdated = jest.fn(); - const requestEmailToken = jest.fn(); - requestEmailToken.mockImplementation(async () => ({ sid: "" })); - - const ia = new InteractiveAuth({ - matrixClient: getFakeClient(), - doRequest, - stateUpdated, - requestEmailToken, - }); - - await ia.requestEmailToken(); - expect(requestEmailToken).toHaveBeenLastCalledWith(undefined, ia.getClientSecret(), 1, undefined); - requestEmailToken.mockClear(); - await ia.requestEmailToken(); - expect(requestEmailToken).toHaveBeenLastCalledWith(undefined, ia.getClientSecret(), 2, undefined); - requestEmailToken.mockClear(); - await ia.requestEmailToken(); - expect(requestEmailToken).toHaveBeenLastCalledWith(undefined, ia.getClientSecret(), 3, undefined); - requestEmailToken.mockClear(); - await ia.requestEmailToken(); - expect(requestEmailToken).toHaveBeenLastCalledWith(undefined, ia.getClientSecret(), 4, undefined); - requestEmailToken.mockClear(); - await ia.requestEmailToken(); - expect(requestEmailToken).toHaveBeenLastCalledWith(undefined, ia.getClientSecret(), 5, undefined); - }); - it("passes errors through", async () => { const doRequest = jest.fn(); const stateUpdated = jest.fn(); diff --git a/spec/unit/notifications.spec.ts b/spec/unit/notifications.spec.ts index 144afb70f12..95b5a20bc3c 100644 --- a/spec/unit/notifications.spec.ts +++ b/spec/unit/notifications.spec.ts @@ -131,7 +131,7 @@ describe("fixNotificationCountOnDecryption", () => { expect(room.getThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Highlight)).toBe(1); }); - it("does not change the room count when there's no unread count", () => { + it("does not change the thread count when there's no unread count", () => { room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Total, 0); room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Highlight, 0); diff --git a/spec/unit/rendezvous/rendezvous.spec.ts b/spec/unit/rendezvous/rendezvous.spec.ts index 1362335d5ac..63fa26f6bee 100644 --- a/spec/unit/rendezvous/rendezvous.spec.ts +++ b/spec/unit/rendezvous/rendezvous.spec.ts @@ -278,7 +278,7 @@ describe("Rendezvous", function () { expect(aliceOnFailure).toHaveBeenCalledWith(RendezvousFailureReason.UnsupportedAlgorithm); }); - it("new device declines protocol", async function () { + it("new device declines protocol (TODO: how is this different from the other test with the same name?)", async function () { const aliceTransport = makeTransport("Alice", "https://test.rz/123456"); const bobTransport = makeTransport("Bob", "https://test.rz/999999"); transports.push(aliceTransport, bobTransport); diff --git a/spec/unit/rendezvous/simpleHttpTransport.spec.ts b/spec/unit/rendezvous/simpleHttpTransport.spec.ts index 36595e8a5d8..6087fbc8818 100644 --- a/spec/unit/rendezvous/simpleHttpTransport.spec.ts +++ b/spec/unit/rendezvous/simpleHttpTransport.spec.ts @@ -163,15 +163,6 @@ describe("SimpleHttpRendezvousTransport", function () { ); }); - it("POST with relative path response including parent", async function () { - await postAndCheckLocation( - false, - "https://fallbackserver/rz/abc", - "../xyz/123", - "https://fallbackserver/rz/xyz/123", - ); - }); - it("POST to follow 307 to other server", async function () { const client = makeMockClient({ userId: "@alice:example.com", deviceId: "DEVICEID", msc3886Enabled: false }); const simpleHttpTransport = new MSC3886SimpleHttpRendezvousTransport({ diff --git a/spec/unit/webrtc/mediaHandler.spec.ts b/spec/unit/webrtc/mediaHandler.spec.ts index aa9cb047362..39a84de2e6b 100644 --- a/spec/unit/webrtc/mediaHandler.spec.ts +++ b/spec/unit/webrtc/mediaHandler.spec.ts @@ -403,7 +403,7 @@ describe("Media Handler", function () { }); }); - describe("stopUserMediaStream", () => { + describe("stopScreensharingStream", () => { let stream: MediaStream; beforeEach(async () => { From 782157d38ca7b585d05e259cf239eb025e3f7747 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 20:11:12 -0600 Subject: [PATCH 09/18] Try to rename test accurately --- spec/unit/rendezvous/rendezvous.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/rendezvous/rendezvous.spec.ts b/spec/unit/rendezvous/rendezvous.spec.ts index 63fa26f6bee..0b0c79eb36c 100644 --- a/spec/unit/rendezvous/rendezvous.spec.ts +++ b/spec/unit/rendezvous/rendezvous.spec.ts @@ -220,7 +220,7 @@ describe("Rendezvous", function () { await bobStartPromise; }); - it("new device declines protocol", async function () { + it("new device declines protocol (unsupported outcome)", async function () { const aliceTransport = makeTransport("Alice", "https://test.rz/123456"); const bobTransport = makeTransport("Bob", "https://test.rz/999999"); transports.push(aliceTransport, bobTransport); @@ -278,7 +278,7 @@ describe("Rendezvous", function () { expect(aliceOnFailure).toHaveBeenCalledWith(RendezvousFailureReason.UnsupportedAlgorithm); }); - it("new device declines protocol (TODO: how is this different from the other test with the same name?)", async function () { + it("new device declines protocol (bad protocol)", async function () { const aliceTransport = makeTransport("Alice", "https://test.rz/123456"); const bobTransport = makeTransport("Bob", "https://test.rz/999999"); transports.push(aliceTransport, bobTransport); From c082a565a0b5d95f170324c8b0c1254f73b288c2 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 20:15:11 -0600 Subject: [PATCH 10/18] Fix jest/valid-describe-callback --- spec/unit/room.spec.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index 81f6602e784..72041837c72 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -784,8 +784,12 @@ describe("Room", function () { }); }; - describe("resetLiveTimeline with timeline support enabled", resetTimelineTests.bind(null, true)); - describe("resetLiveTimeline with timeline support disabled", resetTimelineTests.bind(null, false)); + describe("resetLiveTimeline with timeline support enabled", () => { + resetTimelineTests.bind(null, true); + }); + describe("resetLiveTimeline with timeline support disabled", () => { + resetTimelineTests.bind(null, false); + }); describe("compareEventOrdering", function () { beforeEach(function () { From 2ebd5c551a1ae9212a3704b284409f23f081f2aa Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 20:16:38 -0600 Subject: [PATCH 11/18] Fix jest/no-alias-methods --- spec/unit/crypto/DeviceList.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/crypto/DeviceList.spec.ts b/spec/unit/crypto/DeviceList.spec.ts index deb9b072f04..ae96a4812b9 100644 --- a/spec/unit/crypto/DeviceList.spec.ts +++ b/spec/unit/crypto/DeviceList.spec.ts @@ -200,7 +200,7 @@ describe("DeviceList", function () { downloadSpy.mockReturnValueOnce(queryDefer2.promise); const prom1 = dl.refreshOutdatedDeviceLists(); - expect(downloadSpy).toBeCalledTimes(2); + expect(downloadSpy).toHaveBeenCalledTimes(2); expect(downloadSpy).toHaveBeenNthCalledWith(1, ["@test1:sw1v.org"], {}); expect(downloadSpy).toHaveBeenNthCalledWith(2, ["@test2:sw1v.org"], {}); queryDefer1.resolve(utils.deepCopy(signedDeviceList)); From 9ddde4d55e6578b4639b88027bce34b7db4fca82 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 20:18:21 -0600 Subject: [PATCH 12/18] Fix jest/valid-title --- spec/integ/matrix-client-syncing.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/integ/matrix-client-syncing.spec.ts b/spec/integ/matrix-client-syncing.spec.ts index b932985b104..5b612601937 100644 --- a/spec/integ/matrix-client-syncing.spec.ts +++ b/spec/integ/matrix-client-syncing.spec.ts @@ -836,6 +836,7 @@ describe("MatrixClient syncing", () => { roomVersion: "org.matrix.msc2716v3", }, ].forEach((testMeta) => { + // eslint-disable-next-line jest/valid-title describe(testMeta.label, () => { const roomCreateEvent = utils.mkEvent({ type: "m.room.create", From 0adad602d87f174c471e97023f141bbc21cf1dba Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 20:21:23 -0600 Subject: [PATCH 13/18] Ignore jest/no-conditional-expect for now See https://github.com/matrix-org/matrix-js-sdk/issues/2978 --- .eslintrc.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index 772be7c2e75..29c341e5bbd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -66,6 +66,9 @@ module.exports = { // TODO: There are many tests with invalid expects that should be fixed, // https://github.com/matrix-org/matrix-js-sdk/issues/2976 "jest/valid-expect": "off", + // TODO: There are many cases to refactor away, + // https://github.com/matrix-org/matrix-js-sdk/issues/2978 + "jest/no-conditional-expect": "off", }, overrides: [ { From 501865adeff67800fe51cbec32085c80e533e3e3 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 13 Dec 2022 20:27:37 -0600 Subject: [PATCH 14/18] Run prettier --- spec/integ/megolm-integ.spec.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/spec/integ/megolm-integ.spec.ts b/spec/integ/megolm-integ.spec.ts index e8727560682..70ac77f0df3 100644 --- a/spec/integ/megolm-integ.spec.ts +++ b/spec/integ/megolm-integ.spec.ts @@ -653,9 +653,7 @@ describe("megolm", () => { describe("get|setGlobalErrorOnUnknownDevices", () => { it("should raise an error if crypto is disabled", () => { aliceTestClient.client["cryptoBackend"] = undefined; - expect(() => aliceTestClient.client.setGlobalErrorOnUnknownDevices(true)).toThrow( - "encryption disabled", - ); + expect(() => aliceTestClient.client.setGlobalErrorOnUnknownDevices(true)).toThrow("encryption disabled"); expect(() => aliceTestClient.client.getGlobalErrorOnUnknownDevices()).toThrow("encryption disabled"); }); @@ -712,9 +710,7 @@ describe("megolm", () => { expect(() => aliceTestClient.client.setGlobalBlacklistUnverifiedDevices(true)).toThrow( "encryption disabled", ); - expect(() => aliceTestClient.client.getGlobalBlacklistUnverifiedDevices()).toThrow( - "encryption disabled", - ); + expect(() => aliceTestClient.client.getGlobalBlacklistUnverifiedDevices()).toThrow("encryption disabled"); }); it("should disable sending to unverified devices", async () => { From 2cf6296fd544e3a5e28f16adc198fae8eb99ec37 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 14 Dec 2022 09:41:24 +0000 Subject: [PATCH 15/18] Rendezvous test case name tweaks --- spec/unit/rendezvous/rendezvous.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/rendezvous/rendezvous.spec.ts b/spec/unit/rendezvous/rendezvous.spec.ts index 0b0c79eb36c..07187647630 100644 --- a/spec/unit/rendezvous/rendezvous.spec.ts +++ b/spec/unit/rendezvous/rendezvous.spec.ts @@ -220,7 +220,7 @@ describe("Rendezvous", function () { await bobStartPromise; }); - it("new device declines protocol (unsupported outcome)", async function () { + it("new device declines protocol with outcome unsupported", async function () { const aliceTransport = makeTransport("Alice", "https://test.rz/123456"); const bobTransport = makeTransport("Bob", "https://test.rz/999999"); transports.push(aliceTransport, bobTransport); @@ -278,7 +278,7 @@ describe("Rendezvous", function () { expect(aliceOnFailure).toHaveBeenCalledWith(RendezvousFailureReason.UnsupportedAlgorithm); }); - it("new device declines protocol (bad protocol)", async function () { + it("new device requests an invalid protocol", async function () { const aliceTransport = makeTransport("Alice", "https://test.rz/123456"); const bobTransport = makeTransport("Bob", "https://test.rz/999999"); transports.push(aliceTransport, bobTransport); From e58923ad79ddff47144f029fe8ffadbd0d524cd2 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Thu, 2 Feb 2023 17:14:01 +0100 Subject: [PATCH 16/18] Fix new test code --- .eslintrc.js | 8 ++ spec/unit/ToDeviceMessageQueue.spec.ts | 22 +++-- .../PollResponseEvent.spec.ts | 20 ----- spec/unit/matrix-client.spec.ts | 31 +------ spec/unit/models/poll.spec.ts | 87 +------------------ spec/unit/room.spec.ts | 2 +- spec/unit/webrtc/groupCall.spec.ts | 2 +- 7 files changed, 31 insertions(+), 141 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 29c341e5bbd..31ba94d2281 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -69,6 +69,14 @@ module.exports = { // TODO: There are many cases to refactor away, // https://github.com/matrix-org/matrix-js-sdk/issues/2978 "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"], + }, + ], }, overrides: [ { diff --git a/spec/unit/ToDeviceMessageQueue.spec.ts b/spec/unit/ToDeviceMessageQueue.spec.ts index 8752331c79e..7c0a023e53f 100644 --- a/spec/unit/ToDeviceMessageQueue.spec.ts +++ b/spec/unit/ToDeviceMessageQueue.spec.ts @@ -5,6 +5,7 @@ import { getMockClientWithEventEmitter } from "../test-utils/client"; import { StubStore } from "../../src/store/stub"; import { IndexedToDeviceBatch } from "../../src/models/ToDeviceMessage"; import { SyncState } from "../../src/sync"; +import { defer } from "../../src/utils"; describe("onResumedSync", () => { let batch: IndexedToDeviceBatch | null; @@ -58,7 +59,9 @@ describe("onResumedSync", () => { queue = new ToDeviceMessageQueue(mockClient); }); - it("resends queue after connectivity restored", (done) => { + it("resends queue after connectivity restored", async () => { + const deferred = defer(); + onSendToDeviceFailure = () => { expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1); expect(store.removeToDeviceBatch).not.toHaveBeenCalled(); @@ -70,26 +73,32 @@ describe("onResumedSync", () => { onSendToDeviceSuccess = () => { expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(3); expect(store.removeToDeviceBatch).toHaveBeenCalled(); - done(); + deferred.resolve(); }; queue.start(); + return deferred.promise; }); - it("does not resend queue if client sync still catching up", (done) => { + it("does not resend queue if client sync still catching up", async () => { + const deferred = defer(); + onSendToDeviceFailure = () => { expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1); expect(store.removeToDeviceBatch).not.toHaveBeenCalled(); resumeSync(SyncState.Catchup, SyncState.Catchup); expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1); - done(); + deferred.resolve(); }; queue.start(); + return deferred.promise; }); - it("does not resend queue if connectivity restored after queue stopped", (done) => { + it("does not resend queue if connectivity restored after queue stopped", async () => { + const deferred = defer(); + onSendToDeviceFailure = () => { expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1); expect(store.removeToDeviceBatch).not.toHaveBeenCalled(); @@ -98,9 +107,10 @@ describe("onResumedSync", () => { resumeSync(SyncState.Syncing, SyncState.Catchup); expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1); - done(); + deferred.resolve(); }; queue.start(); + return deferred.promise; }); }); diff --git a/spec/unit/extensible_events_v1/PollResponseEvent.spec.ts b/spec/unit/extensible_events_v1/PollResponseEvent.spec.ts index 49e900407d5..6abdd824e64 100644 --- a/spec/unit/extensible_events_v1/PollResponseEvent.spec.ts +++ b/spec/unit/extensible_events_v1/PollResponseEvent.spec.ts @@ -150,26 +150,6 @@ describe("PollResponseEvent", () => { expect(response.spoiled).toBe(true); }); - it("should spoil the vote when answers are empty", () => { - const input: IPartialEvent = { - type: M_POLL_RESPONSE.name, - content: { - "m.relates_to": { - rel_type: REFERENCE_RELATION.name, - event_id: "$poll", - }, - [M_POLL_RESPONSE.name]: { - answers: [], - }, - }, - }; - const response = new PollResponseEvent(input); - expect(response.spoiled).toBe(true); - - response.validateAgainst(SAMPLE_POLL); - expect(response.spoiled).toBe(true); - }); - it("should spoil the vote when answers are not strings", () => { const input: IPartialEvent = { type: M_POLL_RESPONSE.name, diff --git a/spec/unit/matrix-client.spec.ts b/spec/unit/matrix-client.spec.ts index bb336fba2cf..915214f1d9c 100644 --- a/spec/unit/matrix-client.spec.ts +++ b/spec/unit/matrix-client.spec.ts @@ -1365,7 +1365,7 @@ describe("MatrixClient", function () { client.redactEvent(roomId, eventId, txnId, { with_relations: [RelationType.Reference], }); - }).toThrowError( + }).toThrow( new Error( "Server does not support relation based redactions " + `roomId ${roomId} eventId ${eventId} txnId: ${txnId} threadId null`, @@ -1494,7 +1494,7 @@ describe("MatrixClient", function () { { startOpts: { threadSupport: false }, hasThreadSupport: false }, { startOpts: { experimentalThreadSupport: true }, hasThreadSupport: true }, { startOpts: { experimentalThreadSupport: true, threadSupport: false }, hasThreadSupport: false }, - ])("enabled thread support for the SDK instance ", async ({ startOpts, hasThreadSupport }) => { + ])("enabled thread support for the SDK instance", async ({ startOpts, hasThreadSupport }) => { await client.startClient(startOpts); expect(client.supportsThreads()).toBe(hasThreadSupport); }); @@ -2440,31 +2440,6 @@ describe("MatrixClient", function () { expect(rooms).toContain(room1); expect(rooms).toContain(room2); }); - - it("Ignores m.predecessor if we don't ask to use it", () => { - // Given 6 rooms, 2 of which have been replaced, and 2 of which WERE - // replaced by create events, but are now NOT replaced, because an - // m.predecessor event has changed the room's predecessor. - const { - room1, - room2, - replacedByCreate1, - replacedByCreate2, - replacedByDynamicPredecessor1, - replacedByDynamicPredecessor2, - } = setUpReplacedRooms(); - - // When we ask for the visible rooms - const rooms = client.getVisibleRooms(); // Don't supply msc3946ProcessDynamicPredecessor - - // Then we only get the ones that have not been replaced - expect(rooms).not.toContain(replacedByCreate1); - expect(rooms).not.toContain(replacedByCreate2); - expect(rooms).toContain(replacedByDynamicPredecessor1); - expect(rooms).toContain(replacedByDynamicPredecessor2); - expect(rooms).toContain(room1); - expect(rooms).toContain(room2); - }); }); describe("getRoomUpgradeHistory", () => { @@ -2649,7 +2624,7 @@ describe("MatrixClient", function () { expect(history.map((room) => room.roomId)).toEqual([room1.roomId]); }); - it("Without verify links, includes predecessors that don't point forwards", () => { + it("Without verify links, includes successors that don't point backwards", () => { // Given predecessors point forwards with tombstones, but // successors do not point back with create events. const [room1, room2, room3, room4] = createRoomHistory(false, true); diff --git a/spec/unit/models/poll.spec.ts b/spec/unit/models/poll.spec.ts index 6b00e4a5dbd..9ca3df7a2fa 100644 --- a/spec/unit/models/poll.spec.ts +++ b/spec/unit/models/poll.spec.ts @@ -80,7 +80,7 @@ describe("Poll", () => { const pollStartEvent = new MatrixEvent( PollStartEvent.from("What?", ["a", "b"], M_POLL_KIND_DISCLOSED.name).serialize(), ); - expect(() => new Poll(pollStartEvent, mockClient, room)).toThrowError("Invalid poll start event."); + expect(() => new Poll(pollStartEvent, mockClient, room)).toThrow("Invalid poll start event."); }); it("throws when poll start has no event id", () => { @@ -88,7 +88,7 @@ describe("Poll", () => { ...PollStartEvent.from("What?", ["a", "b"], M_POLL_KIND_DISCLOSED.name).serialize(), room_id: roomId, }); - expect(() => new Poll(pollStartEvent, mockClient, room)).toThrowError("Invalid poll start event."); + expect(() => new Poll(pollStartEvent, mockClient, room)).toThrow("Invalid poll start event."); }); describe("fetching responses", () => { @@ -292,33 +292,6 @@ describe("Poll", () => { expect(maySendRedactionForEventSpy).toHaveBeenCalledWith(basePollStartEvent, "@charlie:server.org"); }); - it("does not set poll end event when an earlier end event already exists", async () => { - const earlierPollEndEvent = makeRelatedEvent( - { type: M_POLL_END.stable!, sender: "@valid:server.org" }, - now, - ); - const laterPollEndEvent = makeRelatedEvent( - { type: M_POLL_END.stable!, sender: "@valid:server.org" }, - now + 2000, - ); - - const poll = new Poll(basePollStartEvent, mockClient, room); - await poll.getResponses(); - - poll.onNewRelation(earlierPollEndEvent); - - // first end event set correctly - expect(poll.isEnded).toBeTruthy(); - - // reset spy count - jest.spyOn(poll, "emit").mockClear(); - - poll.onNewRelation(laterPollEndEvent); - // didn't set new end event, didn't refilter responses - expect(poll.emit).not.toHaveBeenCalled(); - expect(poll.isEnded).toBeTruthy(); - }); - it("replaces poll end event and refilters when an older end event already exists", async () => { const earlierPollEndEvent = makeRelatedEvent( { type: M_POLL_END.stable!, sender: "@valid:server.org" }, @@ -356,25 +329,6 @@ describe("Poll", () => { expect(responses.getRelations()).toEqual([responseEventAtEnd, responseEventBeforeEnd]); }); - it("does not set poll end event when sent by invalid user", async () => { - maySendRedactionForEventSpy.mockReturnValue(false); - const stablePollEndEvent = makeRelatedEvent({ type: M_POLL_END.stable!, sender: "@charlie:server.org" }); - const responseEventAfterEnd = makeRelatedEvent({ type: M_POLL_RESPONSE.name }, now + 1000); - mockClient.relations.mockResolvedValue({ - events: [responseEventAfterEnd], - }); - const poll = new Poll(basePollStartEvent, mockClient, room); - await poll.getResponses(); - jest.spyOn(poll, "emit"); - - poll.onNewRelation(stablePollEndEvent); - - // didn't end, didn't refilter responses - expect(poll.emit).not.toHaveBeenCalled(); - expect(poll.isEnded).toBeFalsy(); - expect(maySendRedactionForEventSpy).toHaveBeenCalledWith(basePollStartEvent, "@charlie:server.org"); - }); - it("does not set poll end event when an earlier end event already exists", async () => { const earlierPollEndEvent = makeRelatedEvent( { type: M_POLL_END.stable!, sender: "@valid:server.org" }, @@ -402,43 +356,6 @@ describe("Poll", () => { expect(poll.isEnded).toBeTruthy(); }); - it("replaces poll end event and refilters when an older end event already exists", async () => { - const earlierPollEndEvent = makeRelatedEvent( - { type: M_POLL_END.stable!, sender: "@valid:server.org" }, - now, - ); - const laterPollEndEvent = makeRelatedEvent( - { type: M_POLL_END.stable!, sender: "@valid:server.org" }, - now + 2000, - ); - const responseEventBeforeEnd = makeRelatedEvent({ type: M_POLL_RESPONSE.name }, now - 1000); - const responseEventAtEnd = makeRelatedEvent({ type: M_POLL_RESPONSE.name }, now); - const responseEventAfterEnd = makeRelatedEvent({ type: M_POLL_RESPONSE.name }, now + 1000); - mockClient.relations.mockResolvedValue({ - events: [responseEventAfterEnd, responseEventAtEnd, responseEventBeforeEnd, laterPollEndEvent], - }); - - const poll = new Poll(basePollStartEvent, mockClient, room); - const responses = await poll.getResponses(); - - // all responses have a timestamp < laterPollEndEvent - expect(responses.getRelations().length).toEqual(3); - // first end event set correctly - expect(poll.isEnded).toBeTruthy(); - - // reset spy count - jest.spyOn(poll, "emit").mockClear(); - - // add a valid end event with earlier timestamp - poll.onNewRelation(earlierPollEndEvent); - - // emitted new end event - expect(poll.emit).toHaveBeenCalledWith(PollEvent.End); - // filtered responses and emitted - expect(poll.emit).toHaveBeenCalledWith(PollEvent.Responses, responses); - expect(responses.getRelations()).toEqual([responseEventAtEnd, responseEventBeforeEnd]); - }); - it("sets poll end event and refilters responses based on timestamp", async () => { const stablePollEndEvent = makeRelatedEvent({ type: M_POLL_END.stable!, sender: userId }); const responseEventBeforeEnd = makeRelatedEvent({ type: M_POLL_RESPONSE.name }, now - 1000); diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index 6a258f8a86e..66e21bd82f4 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -3255,7 +3255,7 @@ describe("Room", function () { return event; }; - it("adds poll models to room state for a poll start event ", async () => { + it("adds poll models to room state for a poll start event", async () => { const pollStartEvent = makePollStart("1"); const events = [pollStartEvent]; diff --git a/spec/unit/webrtc/groupCall.spec.ts b/spec/unit/webrtc/groupCall.spec.ts index c6fae8819ff..92f65ceb220 100644 --- a/spec/unit/webrtc/groupCall.spec.ts +++ b/spec/unit/webrtc/groupCall.spec.ts @@ -147,7 +147,7 @@ describe("Group Call", function () { async (state: GroupCallState) => { // @ts-ignore groupCall.state = state; - await expect(groupCall.initLocalCallFeed()).rejects.toThrowError(); + await expect(groupCall.initLocalCallFeed()).rejects.toThrow(); }, ); From af9e441efe588b3db439ee75ffe7806b08bb64ae Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Thu, 2 Feb 2023 17:26:30 +0100 Subject: [PATCH 17/18] Use specific eslint plugin commit --- package.json | 2 +- yarn.lock | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 3adbff38892..5afeb959515 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^27.1.6", "eslint-plugin-jsdoc": "^39.6.4", - "eslint-plugin-matrix-org": "^0.9.0", + "eslint-plugin-matrix-org": "https://github.com/matrix-org/eslint-plugin-matrix-org.git#f430bfb4a41ae0dff7b4b8706048efe88d59681e", "eslint-plugin-tsdoc": "^0.2.17", "eslint-plugin-unicorn": "^45.0.0", "exorcist": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index f07848e1415..f634e1e9521 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3373,10 +3373,9 @@ eslint-plugin-jsdoc@^39.6.4: semver "^7.3.8" spdx-expression-parse "^3.0.1" -eslint-plugin-matrix-org@^0.9.0: +"eslint-plugin-matrix-org@https://github.com/matrix-org/eslint-plugin-matrix-org.git#f430bfb4a41ae0dff7b4b8706048efe88d59681e": version "0.9.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-matrix-org/-/eslint-plugin-matrix-org-0.9.0.tgz#b2a5186052ddbfa7dc9878779bafa5d68681c7b4" - integrity sha512-+j6JuMnFH421Z2vOxc+0YMt5Su5vD76RSatviy3zHBaZpgd+sOeAWoCLBHD5E7mMz5oKae3Y3wewCt9LRzq2Nw== + resolved "https://github.com/matrix-org/eslint-plugin-matrix-org.git#f430bfb4a41ae0dff7b4b8706048efe88d59681e" eslint-plugin-tsdoc@^0.2.17: version "0.2.17" From cae448c4d31c9e6bc30a99eff3653c58ea3d8bb6 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Tue, 7 Feb 2023 16:53:02 +0100 Subject: [PATCH 18/18] Use eslint-plugin-matrix-org 1.0.0 --- package.json | 2 +- yarn.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f2f42c713d0..80937a97840 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^27.1.6", "eslint-plugin-jsdoc": "^39.6.4", - "eslint-plugin-matrix-org": "https://github.com/matrix-org/eslint-plugin-matrix-org.git#63ba4c640207a8a112b92beba663c1f44e267b19", + "eslint-plugin-matrix-org": "^1.0.0", "eslint-plugin-tsdoc": "^0.2.17", "eslint-plugin-unicorn": "^45.0.0", "exorcist": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index b357e7055fc..77322500ba2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3440,9 +3440,10 @@ eslint-plugin-jsdoc@^39.6.4: semver "^7.3.8" spdx-expression-parse "^3.0.1" -"eslint-plugin-matrix-org@https://github.com/matrix-org/eslint-plugin-matrix-org.git#63ba4c640207a8a112b92beba663c1f44e267b19": - version "0.10.0" - resolved "https://github.com/matrix-org/eslint-plugin-matrix-org.git#63ba4c640207a8a112b92beba663c1f44e267b19" +eslint-plugin-matrix-org@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-matrix-org/-/eslint-plugin-matrix-org-1.0.0.tgz#cead71391e2a36d63cb8f8018a38305ecf81b4b8" + integrity sha512-JSjw+hswEcFR+N4N2JXZttK65cK6huykZKkbnwcITxPTelsaOfZ8qXG0Az9BfmVADaLgY3MGmHK1YYKbykUfBQ== eslint-plugin-tsdoc@^0.2.17: version "0.2.17"