






















@@ -46,6 +46,52 @@ class MockMatrixClient {
4646}
4747}
484849+function requireRecord(value: unknown, label: string): Record<string, unknown> {
50+expect(typeof value).toBe("object");
51+expect(value).not.toBeNull();
52+if (typeof value !== "object" || value === null) {
53+throw new Error(`${label} was not an object`);
54+}
55+return value as Record<string, unknown>;
56+}
57+58+function expectRecordFields(record: Record<string, unknown>, fields: Record<string, unknown>) {
59+for (const [key, value] of Object.entries(fields)) {
60+expect(record[key]).toEqual(value);
61+}
62+}
63+64+function expectAuthFields(auth: unknown, fields: Record<string, unknown>) {
65+expectRecordFields(requireRecord(auth, "Matrix auth"), fields);
66+}
67+68+function expectSavedCredentials(
69+mock: ReturnType<typeof vi.fn>,
70+fields: Record<string, unknown>,
71+accountId: string,
72+) {
73+const call = mock.mock.calls[0] as unknown[] | undefined;
74+expect(call).toBeDefined();
75+if (!call) {
76+throw new Error("missing save credentials call");
77+}
78+expectRecordFields(requireRecord(call[0], "Matrix credentials"), fields);
79+requireRecord(call[1], "Matrix credential save options");
80+expect(call[2]).toBe(accountId);
81+}
82+83+function expectMatrixLoginCall(fields: Record<string, unknown>) {
84+const call = matrixDoRequestMock.mock.calls[0] as unknown[] | undefined;
85+expect(call).toBeDefined();
86+if (!call) {
87+throw new Error("missing Matrix login call");
88+}
89+expect(call[0]).toBe("POST");
90+expect(call[1]).toBe("/_matrix/client/v3/login");
91+expect(call[2]).toBeUndefined();
92+expectRecordFields(requireRecord(call[3], "Matrix login body"), fields);
93+}
94+4995describe("resolveMatrixAuth", () => {
5096beforeEach(() => {
5197vi.mocked(credentialsReadModule.loadMatrixCredentials).mockReset();
@@ -95,30 +141,27 @@ describe("resolveMatrixAuth", () => {
95141env: {} as NodeJS.ProcessEnv,
96142});
9714398-expect(matrixDoRequestMock).toHaveBeenCalledWith(
99-"POST",
100-"/_matrix/client/v3/login",
101-undefined,
102-expect.objectContaining({
103-type: "m.login.password",
104-}),
105-);
106-expect(auth).toMatchObject({
144+expectMatrixLoginCall({
145+type: "m.login.password",
146+identifier: { type: "m.id.user", user: "@bot:example.org" },
147+password: "secret",
148+});
149+expectAuthFields(auth, {
107150accountId: "default",
108151homeserver: "https://matrix.example.org",
109152userId: "@bot:example.org",
110153accessToken: "tok-123",
111154deviceId: "DEVICE123",
112155encryption: true,
113156});
114-expect(saveMatrixCredentialsMock).toHaveBeenCalledWith(
115-expect.objectContaining({
157+expectSavedCredentials(
158+saveMatrixCredentialsMock,
159+{
116160homeserver: "https://matrix.example.org",
117161userId: "@bot:example.org",
118162accessToken: "tok-123",
119163deviceId: "DEVICE123",
120-}),
121-expect.any(Object),
164+},
122165"default",
123166);
124167});
@@ -143,14 +186,11 @@ describe("resolveMatrixAuth", () => {
143186}),
144187).rejects.toThrow("Invalid username or password");
145188146-expect(matrixDoRequestMock).toHaveBeenCalledWith(
147-"POST",
148-"/_matrix/client/v3/login",
149-undefined,
150-expect.objectContaining({
151-type: "m.login.password",
152-}),
153-);
189+expectMatrixLoginCall({
190+type: "m.login.password",
191+identifier: { type: "m.id.user", user: "@bot:example.org" },
192+password: "secret",
193+});
154194expect(saveMatrixCredentialsMock).not.toHaveBeenCalled();
155195});
156196@@ -179,7 +219,7 @@ describe("resolveMatrixAuth", () => {
179219env: {} as NodeJS.ProcessEnv,
180220});
181221182-expect(auth).toMatchObject({
222+expectAuthFields(auth, {
183223accountId: "default",
184224homeserver: "https://matrix.example.org",
185225userId: "@bot:example.org",
@@ -216,7 +256,7 @@ describe("resolveMatrixAuth", () => {
216256accountId: "ops",
217257});
218258219-expect(auth).toMatchObject({
259+expectAuthFields(auth, {
220260accountId: "ops",
221261homeserver: "https://matrix.example.org",
222262userId: "@ops:example.org",
@@ -266,14 +306,14 @@ describe("resolveMatrixAuth", () => {
266306267307expect(auth.deviceId).toBe("DEVICE123");
268308expect(auth.accountId).toBe("default");
269-expect(saveMatrixCredentialsMock).toHaveBeenCalledWith(
270-expect.objectContaining({
309+expectSavedCredentials(
310+saveMatrixCredentialsMock,
311+{
271312homeserver: "https://matrix.example.org",
272313userId: "@bot:example.org",
273314accessToken: "tok-123",
274315deviceId: "DEVICE123",
275-}),
276-expect.any(Object),
316+},
277317"default",
278318);
279319});
@@ -293,7 +333,7 @@ describe("resolveMatrixAuth", () => {
293333294334const auth = await resolveMatrixAuth({ cfg, env: {} as NodeJS.ProcessEnv });
295335296-expect(auth).toMatchObject({
336+expectAuthFields(auth, {
297337homeserver: "http://127.0.0.1:8008",
298338allowPrivateNetwork: true,
299339ssrfPolicy: { allowPrivateNetwork: true },
@@ -363,17 +403,12 @@ describe("resolveMatrixAuth", () => {
363403accountId: "ops",
364404});
365405366-expect(matrixDoRequestMock).toHaveBeenCalledWith(
367-"POST",
368-"/_matrix/client/v3/login",
369-undefined,
370-expect.objectContaining({
371-type: "m.login.password",
372-identifier: { type: "m.id.user", user: "@ops:example.org" },
373-password: "ops-pass",
374-}),
375-);
376-expect(auth).toMatchObject({
406+expectMatrixLoginCall({
407+type: "m.login.password",
408+identifier: { type: "m.id.user", user: "@ops:example.org" },
409+password: "ops-pass",
410+});
411+expectAuthFields(auth, {
377412accountId: "ops",
378413homeserver: "https://matrix.example.org",
379414userId: "@ops:example.org",
@@ -404,7 +439,7 @@ describe("resolveMatrixAuth", () => {
404439});
405440406441expect(matrixDoRequestMock).toHaveBeenCalledWith("GET", "/_matrix/client/v3/account/whoami");
407-expect(auth).toMatchObject({
442+expectAuthFields(auth, {
408443accountId: "default",
409444homeserver: "https://matrix.example.org",
410445userId: "@bot:example.org",
@@ -443,7 +478,7 @@ describe("resolveMatrixAuth", () => {
443478});
444479445480expect(matrixDoRequestMock).toHaveBeenCalledTimes(2);
446-expect(auth).toMatchObject({
481+expectAuthFields(auth, {
447482userId: "@bot:example.org",
448483deviceId: "DEVICE123",
449484});
@@ -469,7 +504,7 @@ describe("resolveMatrixAuth", () => {
469504});
470505471506expect(matrixDoRequestMock).not.toHaveBeenCalled();
472-expect(auth).toMatchObject({
507+expectAuthFields(auth, {
473508accountId: "default",
474509homeserver: "https://matrix.example.org",
475510userId: "@bot:example.org",
@@ -510,7 +545,7 @@ describe("resolveMatrixAuth", () => {
510545});
511546512547expect(matrixDoRequestMock).toHaveBeenCalledTimes(2);
513-expect(auth).toMatchObject({
548+expectAuthFields(auth, {
514549accessToken: "tok-123",
515550deviceId: "DEVICE123",
516551});
@@ -533,24 +568,28 @@ describe("resolveMatrixAuth", () => {
533568});
534569535570expect(matrixDoRequestMock).toHaveBeenCalledWith("GET", "/_matrix/client/v3/account/whoami");
536-expect(saveBackfilledMatrixDeviceIdMock).toHaveBeenCalledWith(
571+expectSavedCredentials(
572+saveBackfilledMatrixDeviceIdMock,
537573{
538574homeserver: "https://matrix.example.org",
539575userId: "@bot:example.org",
540576accessToken: "tok-123",
541577deviceId: "DEVICE123",
542578},
543-expect.any(Object),
544579"default",
545580);
546-expect(repairCurrentTokenStorageMetaDeviceIdMock).toHaveBeenCalledWith({
581+const repairMeta = requireRecord(
582+repairCurrentTokenStorageMetaDeviceIdMock.mock.calls[0]?.[0],
583+"repair metadata",
584+);
585+expectRecordFields(repairMeta, {
547586homeserver: "https://matrix.example.org",
548587userId: "@bot:example.org",
549588accessToken: "tok-123",
550589accountId: "default",
551590deviceId: "DEVICE123",
552-env: expect.any(Object),
553591});
592+requireRecord(repairMeta.env, "repair env");
554593expect(repairCurrentTokenStorageMetaDeviceIdMock.mock.invocationCallOrder[0]).toBeLessThan(
555594saveBackfilledMatrixDeviceIdMock.mock.invocationCallOrder[0],
556595);
@@ -689,15 +728,16 @@ describe("resolveMatrixAuth", () => {
689728env: {} as NodeJS.ProcessEnv,
690729});
691730692-expect(resolveConfiguredSecretInputStringMock).toHaveBeenCalledWith(
693-expect.objectContaining({
731+expectRecordFields(
732+requireRecord(resolveConfiguredSecretInputStringMock.mock.calls[0]?.[0], "secret request"),
733+{
694734config: cfg,
695735value: { source: "file", provider: "matrix-file", id: "value" },
696736path: "channels.matrix.accessToken",
697-}),
737+},
698738);
699739expect(matrixDoRequestMock).toHaveBeenCalledWith("GET", "/_matrix/client/v3/account/whoami");
700-expect(auth).toMatchObject({
740+expectAuthFields(auth, {
701741accountId: "default",
702742homeserver: "https://matrix.example.org",
703743userId: "@bot:example.org",
@@ -741,7 +781,7 @@ describe("resolveMatrixAuth", () => {
741781});
742782743783expect(matrixDoRequestMock).toHaveBeenCalledWith("GET", "/_matrix/client/v3/account/whoami");
744-expect(auth).toMatchObject({
784+expectAuthFields(auth, {
745785accountId: "ops",
746786homeserver: "https://matrix.example.org",
747787userId: "@ops:example.org",
@@ -773,7 +813,7 @@ describe("resolveMatrixAuth", () => {
773813774814const auth = await resolveMatrixAuth({ cfg, env: {} as NodeJS.ProcessEnv });
775815776-expect(auth).toMatchObject({
816+expectAuthFields(auth, {
777817accountId: "default",
778818homeserver: "https://matrix.example.org",
779819userId: "@bot:example.org",
@@ -802,22 +842,22 @@ describe("resolveMatrixAuth", () => {
802842803843const auth = await resolveMatrixAuth({ cfg, env: {} as NodeJS.ProcessEnv });
804844805-expect(auth).toMatchObject({
845+expectAuthFields(auth, {
806846accountId: "ops",
807847homeserver: "https://ops.example.org",
808848userId: "@ops:example.org",
809849accessToken: "ops-token",
810850deviceId: "OPSDEVICE",
811851encryption: true,
812852});
813-expect(saveMatrixCredentialsMock).toHaveBeenCalledWith(
814-expect.objectContaining({
853+expectSavedCredentials(
854+saveMatrixCredentialsMock,
855+{
815856homeserver: "https://ops.example.org",
816857userId: "@ops:example.org",
817858accessToken: "ops-token",
818859deviceId: "OPSDEVICE",
819-}),
820-expect.any(Object),
860+},
821861"ops",
822862);
823863});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。