diff --git a/packages/server/src/server/websocket-server.relay-reconnect.test.ts b/packages/server/src/server/websocket-server.relay-reconnect.test.ts index bcded16c31..e49a1c2b2a 100644 --- a/packages/server/src/server/websocket-server.relay-reconnect.test.ts +++ b/packages/server/src/server/websocket-server.relay-reconnect.test.ts @@ -1,4 +1,14 @@ import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import type { Server as HTTPServer } from "http"; +import type pino from "pino"; +import type { AgentManager } from "./agent/agent-manager.js"; +import type { AgentStorage } from "./agent/agent-storage.js"; +import type { DownloadTokenStore } from "./file-download/token-store.js"; +import type { DaemonConfigStore } from "./daemon-config-store.js"; +import type { FileBackedChatService } from "./chat/chat-service.js"; +import type { LoopService } from "./loop-service.js"; +import type { ScheduleService } from "./schedule/service.js"; +import type { CheckoutDiffManager } from "./checkout-diff-manager.js"; import { asUint8Array, decodeTerminalStreamFrame, @@ -6,16 +16,18 @@ import { TerminalStreamOpcode, } from "../shared/terminal-stream-protocol.js"; +type SocketListener = (...args: unknown[]) => void; + const wsModuleMock = vi.hoisted(() => { class MockWebSocketServer { static instances: MockWebSocketServer[] = []; - readonly handlers = new Map void>(); + readonly handlers = new Map void>(); constructor(_options: unknown) { MockWebSocketServer.instances.push(this); } - on(event: string, handler: (...args: any[]) => void) { + on(event: string, handler: (...args: unknown[]) => void) { this.handlers.set(event, handler); return this; } @@ -86,22 +98,26 @@ import { VoiceAssistantWebSocketServer } from "./websocket-server"; import { parseServerInfoStatusPayload } from "./messages.js"; import type { SpeechReadinessSnapshot } from "./speech/speech-runtime.js"; +interface WebSocketServerInternals { + attachSocket(ws: unknown, req: unknown): Promise; +} + const TEST_DAEMON_VERSION = "1.2.3-test"; class MockSocket { readyState = 1; bufferedAmount = 0; sent: unknown[] = []; - private listeners = new Map void>>(); + private listeners = new Map(); - on(event: "message" | "close" | "error", listener: (...args: any[]) => void): void { + on(event: "message" | "close" | "error", listener: SocketListener): void { const handlers = this.listeners.get(event) ?? []; handlers.push(listener); this.listeners.set(event, handlers); } - once(event: "close" | "error", listener: (...args: any[]) => void): void { - const wrapped = (...args: any[]) => { + once(event: "close" | "error", listener: SocketListener): void { + const wrapped: SocketListener = (...args) => { this.off(event, wrapped); listener(...args); }; @@ -117,14 +133,14 @@ class MockSocket { this.emit("close", code ?? 1000, reason ?? ""); } - emit(event: "message" | "close" | "error", ...args: any[]): void { + emit(event: "message" | "close" | "error", ...args: unknown[]): void { const handlers = this.listeners.get(event) ?? []; for (const handler of [...handlers]) { handler(...args); } } - private off(event: "close" | "error", listener: (...args: any[]) => void): void { + private off(event: "close" | "error", listener: SocketListener): void { const handlers = this.listeners.get(event) ?? []; this.listeners.set( event, @@ -151,8 +167,8 @@ function createServer(options?: { speechReadiness?: SpeechReadinessSnapshot | nu onChange: vi.fn(() => () => {}), }; return new VoiceAssistantWebSocketServer( - {} as any, - createLogger() as any, + {} as unknown as HTTPServer, + createLogger() as unknown as pino.Logger, "srv_test", { setAgentAttentionCallback: vi.fn(), @@ -164,11 +180,11 @@ function createServer(options?: { speechReadiness?: SpeechReadinessSnapshot | nu pendingPermissionAgents: 0, erroredAgents: 0, })), - } as any, - {} as any, - {} as any, + } as unknown as AgentManager, + {} as unknown as AgentStorage, + {} as unknown as DownloadTokenStore, "/tmp/paseo-test", - daemonConfigStore as any, + daemonConfigStore as unknown as DaemonConfigStore, null, { allowedOrigins: new Set() }, speechReadiness @@ -186,9 +202,9 @@ function createServer(options?: { speechReadiness?: SpeechReadinessSnapshot | nu undefined, undefined, undefined, - {} as any, - {} as any, - {} as any, + {} as unknown as FileBackedChatService, + {} as unknown as LoopService, + {} as unknown as ScheduleService, { subscribe: vi.fn(), scheduleRefreshForCwd: vi.fn(), @@ -199,7 +215,7 @@ function createServer(options?: { speechReadiness?: SpeechReadinessSnapshot | nu checkoutDiffFallbackRefreshTargetCount: 0, })), dispose: vi.fn(), - } as any, + } as unknown as CheckoutDiffManager, ); } @@ -324,7 +340,10 @@ async function attachDirectAndHello(params: { socket: MockSocket; clientId: string; }) { - await (params.server as any).attachSocket(params.socket, createDirectRequest()); + await (params.server as unknown as WebSocketServerInternals).attachSocket( + params.socket, + createDirectRequest(), + ); params.socket.emit("message", JSON.stringify(createHelloMessage(params.clientId))); await Promise.resolve(); expect(params.socket.sent.length).toBeGreaterThan(0); @@ -391,7 +410,7 @@ describe("relay external socket reconnect behavior", () => { closeReason = typeof reason === "string" ? reason : String(reason ?? ""); }); - await (server as any).attachSocket(socket, createDirectRequest()); + await (server as unknown as WebSocketServerInternals).attachSocket(socket, createDirectRequest()); await vi.advanceTimersByTimeAsync(15_000); expect(closeCode).toBe(4001);