From 1476cd1a1d625e50d673e6191e27f4e45c590b47 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 10 May 2026 13:37:09 +0100 Subject: [PATCH] test: clear matrix sdk broad matchers --- extensions/matrix/src/matrix/sdk.test.ts | 157 ++++++++++++++--------- 1 file changed, 94 insertions(+), 63 deletions(-) diff --git a/extensions/matrix/src/matrix/sdk.test.ts b/extensions/matrix/src/matrix/sdk.test.ts index 69d0a0a5be2..053199bf5b8 100644 --- a/extensions/matrix/src/matrix/sdk.test.ts +++ b/extensions/matrix/src/matrix/sdk.test.ts @@ -18,6 +18,55 @@ function requestUrl(input: RequestInfo | URL | undefined): string { return input.url; } +function requireRecord(value: unknown, label: string): Record { + expect(typeof value).toBe("object"); + expect(value).not.toBeNull(); + if (typeof value !== "object" || value === null) { + throw new Error(`${label} was not an object`); + } + return value as Record; +} + +function expectRecordFields(record: Record, fields: Record) { + for (const [key, value] of Object.entries(fields)) { + expect(record[key]).toEqual(value); + } +} + +async function expectAbortError(promise: Promise) { + const err = await promise.catch((caught: unknown) => caught); + expect(err).toBeInstanceOf(Error); + expectRecordFields(requireRecord(err, "abort error"), { + message: "Matrix startup aborted", + name: "AbortError", + }); +} + +function expectMockCallOptions( + mock: ReturnType, + callIndex: number, + fields: Record, +) { + const call = (mock.mock.calls as unknown[][])[callIndex]?.[0]; + expectRecordFields(requireRecord(call, `mock call ${callIndex + 1} options`), fields); +} + +function expectSomeMockCallOptions( + mock: ReturnType, + fields: Record, +) { + const calls = mock.mock.calls as unknown[][]; + const matched = calls.some((call) => { + const arg = call[0]; + if (typeof arg !== "object" || arg === null) { + return false; + } + const record = arg as Record; + return Object.entries(fields).every(([key, value]) => Object.is(record[key], value)); + }); + expect(matched).toBe(true); +} + const TEST_UNDICI_RUNTIME_DEPS_KEY = "__OPENCLAW_TEST_UNDICI_RUNTIME_DEPS__"; function clearTestUndiciRuntimeDepsOverride(): void { @@ -296,7 +345,7 @@ describe("MatrixClient request hardening", () => { const client = new MatrixClient("https://matrix.example.org", "token"); expect(client).toBeInstanceOf(MatrixClient); - expect(lastCreateClientOpts).toMatchObject({ + expectRecordFields(requireRecord(lastCreateClientOpts, "create client options"), { baseUrl: "https://matrix.example.org", accessToken: "token", }); @@ -394,7 +443,7 @@ describe("MatrixClient request hardening", () => { const event = await client.getEvent("!room:example.org", "$poll"); expect(matrixJsClient.decryptEventIfNeeded).toHaveBeenCalledTimes(1); - expect(event).toMatchObject({ + expectRecordFields(requireRecord(event, "decrypted event"), { event_id: "$poll", type: "m.poll.start", sender: "@alice:example.org", @@ -505,14 +554,16 @@ describe("MatrixClient request hardening", () => { const page = await client.getRelations("!room:example.org", "$poll", "m.reference"); - expect(page.originalEvent).toMatchObject({ event_id: "$poll", type: "m.poll.start" }); - expect(page.events).toEqual([ - expect.objectContaining({ - event_id: "$vote", - type: "m.poll.response", - sender: "@bob:example.org", - }), - ]); + expectRecordFields(requireRecord(page.originalEvent, "original relation event"), { + event_id: "$poll", + type: "m.poll.start", + }); + expect(page.events).toHaveLength(1); + expectRecordFields(requireRecord(page.events[0], "relation event"), { + event_id: "$vote", + type: "m.poll.response", + sender: "@bob:example.org", + }); }); it("blocks cross-protocol redirects when absolute endpoints are allowed", async () => { @@ -1223,10 +1274,7 @@ describe("MatrixClient event bridge", () => { abortController.abort(); - await expect(startPromise).rejects.toMatchObject({ - message: "Matrix startup aborted", - name: "AbortError", - }); + await expectAbortError(startPromise); }); it("aborts before post-ready startup work when shutdown races ready sync", async () => { @@ -1250,10 +1298,7 @@ describe("MatrixClient event bridge", () => { } }); - await expect(client.start({ abortSignal: abortController.signal })).rejects.toMatchObject({ - message: "Matrix startup aborted", - name: "AbortError", - }); + await expectAbortError(client.start({ abortSignal: abortController.signal })); expect(bootstrapCryptoSpy).not.toHaveBeenCalled(); }); @@ -1367,11 +1412,11 @@ describe("MatrixClient crypto bootstrapping", () => { await client.start(); - expect(bootstrapCrossSigning).toHaveBeenCalledWith( - expect.objectContaining({ - authUploadDeviceSigningKeys: expect.any(Function), - }), + const crossSigningOptions = requireRecord( + (bootstrapCrossSigning.mock.calls as unknown[][])[0]?.[0], + "cross-signing options", ); + expect(crossSigningOptions.authUploadDeviceSigningKeys).toBeTypeOf("function"); }); it("trusts the own Matrix identity after completed self-verification", async () => { @@ -1623,12 +1668,8 @@ describe("MatrixClient crypto bootstrapping", () => { debug?: (...args: unknown[]) => void; getChild?: (namespace: string) => unknown; } | null; - expect(logger).toEqual( - expect.objectContaining({ - debug: expect.any(Function), - getChild: expect.any(Function), - }), - ); + expect(logger?.debug).toBeTypeOf("function"); + expect(logger?.getChild).toBeTypeOf("function"); }); it("passes a custom sync filter to matrix-js-sdk startup", async () => { @@ -1664,7 +1705,9 @@ describe("MatrixClient crypto bootstrapping", () => { await client.start(); expect(databasesSpy).toHaveBeenCalled(); - expect(setIntervalSpy).toHaveBeenCalledWith(expect.any(Function), 60_000); + const intervalCall = setIntervalSpy.mock.calls[0] as unknown[]; + expect(intervalCall[0]).toBeTypeOf("function"); + expect(intervalCall[1]).toBe(60_000); client.stop(); }); @@ -1747,7 +1790,7 @@ describe("MatrixClient crypto bootstrapping", () => { const status = await client.getOwnDeviceVerificationStatus(); expect(status.verified).toBe(true); - expect(status.backup).toMatchObject({ + expectRecordFields(requireRecord(status.backup, "backup status"), { serverVersion: null, activeVersion: null, trusted: null, @@ -1864,7 +1907,7 @@ describe("MatrixClient crypto bootstrapping", () => { const status = await client.getDeviceVerificationStatus("@peer:example.org", "PEERDEVICE"); expect(getDeviceVerificationStatus).toHaveBeenCalledWith("@peer:example.org", "PEERDEVICE"); - expect(status).toMatchObject({ + expectRecordFields(requireRecord(status, "device verification status"), { deviceId: "PEERDEVICE", encryptionEnabled: true, localVerified: true, @@ -2476,7 +2519,7 @@ describe("MatrixClient crypto bootstrapping", () => { }); const backup = await client.getRoomKeyBackupStatus(); - expect(backup).toMatchObject({ + expectRecordFields(requireRecord(backup, "room key backup status"), { serverVersion: "9", activeVersion: "9", trusted: true, @@ -2520,7 +2563,7 @@ describe("MatrixClient crypto bootstrapping", () => { }); const backup = await client.getRoomKeyBackupStatus(); - expect(backup).toMatchObject({ + expectRecordFields(requireRecord(backup, "room key backup status"), { serverVersion: "49262", activeVersion: "49262", trusted: true, @@ -2801,9 +2844,7 @@ describe("MatrixClient crypto bootstrapping", () => { expect(result.previousVersion).toBe("21868"); expect(result.deletedVersion).toBe("21868"); expect(result.createdVersion).toBe("21869"); - expect(bootstrapSecretStorage).toHaveBeenCalledWith( - expect.objectContaining({ setupNewKeyBackup: true }), - ); + expectSomeMockCallOptions(bootstrapSecretStorage, { setupNewKeyBackup: true }); expect(checkKeyBackupAndEnable).toHaveBeenCalledTimes(1); }); @@ -2853,12 +2894,10 @@ describe("MatrixClient crypto bootstrapping", () => { expect(result.success).toBe(true); expect(createRecoveryKeyFromPassphrase).toHaveBeenCalledTimes(1); - expect(bootstrapSecretStorage).toHaveBeenCalledWith( - expect.objectContaining({ - setupNewKeyBackup: true, - setupNewSecretStorage: true, - }), - ); + expectSomeMockCallOptions(bootstrapSecretStorage, { + setupNewKeyBackup: true, + setupNewSecretStorage: true, + }); }); it("reloads the new backup decryption key after reset when the old cached key mismatches", async () => { @@ -3007,12 +3046,10 @@ describe("MatrixClient crypto bootstrapping", () => { expect(result.createdVersion).toBe("22000"); // bootstrapSecretStorage must have been called with setupNewSecretStorage: true // because the pre-reset bad MAC status triggered forceNewSecretStorage. - expect(bootstrapSecretStorage).toHaveBeenCalledWith( - expect.objectContaining({ - setupNewKeyBackup: true, - setupNewSecretStorage: true, - }), - ); + expectSomeMockCallOptions(bootstrapSecretStorage, { + setupNewKeyBackup: true, + setupNewSecretStorage: true, + }); expect(loadSessionBackupPrivateKeyFromSecretStorage).toHaveBeenCalledTimes(1); }); @@ -3064,12 +3101,10 @@ describe("MatrixClient crypto bootstrapping", () => { expect(result.previousVersion).toBe(null); expect(result.deletedVersion).toBe(null); expect(result.createdVersion).toBe("22001"); - expect(bootstrapSecretStorage).toHaveBeenCalledWith( - expect.objectContaining({ - setupNewKeyBackup: true, - setupNewSecretStorage: true, - }), - ); + expectSomeMockCallOptions(bootstrapSecretStorage, { + setupNewKeyBackup: true, + setupNewSecretStorage: true, + }); expect(loadSessionBackupPrivateKeyFromSecretStorage).toHaveBeenCalledTimes(1); expect(doRequest).not.toHaveBeenCalledWith( "DELETE", @@ -3122,12 +3157,10 @@ describe("MatrixClient crypto bootstrapping", () => { expect(result.success).toBe(true); expect(result.createdVersion).toBe("22002"); - expect(bootstrapSecretStorage).toHaveBeenCalledWith( - expect.objectContaining({ - setupNewKeyBackup: true, - setupNewSecretStorage: true, - }), - ); + expectSomeMockCallOptions(bootstrapSecretStorage, { + setupNewKeyBackup: true, + setupNewSecretStorage: true, + }); expect(loadSessionBackupPrivateKeyFromSecretStorage).toHaveBeenCalledTimes(1); }); @@ -3307,9 +3340,7 @@ describe("MatrixClient crypto bootstrapping", () => { expect(result.success).toBe(true); expect(result.verification.backupVersion).toBe("7"); - expect(bootstrapSecretStorage).toHaveBeenCalledWith( - expect.objectContaining({ setupNewKeyBackup: true }), - ); + expectSomeMockCallOptions(bootstrapSecretStorage, { setupNewKeyBackup: true }); }); it("does not recreate key backup during bootstrap when one already exists", async () => {