Files
PaperClipAI/ui/src/lib/websocket.test.ts
T
Devin FoleyandPaperclip c65fc9e3c8 fix: recover authentication and browser connection failures (#13724)
fix: recover authentication and browser connection failures

Include connect timeouts in the bounded retry policy for idempotent actor
synchronization. Handle WebSocket constructor failures through existing
reconnect paths and preserve HTTP polling while realtime is unavailable.
Refresh visible company queries until the socket recovers and clear all
fallback timers on hiding or unmount.

Verify 172 focused tests, server/UI typechecks, UI build, and design token
gates. Full workspace build/typecheck require the unavailable Rust toolchain;
the full test run is tracked separately.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-20 12:43:25 -07:00

29 lines
1.1 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "vitest";
import { tryCreateWebSocket } from "./websocket";
afterEach(() => vi.unstubAllGlobals());
describe("tryCreateWebSocket", () => {
it.each([undefined, {}, () => undefined])("returns null for an unavailable constructor: %s", (value) => {
vi.stubGlobal("WebSocket", value);
expect(tryCreateWebSocket("ws://localhost/events")).toBeNull();
});
it("returns null when browser policy prevents construction", () => {
vi.stubGlobal("WebSocket", class {
constructor() { throw new DOMException("Blocked", "SecurityError"); }
});
expect(tryCreateWebSocket("ws://localhost/events")).toBeNull();
});
it("uses the current constructor so a later retry can recover", () => {
vi.stubGlobal("WebSocket", undefined);
expect(tryCreateWebSocket("ws://localhost/events")).toBeNull();
class Socket {
constructor(readonly url: string) {}
}
vi.stubGlobal("WebSocket", Socket);
expect(tryCreateWebSocket("ws://localhost/events")).toEqual(new Socket("ws://localhost/events"));
});
});