181 lines
5.9 KiB
TypeScript
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.' });
|
|
});
|
|
});
|