diff --git a/test/DecryptionFailureTracker-test.js b/test/DecryptionFailureTracker-test.ts similarity index 74% rename from test/DecryptionFailureTracker-test.js rename to test/DecryptionFailureTracker-test.ts index 7fcb53d5d4..553d4f4d74 100644 --- a/test/DecryptionFailureTracker-test.js +++ b/test/DecryptionFailureTracker-test.ts @@ -14,12 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { mkDecryptionFailureMatrixEvent } from "matrix-js-sdk/src/testing"; +import { decryptExistingEvent, mkDecryptionFailureMatrixEvent } from "matrix-js-sdk/src/testing"; +import { DecryptionFailureCode } from "matrix-js-sdk/src/crypto-api"; import { DecryptionFailureTracker } from "../src/DecryptionFailureTracker"; class MockDecryptionError extends Error { - constructor(code) { + public readonly code: string; + + constructor(code?: string) { super(); this.code = code || "MOCK_DECRYPTION_ERROR"; @@ -30,7 +33,7 @@ async function createFailedDecryptionEvent() { return await mkDecryptionFailureMatrixEvent({ roomId: "!room:id", sender: "@alice:example.com", - code: "UNKNOWN_ERROR", + code: DecryptionFailureCode.UNKNOWN_ERROR, msg: ":(", }); } @@ -40,8 +43,9 @@ describe("DecryptionFailureTracker", function () { const failedDecryptionEvent = await createFailedDecryptionEvent(); let count = 0; + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total) => (count += total), + (total: number) => (count += total), () => "UnknownError", ); @@ -56,7 +60,8 @@ describe("DecryptionFailureTracker", function () { // Immediately track the newest failures tracker.trackFailures(); - expect(count).not.toBe(0, "should track a failure for an event that failed decryption"); + // should track a failure for an event that failed decryption + expect(count).not.toBe(0); }); it("tracks a failed decryption with expected raw error for a visible event", async function () { @@ -64,8 +69,9 @@ describe("DecryptionFailureTracker", function () { let count = 0; let reportedRawCode = ""; + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total, errcode, rawCode) => { + (total: number, _errCode: string, rawCode: string) => { count += total; reportedRawCode = rawCode; }, @@ -83,16 +89,20 @@ describe("DecryptionFailureTracker", function () { // Immediately track the newest failures tracker.trackFailures(); - expect(count).not.toBe(0, "should track a failure for an event that failed decryption"); - expect(reportedRawCode).toBe("INBOUND_SESSION_MISMATCH_ROOM_ID", "Should add the rawCode to the event context"); + // should track a failure for an event that failed decryption + expect(count).not.toBe(0); + + // Should add the rawCode to the event context + expect(reportedRawCode).toBe("INBOUND_SESSION_MISMATCH_ROOM_ID"); }); it("tracks a failed decryption for an event that becomes visible later", async function () { const failedDecryptionEvent = await createFailedDecryptionEvent(); let count = 0; + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total) => (count += total), + (total: number) => (count += total), () => "UnknownError", ); @@ -107,15 +117,17 @@ describe("DecryptionFailureTracker", function () { // Immediately track the newest failures tracker.trackFailures(); - expect(count).not.toBe(0, "should track a failure for an event that failed decryption"); + // should track a failure for an event that failed decryption + expect(count).not.toBe(0); }); it("does not track a failed decryption for an event that never becomes visible", async function () { const failedDecryptionEvent = await createFailedDecryptionEvent(); let count = 0; + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total) => (count += total), + (total: number) => (count += total), () => "UnknownError", ); @@ -128,14 +140,17 @@ describe("DecryptionFailureTracker", function () { // Immediately track the newest failures tracker.trackFailures(); - expect(count).toBe(0, "should not track a failure for an event that never became visible"); + // should not track a failure for an event that never became visible + expect(count).toBe(0); }); it("does not track a failed decryption where the event is subsequently successfully decrypted", async () => { const decryptedEvent = await createFailedDecryptionEvent(); + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total) => { - expect(true).toBe(false, "should not track an event that has since been decrypted correctly"); + (_total: number) => { + // should not track an event that has since been decrypted correctly + expect(true).toBe(false); }, () => "UnknownError", ); @@ -145,8 +160,11 @@ describe("DecryptionFailureTracker", function () { const err = new MockDecryptionError(); tracker.eventDecrypted(decryptedEvent, err); - // Indicate successful decryption: clear data can be anything where the msgtype is not m.bad.encrypted - decryptedEvent.setClearData({}); + // Indicate successful decryption. + await decryptExistingEvent(decryptedEvent, { + plainType: "m.room.message", + plainContent: { body: "success" }, + }); tracker.eventDecrypted(decryptedEvent, null); // Pretend "now" is Infinity @@ -161,9 +179,11 @@ describe("DecryptionFailureTracker", function () { "and later becomes visible", async () => { const decryptedEvent = await createFailedDecryptionEvent(); + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total) => { - expect(true).toBe(false, "should not track an event that has since been decrypted correctly"); + (_total: number) => { + // should not track an event that has since been decrypted correctly + expect(true).toBe(false); }, () => "UnknownError", ); @@ -171,8 +191,11 @@ describe("DecryptionFailureTracker", function () { const err = new MockDecryptionError(); tracker.eventDecrypted(decryptedEvent, err); - // Indicate successful decryption: clear data can be anything where the msgtype is not m.bad.encrypted - decryptedEvent.setClearData({}); + // Indicate successful decryption. + await decryptExistingEvent(decryptedEvent, { + plainType: "m.room.message", + plainContent: { body: "success" }, + }); tracker.eventDecrypted(decryptedEvent, null); tracker.addVisibleEvent(decryptedEvent); @@ -190,8 +213,9 @@ describe("DecryptionFailureTracker", function () { const decryptedEvent2 = await createFailedDecryptionEvent(); let count = 0; + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total) => (count += total), + (total: number) => (count += total), () => "UnknownError", ); @@ -218,15 +242,17 @@ describe("DecryptionFailureTracker", function () { tracker.trackFailures(); tracker.trackFailures(); - expect(count).toBe(2, count + " failures tracked, should only track a single failure per event"); + // should only track a single failure per event + expect(count).toBe(2); }); it("should not track a failure for an event that was tracked previously", async () => { const decryptedEvent = await createFailedDecryptionEvent(); let count = 0; + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total) => (count += total), + (total: number) => (count += total), () => "UnknownError", ); @@ -246,7 +272,8 @@ describe("DecryptionFailureTracker", function () { tracker.trackFailures(); - expect(count).toBe(1, "should only track a single failure per event"); + // should only track a single failure per event + expect(count).toBe(1); }); it.skip("should not track a failure for an event that was tracked in a previous session", async () => { @@ -256,8 +283,9 @@ describe("DecryptionFailureTracker", function () { const decryptedEvent = await createFailedDecryptionEvent(); let count = 0; + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total) => (count += total), + (total: number) => (count += total), () => "UnknownError", ); @@ -274,8 +302,9 @@ describe("DecryptionFailureTracker", function () { tracker.trackFailures(); // Simulate the browser refreshing by destroying tracker and creating a new tracker + // @ts-ignore access to private constructor const secondTracker = new DecryptionFailureTracker( - (total) => (count += total), + (total: number) => (count += total), () => "UnknownError", ); @@ -287,14 +316,17 @@ describe("DecryptionFailureTracker", function () { secondTracker.checkFailures(Infinity); secondTracker.trackFailures(); - expect(count).toBe(1, count + " failures tracked, should only track a single failure per event"); + // should only track a single failure per event + expect(count).toBe(1); }); it("should count different error codes separately for multiple failures with different error codes", async () => { - const counts = {}; + const counts: Record = {}; + + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total, errorCode) => (counts[errorCode] = (counts[errorCode] || 0) + total), - (error) => (error === "UnknownError" ? "UnknownError" : "OlmKeysNotSentError"), + (total: number, errorCode: string) => (counts[errorCode] = (counts[errorCode] || 0) + total), + (error: string) => (error === "UnknownError" ? "UnknownError" : "OlmKeysNotSentError"), ); const decryptedEvent1 = await createFailedDecryptionEvent(); @@ -320,14 +352,16 @@ describe("DecryptionFailureTracker", function () { tracker.trackFailures(); //expect(counts['UnknownError']).toBe(1, 'should track one UnknownError'); - expect(counts["OlmKeysNotSentError"]).toBe(2, "should track two OlmKeysNotSentError"); + expect(counts["OlmKeysNotSentError"]).toBe(2); }); it("should aggregate error codes correctly", async () => { - const counts = {}; + const counts: Record = {}; + + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total, errorCode) => (counts[errorCode] = (counts[errorCode] || 0) + total), - (errorCode) => "OlmUnspecifiedError", + (total: number, errorCode: string) => (counts[errorCode] = (counts[errorCode] || 0) + total), + (_errorCode: string) => "OlmUnspecifiedError", ); const decryptedEvent1 = await createFailedDecryptionEvent(); @@ -351,17 +385,16 @@ describe("DecryptionFailureTracker", function () { tracker.trackFailures(); - expect(counts["OlmUnspecifiedError"]).toBe( - 3, - "should track three OlmUnspecifiedError, got " + counts["OlmUnspecifiedError"], - ); + expect(counts["OlmUnspecifiedError"]).toBe(3); }); it("should remap error codes correctly", async () => { - const counts = {}; + const counts: Record = {}; + + // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( - (total, errorCode) => (counts[errorCode] = (counts[errorCode] || 0) + total), - (errorCode) => Array.from(errorCode).reverse().join(""), + (total: number, errorCode: string) => (counts[errorCode] = (counts[errorCode] || 0) + total), + (errorCode: string) => Array.from(errorCode).reverse().join(""), ); const decryptedEvent = await createFailedDecryptionEvent(); @@ -377,6 +410,7 @@ describe("DecryptionFailureTracker", function () { tracker.trackFailures(); - expect(counts["1_EDOC_RORRE"]).toBe(1, "should track remapped error code"); + // should track remapped error code + expect(counts["1_EDOC_RORRE"]).toBe(1); }); });