relay filter/appview bootstrap
1import { describe, it, expect, mock, beforeEach } from "bun:test";
2import { createWebSocketServer, broadcast, closeAllClients, getClientCount } from "../../src/services/websocket";
3import { WebSocket } from "ws";
4
5const mockSend = mock(() => {});
6const mockTerminate = mock(() => {});
7const mockOn = mock(() => {});
8
9const MockWebSocket = mock(() => ({
10 send: mockSend,
11 terminate: mockTerminate,
12 on: mockOn,
13 readyState: WebSocket.OPEN
14}));
15
16const mockWssOn = mock((event, callback) => {
17 if (event === 'connection') {
18 // Simulate a connection immediately for testing purposes if needed,
19 // but usually we trigger it manually.
20 // For now just store the callback to trigger it later.
21 (global as any).triggerConnection = callback;
22 }
23});
24
25const MockWebSocketServer = mock(() => ({
26 on: mockWssOn
27}));
28
29mock.module("ws", () => ({
30 WebSocketServer: MockWebSocketServer,
31 WebSocket: {
32 OPEN: 1,
33 ...MockWebSocket
34 }
35}));
36
37describe("WebSocket Service", () => {
38 let wss: any;
39
40 beforeEach(() => {
41 mockSend.mockClear();
42 mockTerminate.mockClear();
43 mockOn.mockClear();
44 mockWssOn.mockClear();
45 closeAllClients();
46 });
47
48 it("should create a WebSocket server", () => {
49 const mockServer = {} as any;
50 wss = createWebSocketServer(mockServer);
51 expect(MockWebSocketServer).toHaveBeenCalled();
52 expect(mockWssOn).toHaveBeenCalledWith("connection", expect.any(Function));
53 });
54
55 it("should handle client connection", () => {
56 const mockWs = new MockWebSocket();
57 (global as any).triggerConnection(mockWs);
58
59 expect(getClientCount()).toBe(1);
60 expect(mockWs.on).toHaveBeenCalledWith("close", expect.any(Function));
61 expect(mockWs.on).toHaveBeenCalledWith("error", expect.any(Function));
62 });
63
64 it("should broadcast messages to connected clients", () => {
65 const mockWs1 = new MockWebSocket();
66 const mockWs2 = new MockWebSocket();
67
68 (global as any).triggerConnection(mockWs1);
69 (global as any).triggerConnection(mockWs2);
70
71 const data = { type: "test" };
72 broadcast(data);
73
74 expect(mockSend).toHaveBeenCalledTimes(2);
75 expect(mockSend).toHaveBeenCalledWith(JSON.stringify(data));
76 });
77
78 it("should close all clients", () => {
79 const mockWs = new MockWebSocket();
80 (global as any).triggerConnection(mockWs);
81
82 expect(getClientCount()).toBe(1);
83
84 closeAllClients();
85
86 expect(mockTerminate).toHaveBeenCalled();
87 expect(getClientCount()).toBe(0);
88 });
89});