feat: add PairingManager and gateway lock tests (Tier 4 feature 4 foundation)
This commit is contained in:
@@ -219,6 +219,102 @@ describe('GatewayServer integration', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GatewayServer lock mode', () => {
|
||||
const LOCK_PORT = 18897;
|
||||
let lockServer: GatewayServer;
|
||||
|
||||
beforeAll(async () => {
|
||||
lockServer = new GatewayServer({
|
||||
port: LOCK_PORT,
|
||||
sessionManager: mockSessionManager as unknown as GatewayServerConfig['sessionManager'],
|
||||
modelClient: mockModelClient,
|
||||
systemPrompt: 'Test prompt',
|
||||
toolRegistry: mockToolRegistry as unknown as GatewayServerConfig['toolRegistry'],
|
||||
toolExecutor: mockToolExecutor as unknown as GatewayServerConfig['toolExecutor'],
|
||||
lock: true,
|
||||
uiDir: resolve(import.meta.dirname, 'ui'),
|
||||
});
|
||||
await lockServer.start();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await lockServer.stop();
|
||||
});
|
||||
|
||||
function createLockClient(): Promise<WebSocket> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const ws = new WebSocket(`ws://127.0.0.1:${LOCK_PORT}`);
|
||||
ws.on('open', () => resolve(ws));
|
||||
ws.on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
it('allows the first client to connect', async () => {
|
||||
const ws = await createLockClient();
|
||||
try {
|
||||
const result = await sendAndReceive(ws, { id: 1, method: 'system.health' });
|
||||
const response = result as GatewayResponse;
|
||||
expect((response.result as any).status).toBe('ok');
|
||||
} finally {
|
||||
ws.close();
|
||||
// Wait for the close to propagate so connectionMap is empty
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
}
|
||||
});
|
||||
|
||||
it('rejects second client with code 4003 when locked', async () => {
|
||||
const ws1 = await createLockClient();
|
||||
try {
|
||||
// Second client should be rejected
|
||||
const closePromise = new Promise<{ code: number; reason: string }>((resolve) => {
|
||||
const ws2 = new WebSocket(`ws://127.0.0.1:${LOCK_PORT}`);
|
||||
ws2.on('close', (code, reason) => {
|
||||
resolve({ code, reason: reason.toString() });
|
||||
});
|
||||
});
|
||||
|
||||
const { code, reason } = await closePromise;
|
||||
expect(code).toBe(4003);
|
||||
expect(reason).toContain('locked');
|
||||
} finally {
|
||||
ws1.close();
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
}
|
||||
});
|
||||
|
||||
it('allows a new client after the previous one disconnects', async () => {
|
||||
const ws1 = await createLockClient();
|
||||
ws1.close();
|
||||
// Wait for the close to propagate
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
|
||||
const ws2 = await createLockClient();
|
||||
try {
|
||||
const result = await sendAndReceive(ws2, { id: 2, method: 'system.health' });
|
||||
const response = result as GatewayResponse;
|
||||
expect((response.result as any).status).toBe('ok');
|
||||
} finally {
|
||||
ws2.close();
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
}
|
||||
});
|
||||
|
||||
it('system.lock handler returns lock status', async () => {
|
||||
const ws = await createLockClient();
|
||||
try {
|
||||
const result = await sendAndReceive(ws, { id: 3, method: 'system.lock' });
|
||||
const response = result as GatewayResponse;
|
||||
const r = response.result as { locked: boolean; activeClients: number; maxClients: number | null };
|
||||
expect(r.locked).toBe(true);
|
||||
expect(r.activeClients).toBe(1);
|
||||
expect(r.maxClients).toBe(1);
|
||||
} finally {
|
||||
ws.close();
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('GatewayServer HTTP auth', () => {
|
||||
const AUTH_PORT = 18898;
|
||||
let authServer: GatewayServer;
|
||||
|
||||
Reference in New Issue
Block a user