import { FakeTransport } from '../../test-helpers/FakeTransport.js'; import { JsonServer } from './JsonServer.js'; describe('JsonServer', () => { beforeEach(() => { vi.spyOn(console, 'warn').mockImplementation(() => {}); }); afterEach(() => { vi.restoreAllMocks(); }); it('emits a connection for each accepted socket', () => { const sut = new JsonServer(); const onConnection = vi.fn(); sut.onConnection(onConnection); sut.accept(new FakeTransport()); sut.accept(new FakeTransport()); expect(onConnection).toHaveBeenCalledTimes(2); }); it('needs no server, no port and no http — just a transport', () => { // The whole point of the inversion: this test constructs a working server // side with nothing but a plain object. const transport = new FakeTransport(); const sut = new JsonServer<{ ping: true }, { pong: true }>(); const connection = sut.accept(transport); connection.send({ pong: true }); expect(transport.lastSentJson).toEqual({ pong: true }); }); describe('the connection it hands out', () => { it('parses what the client sends', () => { const transport = new FakeTransport(); const sut = new JsonServer<{ name: string }, never>(); const onMessage = vi.fn(); sut.accept(transport).onMessage(onMessage); transport.receiveJson({ name: 'amq' }); expect(onMessage).toHaveBeenCalledWith({ name: 'amq' }); }); it('drops a frame that is not JSON, and keeps going', () => { const transport = new FakeTransport(); const sut = new JsonServer(); const onMessage = vi.fn(); sut.accept(transport).onMessage(onMessage); transport.receive('}{ not json'); transport.receiveJson({ ok: true }); expect(console.warn).toHaveBeenCalled(); expect(onMessage).toHaveBeenCalledTimes(1); expect(onMessage).toHaveBeenCalledWith({ ok: true }); }); it('reports the socket dropping', () => { const transport = new FakeTransport(); const onClose = vi.fn(); new JsonServer().accept(transport).onClose(onClose); transport.drop(); expect(onClose).toHaveBeenCalledTimes(1); }); it('closes the transport when asked to', () => { const transport = new FakeTransport(); new JsonServer().accept(transport).close(); expect(transport.closed).toBe(true); }); }); });