Files
unisono/backend/tests/sessions.test.ts
2025-10-13 13:14:30 +03:00

181 lines
5.9 KiB
TypeScript

import request from 'supertest';
import express from 'express';
import { createServer } from 'http';
import { LLMService } from '../src/services/LLMService';
// Mock the LLMService
jest.mock('../src/services/LLMService');
// Mock the ws module
const mockHandleWebSocketMessage = jest.fn();
const mockSessions = new Map<string, any>();
const mockBroadcastToSession = jest.fn();
jest.mock('../src/ws', () => ({
sessions: mockSessions,
handleWebSocketMessage: mockHandleWebSocketMessage,
broadcastToSession: mockBroadcastToSession,
SessionState: {
SETUP: 'SETUP',
GATHERING: 'GATHERING',
HARMONIZING: 'HARMONIZING',
FINAL: 'FINAL',
ERROR: 'ERROR',
},
}));
// Mock the routes
const app = express();
app.use(express.json());
// Import the actual router after mocks are set up
import sessionsRouter from '../src/routes/sessions';
app.use('/', sessionsRouter);
describe('POST /sessions', () => {
beforeEach(() => {
mockSessions.clear();
});
it('should create a new session and return a session ID', async () => {
const response = await request(app)
.post('/sessions')
.send();
expect(response.status).toBe(201);
expect(response.body).toHaveProperty('sessionId');
expect(typeof response.body.sessionId).toBe('string');
expect(mockSessions.has(response.body.sessionId)).toBe(true);
});
});
describe('POST /sessions/:sessionId/responses', () => {
const testSessionId = 'test-session-id';
const testUserId = 'test-user-id';
beforeEach(() => {
mockSessions.clear();
mockHandleWebSocketMessage.mockClear();
mockBroadcastToSession.mockClear();
// Initialize a session for testing
mockSessions.set(testSessionId, {
state: 'GATHERING',
topic: 'Test Topic',
expectedResponses: 1,
submittedCount: 0,
responses: new Map(),
clients: new Map(),
finalResult: null,
});
});
it('should accept a response with afraidToAsk and call handleWebSocketMessage', async () => {
const responsePayload = {
userId: testUserId,
wants: ['More features'],
accepts: ['Bug fixes'],
afraidToAsk: 'A raise',
};
const response = await request(app)
.post(`/sessions/${testSessionId}/responses`)
.send(responsePayload);
expect(response.status).toBe(202);
expect(response.body).toEqual({ message: 'Response submission acknowledged and processed.' });
expect(mockHandleWebSocketMessage).toHaveBeenCalledTimes(1);
expect(mockHandleWebSocketMessage).toHaveBeenCalledWith(
expect.any(Object), // dummyWs
testSessionId,
{
type: 'SUBMIT_RESPONSE',
clientId: testUserId,
payload: {
response: {
wants: ['More features'],
accepts: ['Bug fixes'],
afraidToAsk: 'A raise',
},
},
}
);
});
it('should return 404 if session is not found', async () => {
const responsePayload = {
userId: testUserId,
wants: ['More features'],
accepts: ['Bug fixes'],
afraidToAsk: 'A raise',
};
const response = await request(app)
.post(`/sessions/non-existent-session/responses`)
.send(responsePayload);
expect(response.status).toBe(404);
expect(response.body).toEqual({ message: 'Session not found.' });
expect(mockHandleWebSocketMessage).not.toHaveBeenCalled();
});
it('should return 500 if handleWebSocketMessage throws an error', async () => {
mockHandleWebSocketMessage.mockRejectedValueOnce(new Error('WebSocket processing error'));
const responsePayload = {
userId: testUserId,
wants: ['More features'],
accepts: ['Bug fixes'],
afraidToAsk: 'A raise',
};
const response = await request(app)
.post(`/sessions/${testSessionId}/responses`)
.send(responsePayload);
expect(response.status).toBe(500);
expect(response.body).toHaveProperty('message', 'Error processing response.');
expect(response.body).toHaveProperty('error', 'WebSocket processing error');
expect(mockHandleWebSocketMessage).toHaveBeenCalledTimes(1);
});
});
describe('POST /sessions/:sessionId/terminate', () => {
const testSessionId = 'session-to-terminate';
beforeEach(() => {
mockSessions.clear();
// Initialize a session for testing termination
mockSessions.set(testSessionId, {
state: 'FINAL',
topic: 'Test Topic',
expectedResponses: 1,
submittedCount: 1,
responses: new Map([['client1', { wants: ['test'], accepts: [], noGoes: [], afraidToAsk: 'secret' }]]),
clients: new Map(),
finalResult: { goTo: 'test' },
});
});
it('should terminate the session and purge its data', async () => {
expect(mockSessions.has(testSessionId)).toBe(true);
const response = await request(app)
.post(`/sessions/${testSessionId}/terminate`)
.send();
expect(response.status).toBe(200);
expect(response.body).toEqual({ message: 'Session terminated and data purged successfully.' });
expect(mockSessions.has(testSessionId)).toBe(false);
});
it('should return 404 if session is not found', async () => {
const response = await request(app)
.post(`/sessions/non-existent-session/terminate`)
.send();
expect(response.status).toBe(404);
expect(response.body).toEqual({ message: 'Session not found.' });
});
});