


























@@ -106,6 +106,34 @@ type ConnectFrame = {
106106};
107107};
108108109+type RequestTimingPayload = {
110+id?: string;
111+method?: string;
112+ok?: boolean;
113+durationMs?: number;
114+startedAtMs?: number;
115+endedAtMs?: number;
116+errorCode?: string;
117+};
118+119+function expectLatestRequestTiming(
120+onRequestTiming: ReturnType<typeof vi.fn>,
121+expected: Partial<RequestTimingPayload>,
122+) {
123+const timing = onRequestTiming.mock.calls.at(-1)?.[0] as RequestTimingPayload | undefined;
124+expect(timing).toMatchObject(expected);
125+expect(timing?.startedAtMs).toBeTypeOf("number");
126+expect(timing?.endedAtMs).toBeTypeOf("number");
127+expect(timing?.durationMs).toBeTypeOf("number");
128+if (
129+typeof timing?.startedAtMs === "number" &&
130+typeof timing.endedAtMs === "number" &&
131+typeof timing.durationMs === "number"
132+) {
133+expect(timing.durationMs).toBe(Math.max(0, timing.endedAtMs - timing.startedAtMs));
134+}
135+}
136+109137function stubWindowGlobals(storage?: ReturnType<typeof createStorageMock>) {
110138vi.stubGlobal("window", {
111139location: { href: "http://127.0.0.1:18789/" },
@@ -282,14 +310,11 @@ describe("GatewayBrowserClient", () => {
282310});
283311284312await expect(request).resolves.toEqual({ sessions: [] });
285-expect(onRequestTiming).toHaveBeenCalledWith(
286-expect.objectContaining({
287-id: frame.id,
288-method: "sessions.list",
289-ok: true,
290-durationMs: expect.any(Number),
291-}),
292-);
313+expectLatestRequestTiming(onRequestTiming, {
314+id: frame.id,
315+method: "sessions.list",
316+ok: true,
317+});
293318});
294319295320it("reports failed request timing without including request params", async () => {
@@ -330,15 +355,12 @@ describe("GatewayBrowserClient", () => {
330355params: expect.anything(),
331356}),
332357);
333-expect(onRequestTiming).toHaveBeenCalledWith(
334-expect.objectContaining({
335-id: frame.id,
336-method: "config.get",
337-ok: false,
338-errorCode: "CONFIG_ERROR",
339-durationMs: expect.any(Number),
340-}),
341-);
358+expectLatestRequestTiming(onRequestTiming, {
359+id: frame.id,
360+method: "config.get",
361+ok: false,
362+errorCode: "CONFIG_ERROR",
363+});
342364});
343365344366it("prefers explicit shared auth over cached device tokens", async () => {
@@ -352,8 +374,10 @@ describe("GatewayBrowserClient", () => {
352374expect(typeof connectFrame.id).toBe("string");
353375expect(connectFrame.method).toBe("connect");
354376expect(connectFrame.params?.auth?.token).toBe("shared-auth-token");
355-expect(signDevicePayloadMock).toHaveBeenCalledWith("private-key", expect.any(String));
356-const signedPayload = signDevicePayloadMock.mock.calls[0]?.[1];
377+const signCall = signDevicePayloadMock.mock.calls[0];
378+expect(signCall?.[0]).toBe("private-key");
379+expect(signCall?.[1]).toBeTypeOf("string");
380+const signedPayload = signCall?.[1];
357381expect(signedPayload).toContain("|shared-auth-token|nonce-1");
358382expect(signedPayload).not.toContain("stored-device-token");
359383});
@@ -408,8 +432,10 @@ describe("GatewayBrowserClient", () => {
408432expect(typeof connectFrame.id).toBe("string");
409433expect(connectFrame.method).toBe("connect");
410434expect(connectFrame.params?.auth?.token).toBe("stored-device-token");
411-expect(signDevicePayloadMock).toHaveBeenCalledWith("private-key", expect.any(String));
412-const signedPayload = signDevicePayloadMock.mock.calls[0]?.[1];
435+const signCall = signDevicePayloadMock.mock.calls[0];
436+expect(signCall?.[0]).toBe("private-key");
437+expect(signCall?.[1]).toBeTypeOf("string");
438+const signedPayload = signCall?.[1];
413439expect(signedPayload).toContain("|stored-device-token|nonce-1");
414440});
415441此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。