diff --git a/.eslintrc.js b/.eslintrc.js index 18b502d7f98..97e66776c1c 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"], parserOptions: { project: ["./tsconfig.json"], }, @@ -63,6 +63,23 @@ 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", + // 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/package.json b/package.json index 5030228f984..591f95153dd 100644 --- a/package.json +++ b/package.json @@ -103,8 +103,9 @@ "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.10.0", + "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/spec/TestClient.ts b/spec/TestClient.ts index c35aff30fc8..235510a7939 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/integ/crypto.spec.ts b/spec/integ/crypto.spec.ts index eb39f4fcff2..718f027c9ed 100644 --- a/spec/integ/crypto.spec.ts +++ b/spec/integ/crypto.spec.ts @@ -743,10 +743,8 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("megolm (%s)", (backend: string, describe("get|setGlobalErrorOnUnknownDevices", () => { it("should raise an error if crypto is disabled", () => { aliceTestClient.client["cryptoBackend"] = undefined; - expect(() => aliceTestClient.client.setGlobalErrorOnUnknownDevices(true)).toThrowError( - "encryption disabled", - ); - expect(() => aliceTestClient.client.getGlobalErrorOnUnknownDevices()).toThrowError("encryption disabled"); + expect(() => aliceTestClient.client.setGlobalErrorOnUnknownDevices(true)).toThrow("encryption disabled"); + expect(() => aliceTestClient.client.getGlobalErrorOnUnknownDevices()).toThrow("encryption disabled"); }); oldBackendOnly("should permit sending to unknown devices", async () => { @@ -799,12 +797,10 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("megolm (%s)", (backend: string, describe("get|setGlobalBlacklistUnverifiedDevices", () => { it("should raise an error if crypto is disabled", () => { aliceTestClient.client["cryptoBackend"] = undefined; - expect(() => aliceTestClient.client.setGlobalBlacklistUnverifiedDevices(true)).toThrowError( - "encryption disabled", - ); - expect(() => aliceTestClient.client.getGlobalBlacklistUnverifiedDevices()).toThrowError( + expect(() => aliceTestClient.client.setGlobalBlacklistUnverifiedDevices(true)).toThrow( "encryption disabled", ); + expect(() => aliceTestClient.client.getGlobalBlacklistUnverifiedDevices()).toThrow("encryption disabled"); }); oldBackendOnly("should disable sending to unverified devices", async () => { 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 c5ea7fe5d98..a665aef86e1 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -205,19 +205,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", }; @@ -230,15 +228,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", }; @@ -247,20 +241,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 = { @@ -276,13 +266,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..a14912c4a02 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", }); @@ -178,30 +176,38 @@ 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); }); - httpBackend.flush("/txn2", 1).then(function () { - httpBackend.flush("/txn1", 1).then(function () { - done(); - }); - }); + // 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", 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-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-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 75487eb81dd..86228037a46 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 () => { @@ -724,7 +720,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 +737,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({ @@ -840,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", @@ -1592,27 +1589,24 @@ 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", () => { - 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/integ/sliding-sync-sdk.spec.ts b/spec/integ/sliding-sync-sdk.spec.ts index 98c3879f30b..9da48d6cc14 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/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/crypto.spec.ts b/spec/unit/crypto.spec.ts index 4bb5b58ca37..43b6fd9f056 100644 --- a/spec/unit/crypto.spec.ts +++ b/spec/unit/crypto.spec.ts @@ -550,7 +550,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 @@ -564,7 +564,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..ae96a4812b9 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).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 6c91d530f28..3931ee3fc5e 100644 --- a/spec/unit/crypto/algorithms/megolm.spec.ts +++ b/spec/unit/crypto/algorithms/megolm.spec.ts @@ -211,7 +211,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 6322289f059..4a624268c8a 100644 --- a/spec/unit/event-timeline-set.spec.ts +++ b/spec/unit/event-timeline-set.spec.ts @@ -179,7 +179,7 @@ describe("EventTimelineSet", () => { eventTimelineSet.addEventToTimeline(messageEvent, liveTimeline2, { toStartOfTimeline: true, }); - }).toThrowError(); + }).toThrow(); }); it("should not add a threaded reply to the main room timeline", () => { @@ -399,7 +399,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/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/interactive-auth.spec.ts b/spec/unit/interactive-auth.spec.ts index 366a9a710c8..48279530289 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", () => { @@ -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(); @@ -508,7 +479,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 45a584c06bc..efd4353062f 100644 --- a/spec/unit/matrix-client.spec.ts +++ b/spec/unit/matrix-client.spec.ts @@ -893,7 +893,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! @@ -919,10 +919,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); }); }); @@ -933,7 +931,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({ @@ -944,23 +942,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", @@ -972,22 +973,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", @@ -998,20 +1002,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; }); }); @@ -1035,14 +1042,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); @@ -1052,14 +1062,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 - xit("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 = []; @@ -1089,19 +1102,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; }); - xit("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({ @@ -1119,11 +1138,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; }); - xit("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", @@ -1135,11 +1157,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); @@ -1147,11 +1172,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; }); - xit("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({ @@ -1175,8 +1203,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; }); }); @@ -1214,7 +1245,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 () {}); }); describe("getPresence", function () { @@ -1334,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`, @@ -1464,7 +1495,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); }); @@ -2410,31 +2441,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", () => { @@ -2619,7 +2625,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/notifications.spec.ts b/spec/unit/notifications.spec.ts index 84ba9971cb2..a7a23eb213f 100644 --- a/spec/unit/notifications.spec.ts +++ b/spec/unit/notifications.spec.ts @@ -159,7 +159,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/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..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", 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", 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); @@ -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..6087fbc8818 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: { @@ -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({ @@ -373,7 +364,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 +385,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 +407,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 +447,7 @@ describe("SimpleHttpRendezvousTransport", function () { }, }; await httpBackend.flush(""); - expect(onFailure).toBeCalledWith(RendezvousFailureReason.Expired); + expect(onFailure).toHaveBeenCalledWith(RendezvousFailureReason.Expired); } }); }); diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index 27d5a00dcb4..ada786a2a12 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -788,8 +788,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 () { @@ -3251,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/scheduler.spec.ts b/spec/unit/scheduler.spec.ts index 5efd9ce1bc1..6975e475553 100644 --- a/spec/unit/scheduler.spec.ts +++ b/spec/unit/scheduler.spec.ts @@ -150,7 +150,7 @@ describe("MatrixScheduler", function () { expect(procCount).toEqual(1); }); - 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 @@ -175,13 +175,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); @@ -193,6 +195,7 @@ describe("MatrixScheduler", function () { deferA.resolve({}); }, 1000); jest.advanceTimersByTime(1000); + await allExpectedEventsSeenInOrderPromise; }); describe("queueEvent", function () { @@ -290,7 +293,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"; }; @@ -303,9 +306,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 () { diff --git a/spec/unit/utils.spec.ts b/spec/unit/utils.spec.ts index caf15a43e6d..98a4ddc3081 100644 --- a/spec/unit/utils.spec.ts +++ b/spec/unit/utils.spec.ts @@ -145,9 +145,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); }, }; diff --git a/spec/unit/webrtc/call.spec.ts b/spec/unit/webrtc/call.spec.ts index d782c61a903..6ec2dcb5d4d 100644 --- a/spec/unit/webrtc/call.spec.ts +++ b/spec/unit/webrtc/call.spec.ts @@ -1579,7 +1579,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 ec12d1640ab..4b68100113e 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(); }, ); @@ -389,7 +389,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 1dc84e58550..1b3a815b00a 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(); @@ -401,7 +401,7 @@ describe("Media Handler", function () { }); }); - describe("stopUserMediaStream", () => { + describe("stopScreensharingStream", () => { let stream: MediaStream; beforeEach(async () => { diff --git a/yarn.lock b/yarn.lock index 16c7ad66dc8..80aaab86709 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1869,7 +1869,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.51.0": +"@typescript-eslint/utils@5.51.0", "@typescript-eslint/utils@^5.10.0": version "5.51.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.51.0.tgz#074f4fabd5b12afe9c8aa6fdee881c050f8b4d47" integrity sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw== @@ -3414,6 +3414,13 @@ eslint-plugin-import@^2.26.0: semver "^6.3.0" tsconfig-paths "^3.14.1" +eslint-plugin-jest@^27.1.6: + version "27.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz#b85b4adf41c682ea29f1f01c8b11ccc39b5c672c" + integrity sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg== + dependencies: + "@typescript-eslint/utils" "^5.10.0" + eslint-plugin-jsdoc@^39.6.4: version "39.8.0" resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.8.0.tgz#9ca38ae31fb6e6de6268c5c041fa175fe1190469" @@ -3427,10 +3434,10 @@ eslint-plugin-jsdoc@^39.6.4: semver "^7.3.8" spdx-expression-parse "^3.0.1" -eslint-plugin-matrix-org@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-matrix-org/-/eslint-plugin-matrix-org-0.10.0.tgz#8d0998641a4d276343cae2abf253a01bb4d4cc60" - integrity sha512-L7ail0x1yUlF006kn4mHc+OT8/aYZI++i852YXPHxCbM1EY7jeg/fYAQ8tCx5+x08LyqXeS7inAVSL784m0C6Q== +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"