146 lines
3.7 KiB
TypeScript
146 lines
3.7 KiB
TypeScript
import { test, expect, describe, beforeEach } from "bun:test";
|
|
import { ClientManager } from "../src/services/ClientManager.ts";
|
|
import type { IWebSocketClient } from "../src/interfaces/ISignalingMessage.ts";
|
|
|
|
class MockWebSocket {
|
|
sentMessages: string[] = [];
|
|
closed = false;
|
|
|
|
send(data: string) {
|
|
this.sentMessages.push(data);
|
|
}
|
|
|
|
close() {
|
|
this.closed = true;
|
|
}
|
|
}
|
|
|
|
describe("ClientManager", () => {
|
|
let clientManager: ClientManager;
|
|
let mockWs: MockWebSocket;
|
|
|
|
beforeEach(() => {
|
|
clientManager = new ClientManager();
|
|
mockWs = new MockWebSocket();
|
|
});
|
|
|
|
test("should add a publisher client", () => {
|
|
const client: IWebSocketClient = {
|
|
id: "publisher-1",
|
|
ws: mockWs,
|
|
role: "publisher"
|
|
};
|
|
|
|
clientManager.addClient(client);
|
|
|
|
expect(clientManager.getClient("publisher-1")).toBe(client);
|
|
expect(clientManager.getPublisher()).toBe(client);
|
|
});
|
|
|
|
test("should add subscriber clients", () => {
|
|
const subscriber1: IWebSocketClient = {
|
|
id: "subscriber-1",
|
|
ws: mockWs,
|
|
role: "subscriber"
|
|
};
|
|
|
|
const subscriber2: IWebSocketClient = {
|
|
id: "subscriber-2",
|
|
ws: new MockWebSocket(),
|
|
role: "subscriber"
|
|
};
|
|
|
|
clientManager.addClient(subscriber1);
|
|
clientManager.addClient(subscriber2);
|
|
|
|
const subscribers = clientManager.getSubscribers();
|
|
expect(subscribers).toHaveLength(2);
|
|
expect(subscribers).toContain(subscriber1);
|
|
expect(subscribers).toContain(subscriber2);
|
|
});
|
|
|
|
test("should notify subscribers when publisher joins", () => {
|
|
const subscriber1: IWebSocketClient = {
|
|
id: "subscriber-1",
|
|
ws: mockWs,
|
|
role: "subscriber"
|
|
};
|
|
|
|
const subscriber2: IWebSocketClient = {
|
|
id: "subscriber-2",
|
|
ws: new MockWebSocket(),
|
|
role: "subscriber"
|
|
};
|
|
|
|
clientManager.addClient(subscriber1);
|
|
clientManager.addClient(subscriber2);
|
|
|
|
const publisher: IWebSocketClient = {
|
|
id: "publisher-1",
|
|
ws: new MockWebSocket(),
|
|
role: "publisher"
|
|
};
|
|
|
|
clientManager.addClient(publisher);
|
|
|
|
expect(mockWs.sentMessages).toContain(
|
|
JSON.stringify({ type: 'publisher-joined' })
|
|
);
|
|
expect((subscriber2.ws as MockWebSocket).sentMessages).toContain(
|
|
JSON.stringify({ type: 'publisher-joined' })
|
|
);
|
|
});
|
|
|
|
test("should remove client and notify subscribers when publisher leaves", () => {
|
|
const subscriber: IWebSocketClient = {
|
|
id: "subscriber-1",
|
|
ws: mockWs,
|
|
role: "subscriber"
|
|
};
|
|
|
|
const publisher: IWebSocketClient = {
|
|
id: "publisher-1",
|
|
ws: new MockWebSocket(),
|
|
role: "publisher"
|
|
};
|
|
|
|
clientManager.addClient(subscriber);
|
|
clientManager.addClient(publisher);
|
|
|
|
clientManager.removeClient("publisher-1");
|
|
|
|
expect(clientManager.getClient("publisher-1")).toBeUndefined();
|
|
expect(clientManager.getPublisher()).toBeNull();
|
|
expect(mockWs.sentMessages).toContain(
|
|
JSON.stringify({ type: 'publisher-left' })
|
|
);
|
|
});
|
|
|
|
test("should handle removing non-existent client", () => {
|
|
expect(() => {
|
|
clientManager.removeClient("non-existent");
|
|
}).not.toThrow();
|
|
});
|
|
|
|
test("should get all clients", () => {
|
|
const publisher: IWebSocketClient = {
|
|
id: "publisher-1",
|
|
ws: mockWs,
|
|
role: "publisher"
|
|
};
|
|
|
|
const subscriber: IWebSocketClient = {
|
|
id: "subscriber-1",
|
|
ws: new MockWebSocket(),
|
|
role: "subscriber"
|
|
};
|
|
|
|
clientManager.addClient(publisher);
|
|
clientManager.addClient(subscriber);
|
|
|
|
const allClients = clientManager.getAllClients();
|
|
expect(allClients).toHaveLength(2);
|
|
expect(allClients).toContain(publisher);
|
|
expect(allClients).toContain(subscriber);
|
|
});
|
|
}); |