From 46dcf4ef7897160cdb26c633ca6d89b4c2eb190e Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 10 May 2026 11:49:17 +0100 Subject: [PATCH] test: clear device pairing broad matchers --- src/infra/device-pairing.test.ts | 277 +++++++++++++++++-------------- 1 file changed, 155 insertions(+), 122 deletions(-) diff --git a/src/infra/device-pairing.test.ts b/src/infra/device-pairing.test.ts index 07e13808aa7..7c2e7b67baf 100644 --- a/src/infra/device-pairing.test.ts +++ b/src/infra/device-pairing.test.ts @@ -82,6 +82,38 @@ function requireValue(value: T | null | undefined, message: string): T { return value; } +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); +} + +function requireRecord(value: unknown, message: string): Record { + if (!isRecord(value)) { + throw new Error(message); + } + return value; +} + +function expectRecordFields( + value: unknown, + message: string, + expected: Record, +): Record { + const record = requireRecord(value, message); + for (const [key, expectedValue] of Object.entries(expected)) { + expect(record[key], `${message}.${key}`).toEqual(expectedValue); + } + return record; +} + +function expectArrayIncludesAll(value: unknown, expected: readonly unknown[], message: string) { + expect(Array.isArray(value), `${message} must be an array`).toBe(true); + for (const expectedValue of expected) { + expect(value as unknown[], `${message} must include ${String(expectedValue)}`).toContain( + expectedValue, + ); + } +} + function requireRotatedEntry(result: RotateDeviceTokenResult) { expect(result.ok).toBe(true); if (!result.ok) { @@ -183,18 +215,20 @@ describe("device pairing tokens", () => { baseDir, ); - expect(approved).toEqual( - expect.objectContaining({ - status: "approved", - device: expect.objectContaining({ deviceId: "device-array-state" }), - }), - ); + const approvedRecord = expectRecordFields(approved, "approved result", { + status: "approved", + }); + expectRecordFields(approvedRecord.device, "approved device", { + deviceId: "device-array-state", + }); expect(Array.isArray(JSON.parse(await readFile(paths.pendingPath, "utf8")))).toBe(false); - expect(JSON.parse(await readFile(paths.pairedPath, "utf8"))).toEqual( - expect.objectContaining({ - "device-array-state": expect.objectContaining({ deviceId: "device-array-state" }), - }), + const pairedByDeviceId = requireRecord( + JSON.parse(await readFile(paths.pairedPath, "utf8")), + "paired devices", ); + expectRecordFields(pairedByDeviceId["device-array-state"], "paired device", { + deviceId: "device-array-state", + }); }); test("re-requesting with identical params preserves the original ts to prevent queue-jumping", async () => { @@ -263,9 +297,11 @@ describe("device pairing tokens", () => { expect(second.created).toBe(true); expect(second.request.requestId).not.toBe(first.request.requestId); expect(second.request.role).toBe("operator"); - expect(second.request.roles).toEqual(expect.arrayContaining(["node", "operator"])); - expect(second.request.scopes).toEqual( - expect.arrayContaining(["operator.read", "operator.write"]), + expectArrayIncludesAll(second.request.roles, ["node", "operator"], "request roles"); + expectArrayIncludesAll( + second.request.scopes, + ["operator.read", "operator.write"], + "request scopes", ); const list = await listDevicePairing(baseDir); @@ -278,8 +314,8 @@ describe("device pairing tokens", () => { baseDir, ); const paired = await getPairedDevice("device-1", baseDir); - expect(paired?.roles).toEqual(expect.arrayContaining(["node", "operator"])); - expect(paired?.scopes).toEqual(expect.arrayContaining(["operator.read", "operator.write"])); + expectArrayIncludesAll(paired?.roles, ["node", "operator"], "paired roles"); + expectArrayIncludesAll(paired?.scopes, ["operator.read", "operator.write"], "paired scopes"); }); test("approves mixed node and operator requests with admin caller scopes", async () => { @@ -294,13 +330,12 @@ describe("device pairing tokens", () => { baseDir, ); - await expect( - approveDevicePairing( - request.request.requestId, - { callerScopes: ["operator.admin", "operator.pairing"] }, - baseDir, - ), - ).resolves.toMatchObject({ + const approved = await approveDevicePairing( + request.request.requestId, + { callerScopes: ["operator.admin", "operator.pairing"] }, + baseDir, + ); + expectRecordFields(approved, "approved result", { status: "approved", requestId: request.request.requestId, }); @@ -347,13 +382,12 @@ describe("device pairing tokens", () => { baseDir, ); - await expect( - approveDevicePairing( - upgrade.request.requestId, - { callerScopes: ["operator.read", "operator.write"] }, - baseDir, - ), - ).resolves.toMatchObject({ status: "approved" }); + const approved = await approveDevicePairing( + upgrade.request.requestId, + { callerScopes: ["operator.read", "operator.write"] }, + baseDir, + ); + expectRecordFields(approved, "approved result", { status: "approved" }); const paired = await getPairedDevice("device-1", baseDir); expect(paired?.approvedScopes).toEqual(["operator.read", "operator.write"]); @@ -375,13 +409,12 @@ describe("device pairing tokens", () => { baseDir, ); - await expect( - approveDevicePairing( - upgrade.request.requestId, - { callerScopes: ["operator.read", "operator.talk.secrets", "operator.write"] }, - baseDir, - ), - ).resolves.toMatchObject({ status: "approved" }); + const approved = await approveDevicePairing( + upgrade.request.requestId, + { callerScopes: ["operator.read", "operator.talk.secrets", "operator.write"] }, + baseDir, + ); + expectRecordFields(approved, "approved result", { status: "approved" }); const paired = await getPairedDevice("device-1", baseDir); expect(paired?.approvedScopes).toEqual([ @@ -405,7 +438,8 @@ describe("device pairing tokens", () => { baseDir, ); - await expect(approveDevicePairing(request.request.requestId, baseDir)).resolves.toMatchObject({ + const approved = await approveDevicePairing(request.request.requestId, baseDir); + expectRecordFields(approved, "approved result", { status: "approved", requestId: request.request.requestId, }); @@ -482,7 +516,8 @@ describe("device pairing tokens", () => { }, baseDir, ); - await expect(approveDevicePairing(initial.request.requestId, baseDir)).resolves.toMatchObject({ + const approvedInitial = await approveDevicePairing(initial.request.requestId, baseDir); + expectRecordFields(approvedInitial, "initial approved result", { status: "approved", requestId: initial.request.requestId, }); @@ -496,9 +531,12 @@ describe("device pairing tokens", () => { }, baseDir, ); - await expect( - approveDevicePairing(repair.request.requestId, { callerScopes: ["operator.read"] }, baseDir), - ).resolves.toMatchObject({ + const approvedRepair = await approveDevicePairing( + repair.request.requestId, + { callerScopes: ["operator.read"] }, + baseDir, + ); + expectRecordFields(approvedRepair, "repair approved result", { status: "approved", requestId: repair.request.requestId, }); @@ -616,20 +654,17 @@ describe("device pairing tokens", () => { scope: "operator.admin", }); - await expect( - approveDevicePairing( - request.request.requestId, - { - callerScopes: ["operator.admin"], - }, - baseDir, - ), - ).resolves.toEqual( - expect.objectContaining({ - status: "approved", - requestId: request.request.requestId, - }), + const approved = await approveDevicePairing( + request.request.requestId, + { + callerScopes: ["operator.admin"], + }, + baseDir, ); + expectRecordFields(approved, "approved result", { + status: "approved", + requestId: request.request.requestId, + }); }); test("metadata refresh cannot mutate approved role and scope fields", async () => { @@ -657,7 +692,7 @@ describe("device pairing tokens", () => { expect(paired?.roles).toEqual(["node"]); expect(paired?.scopes).toStrictEqual([]); expect(paired?.approvedScopes).toStrictEqual([]); - expect(paired?.tokens?.node).toMatchObject({ token: expect.any(String) }); + expect(typeof paired?.tokens?.node?.token).toBe("string"); expect(paired?.tokens?.operator).toBeUndefined(); }); @@ -680,12 +715,10 @@ describe("device pairing tokens", () => { ); const paired = await getPairedDevice("node-1", baseDir); - expect(paired).toEqual( - expect.objectContaining({ - lastSeenAtMs: 4321, - lastSeenReason: "bg_app_refresh", - }), - ); + expectRecordFields(paired, "paired device", { + lastSeenAtMs: 4321, + lastSeenReason: "bg_app_refresh", + }); }); test("generates base64url device tokens with 256-bit entropy output length", async () => { @@ -866,13 +899,14 @@ describe("device pairing tokens", () => { callerScopes: ["operator.admin"], baseDir, }); - expect(revoked).toEqual({ - ok: true, - entry: expect.objectContaining({ - role: "operator", - revokedAtMs: expect.any(Number), - }), + expect(revoked.ok).toBe(true); + if (!revoked.ok) { + throw new Error(`expected revoked token entry, got ${revoked.reason}`); + } + expectRecordFields(revoked.entry, "revoked entry", { + role: "operator", }); + expect(revoked.entry.revokedAtMs).toBeTypeOf("number"); const after = await getPairedDevice("device-1", baseDir); expect(after?.tokens?.operator?.revokedAtMs).toBeTypeOf("number"); @@ -907,14 +941,13 @@ describe("device pairing tokens", () => { expect(paired?.approvedScopes).toStrictEqual([]); const seededToken = requireToken(paired?.tokens?.node?.token); - await expect( - ensureDeviceToken({ - deviceId: "node-1", - role: "node", - scopes: [], - baseDir, - }), - ).resolves.toEqual(expect.objectContaining({ token: seededToken, scopes: [] })); + const ensured = await ensureDeviceToken({ + deviceId: "node-1", + role: "node", + scopes: [], + baseDir, + }); + expectRecordFields(ensured, "ensured token", { token: seededToken, scopes: [] }); await expect( verifyDeviceToken({ @@ -966,22 +999,25 @@ describe("device pairing tokens", () => { baseDir, ); - await expect( - approveBootstrapDevicePairing( - request.request.requestId, - PAIRING_SETUP_BOOTSTRAP_PROFILE, - baseDir, - ), - ).resolves.toEqual(expect.objectContaining({ status: "approved" })); + const approved = await approveBootstrapDevicePairing( + request.request.requestId, + PAIRING_SETUP_BOOTSTRAP_PROFILE, + baseDir, + ); + expectRecordFields(approved, "approved result", { status: "approved" }); const paired = await getPairedDevice("bootstrap-device-1", baseDir); - expect(paired?.roles).toEqual(expect.arrayContaining(["node", "operator"])); - expect(paired?.approvedScopes).toEqual( - expect.arrayContaining(PAIRING_SETUP_BOOTSTRAP_PROFILE.scopes), + expectArrayIncludesAll(paired?.roles, ["node", "operator"], "paired roles"); + expectArrayIncludesAll( + paired?.approvedScopes, + PAIRING_SETUP_BOOTSTRAP_PROFILE.scopes, + "paired approved scopes", ); expect(paired?.tokens?.node?.scopes).toStrictEqual([]); - expect(paired?.tokens?.operator?.scopes).toEqual( - expect.arrayContaining(PAIRING_SETUP_BOOTSTRAP_PROFILE.scopes), + expectArrayIncludesAll( + paired?.tokens?.operator?.scopes, + PAIRING_SETUP_BOOTSTRAP_PROFILE.scopes, + "operator token scopes", ); }); @@ -999,16 +1035,15 @@ describe("device pairing tokens", () => { baseDir, ); - await expect( - approveBootstrapDevicePairing( - request.request.requestId, - { - roles: ["node", "operator"], - scopes: ["node.exec", "operator.pairing", "operator.read", "operator.write"], - }, - baseDir, - ), - ).resolves.toEqual(expect.objectContaining({ status: "approved" })); + const approved = await approveBootstrapDevicePairing( + request.request.requestId, + { + roles: ["node", "operator"], + scopes: ["node.exec", "operator.pairing", "operator.read", "operator.write"], + }, + baseDir, + ); + expectRecordFields(approved, "approved result", { status: "approved" }); const paired = await getPairedDevice("bootstrap-device-operator-scope", baseDir); expect(paired?.tokens?.operator?.scopes).toEqual(["operator.read", "operator.write"]); @@ -1029,24 +1064,23 @@ describe("device pairing tokens", () => { baseDir, ); - await expect( - approveBootstrapDevicePairing( - request.request.requestId, - { - roles: ["node", "operator"], - scopes: [ - "node.exec", - "operator.admin", - "operator.approvals", - "operator.pairing", - "operator.read", - "operator.talk.secrets", - "operator.write", - ], - }, - baseDir, - ), - ).resolves.toEqual(expect.objectContaining({ status: "approved" })); + const approved = await approveBootstrapDevicePairing( + request.request.requestId, + { + roles: ["node", "operator"], + scopes: [ + "node.exec", + "operator.admin", + "operator.approvals", + "operator.pairing", + "operator.read", + "operator.talk.secrets", + "operator.write", + ], + }, + baseDir, + ); + expectRecordFields(approved, "approved result", { status: "approved" }); const paired = await getPairedDevice("bootstrap-device-bounded-baseline", baseDir); expect(paired?.approvedScopes).toEqual([ @@ -1107,13 +1141,12 @@ describe("device pairing tokens", () => { }, baseDir, ); - await expect( - approveBootstrapDevicePairing( - repair.request.requestId, - PAIRING_SETUP_BOOTSTRAP_PROFILE, - baseDir, - ), - ).resolves.toEqual(expect.objectContaining({ status: "approved" })); + const approved = await approveBootstrapDevicePairing( + repair.request.requestId, + PAIRING_SETUP_BOOTSTRAP_PROFILE, + baseDir, + ); + expectRecordFields(approved, "approved result", { status: "approved" }); const paired = await getPairedDevice("bootstrap-device-legacy-baseline", baseDir); expect(paired?.approvedScopes).toEqual(PAIRING_SETUP_BOOTSTRAP_PROFILE.scopes);