

























@@ -116,6 +116,36 @@ type RequestTimingPayload = {
116116errorCode?: string;
117117};
118118119+function requireRecord(value: unknown, label: string): Record<string, unknown> {
120+if (!value || typeof value !== "object" || Array.isArray(value)) {
121+throw new Error(`expected ${label}`);
122+}
123+return value as Record<string, unknown>;
124+}
125+126+function requireFirstMockArg(
127+mock: ReturnType<typeof vi.fn>,
128+label: string,
129+): Record<string, unknown> {
130+const [call] = mock.mock.calls;
131+if (!call) {
132+throw new Error(`expected ${label} call`);
133+}
134+return requireRecord(call[0], `${label} payload`);
135+}
136+137+function requireFirstSignCall(): [privateKey: string, payload: string] {
138+const [call] = signDevicePayloadMock.mock.calls;
139+if (!call) {
140+throw new Error("expected device payload signing call");
141+}
142+const [privateKey, payload] = call;
143+if (typeof privateKey !== "string" || typeof payload !== "string") {
144+throw new Error("expected device payload signing args");
145+}
146+return [privateKey, payload];
147+}
148+119149function expectLatestRequestTiming(
120150onRequestTiming: ReturnType<typeof vi.fn>,
121151expected: Partial<RequestTimingPayload>,
@@ -330,23 +360,15 @@ describe("GatewayBrowserClient", () => {
330360});
331361332362expect(() => client.start()).not.toThrow();
333-const close = onClose.mock.calls[0]?.[0] as
334-| {
335-code?: number;
336-reason?: string;
337-error?: {
338-code?: string;
339-message?: string;
340-details?: { code?: string; browserErrorName?: string };
341-};
342-}
343-| undefined;
344-expect(close?.code).toBe(1006);
345-expect(close?.reason).toBe("security error");
346-expect(close?.error?.code).toBe("BROWSER_WEBSOCKET_SECURITY_ERROR");
347-expect(close?.error?.message).toContain("Use wss://");
348-expect(close?.error?.details?.code).toBe("BROWSER_WEBSOCKET_SECURITY_ERROR");
349-expect(close?.error?.details?.browserErrorName).toBe("SecurityError");
363+const close = requireFirstMockArg(onClose, "close");
364+expect(close.code).toBe(1006);
365+expect(close.reason).toBe("security error");
366+const closeError = requireRecord(close.error, "close error");
367+const closeErrorDetails = requireRecord(closeError.details, "close error details");
368+expect(closeError.code).toBe("BROWSER_WEBSOCKET_SECURITY_ERROR");
369+expect(String(closeError.message)).toContain("Use wss://");
370+expect(closeErrorDetails.code).toBe("BROWSER_WEBSOCKET_SECURITY_ERROR");
371+expect(closeErrorDetails.browserErrorName).toBe("SecurityError");
350372expect(wsInstances).toHaveLength(0);
351373352374await vi.advanceTimersByTimeAsync(30_000);
@@ -374,24 +396,16 @@ describe("GatewayBrowserClient", () => {
374396});
375397376398expect(() => client.start()).not.toThrow();
377-const close = onClose.mock.calls[0]?.[0] as
378-| {
379-code?: number;
380-reason?: string;
381-error?: {
382-code?: string;
383-message?: string;
384-details?: { code?: string; browserErrorName?: string; browserMessage?: string };
385-};
386-}
387-| undefined;
388-expect(close?.code).toBe(1006);
389-expect(close?.reason).toBe("websocket error");
390-expect(close?.error?.code).toBe("BROWSER_WEBSOCKET_CONSTRUCTOR_ERROR");
391-expect(close?.error?.message).toContain("Could not create the Gateway WebSocket");
392-expect(close?.error?.details?.code).toBe("BROWSER_WEBSOCKET_CONSTRUCTOR_ERROR");
393-expect(close?.error?.details?.browserErrorName).toBe("TypeError");
394-expect(close?.error?.details?.browserMessage).toBe("constructor failed");
399+const close = requireFirstMockArg(onClose, "close");
400+expect(close.code).toBe(1006);
401+expect(close.reason).toBe("websocket error");
402+const closeError = requireRecord(close.error, "close error");
403+const closeErrorDetails = requireRecord(closeError.details, "close error details");
404+expect(closeError.code).toBe("BROWSER_WEBSOCKET_CONSTRUCTOR_ERROR");
405+expect(String(closeError.message)).toContain("Could not create the Gateway WebSocket");
406+expect(closeErrorDetails.code).toBe("BROWSER_WEBSOCKET_CONSTRUCTOR_ERROR");
407+expect(closeErrorDetails.browserErrorName).toBe("TypeError");
408+expect(closeErrorDetails.browserMessage).toBe("constructor failed");
395409expect(wsInstances).toHaveLength(0);
396410397411await vi.advanceTimersByTimeAsync(30_000);
@@ -479,7 +493,7 @@ describe("GatewayBrowserClient", () => {
479493expect((error as { gatewayCode?: string }).gatewayCode).toBe("CONFIG_ERROR");
480494}
481495expect(onRequestTiming).toHaveBeenCalledTimes(1);
482-expect(onRequestTiming.mock.calls[0]?.[0]).not.toHaveProperty("params");
496+expect(requireFirstMockArg(onRequestTiming, "request timing")).not.toHaveProperty("params");
483497expectLatestRequestTiming(onRequestTiming, {
484498id: frame.id,
485499method: "config.get",
@@ -499,10 +513,8 @@ describe("GatewayBrowserClient", () => {
499513expect(typeof connectFrame.id).toBe("string");
500514expect(connectFrame.method).toBe("connect");
501515expect(connectFrame.params?.auth?.token).toBe("shared-auth-token");
502-const signCall = signDevicePayloadMock.mock.calls[0];
503-expect(signCall?.[0]).toBe("private-key");
504-expect(signCall?.[1]).toBeTypeOf("string");
505-const signedPayload = signCall?.[1];
516+const [privateKey, signedPayload] = requireFirstSignCall();
517+expect(privateKey).toBe("private-key");
506518expect(signedPayload).toContain("|shared-auth-token|nonce-1");
507519expect(signedPayload).not.toContain("stored-device-token");
508520});
@@ -557,10 +569,8 @@ describe("GatewayBrowserClient", () => {
557569expect(typeof connectFrame.id).toBe("string");
558570expect(connectFrame.method).toBe("connect");
559571expect(connectFrame.params?.auth?.token).toBe("stored-device-token");
560-const signCall = signDevicePayloadMock.mock.calls[0];
561-expect(signCall?.[0]).toBe("private-key");
562-expect(signCall?.[1]).toBeTypeOf("string");
563-const signedPayload = signCall?.[1];
572+const [privateKey, signedPayload] = requireFirstSignCall();
573+expect(privateKey).toBe("private-key");
564574expect(signedPayload).toContain("|stored-device-token|nonce-1");
565575});
566576@@ -581,7 +591,7 @@ describe("GatewayBrowserClient", () => {
581591582592expect(connectFrame.method).toBe("connect");
583593expect(connectFrame.params?.auth?.token).toBeUndefined();
584-const signedPayload = signDevicePayloadMock.mock.calls[0]?.[1];
594+const [, signedPayload] = requireFirstSignCall();
585595expect(signedPayload).not.toContain("under-scoped-device-token");
586596});
587597此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。