mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-23 08:45:50 +00:00
119 lines
3.2 KiB
TypeScript
119 lines
3.2 KiB
TypeScript
import { describe, test, expect, beforeEach, mock } from 'bun:test'
|
|
|
|
// Mock config with very short timeout for testing
|
|
const mockConfig = {
|
|
port: 3000,
|
|
host: '0.0.0.0',
|
|
apiKeys: ['test-api-key'],
|
|
baseUrl: 'http://localhost:3000',
|
|
pollTimeout: 8,
|
|
heartbeatInterval: 20,
|
|
jwtExpiresIn: 3600,
|
|
disconnectTimeout: 300,
|
|
webCorsOrigins: [],
|
|
wsIdleTimeout: 30,
|
|
wsKeepaliveInterval: 20,
|
|
}
|
|
|
|
mock.module('../config', () => ({
|
|
config: mockConfig,
|
|
getBaseUrl: () => 'http://localhost:3000',
|
|
}))
|
|
|
|
import {
|
|
storeReset,
|
|
storeCreateEnvironment,
|
|
storeUpdateEnvironment,
|
|
storeCreateSession,
|
|
storeUpdateSession,
|
|
storeGetEnvironment,
|
|
storeGetSession,
|
|
} from '../store'
|
|
import {
|
|
getEventBus,
|
|
getAllEventBuses,
|
|
removeEventBus,
|
|
} from '../transport/event-bus'
|
|
import { runDisconnectMonitorSweep } from '../services/disconnect-monitor'
|
|
|
|
describe('Disconnect Monitor Logic', () => {
|
|
beforeEach(() => {
|
|
storeReset()
|
|
for (const [key] of getAllEventBuses()) {
|
|
removeEventBus(key)
|
|
}
|
|
})
|
|
|
|
test('environment times out when lastPollAt is too old', () => {
|
|
const env = storeCreateEnvironment({ secret: 's' })
|
|
const timeoutMs = 300 * 1000 // 5 minutes
|
|
|
|
// Simulate lastPollAt being 6 minutes ago
|
|
const oldDate = new Date(Date.now() - timeoutMs - 60000)
|
|
storeUpdateEnvironment(env.id, { lastPollAt: oldDate })
|
|
|
|
runDisconnectMonitorSweep()
|
|
|
|
const updated = storeGetEnvironment(env.id)
|
|
expect(updated?.status).toBe('disconnected')
|
|
})
|
|
|
|
test('environment stays active when lastPollAt is recent', () => {
|
|
const env = storeCreateEnvironment({ secret: 's' })
|
|
runDisconnectMonitorSweep()
|
|
|
|
const updated = storeGetEnvironment(env.id)
|
|
expect(updated?.status).toBe('active')
|
|
})
|
|
|
|
test('session becomes inactive when updatedAt is too old', () => {
|
|
const session = storeCreateSession({})
|
|
storeUpdateSession(session.id, { status: 'running' })
|
|
const rec = storeGetSession(session.id)
|
|
expect(rec).toBeTruthy()
|
|
if (!rec) return
|
|
|
|
rec.updatedAt = new Date(Date.now() - 300 * 1000 * 2 - 60000)
|
|
|
|
runDisconnectMonitorSweep()
|
|
|
|
const updated = storeGetSession(session.id)
|
|
expect(updated?.status).toBe('inactive')
|
|
})
|
|
|
|
test('session stays running when recently updated', () => {
|
|
const session = storeCreateSession({})
|
|
storeUpdateSession(session.id, { status: 'running' })
|
|
|
|
runDisconnectMonitorSweep()
|
|
|
|
const updated = storeGetSession(session.id)
|
|
expect(updated?.status).toBe('running')
|
|
})
|
|
|
|
test('session timeout publishes an inactive session_status event', () => {
|
|
const session = storeCreateSession({})
|
|
storeUpdateSession(session.id, { status: 'idle' })
|
|
const rec = storeGetSession(session.id)
|
|
expect(rec).toBeTruthy()
|
|
if (!rec) return
|
|
rec.updatedAt = new Date(Date.now() - 300 * 1000 * 2 - 60000)
|
|
|
|
const bus = getEventBus(session.id)
|
|
const events: Array<{ type: string; payload: { status?: string } }> = []
|
|
bus.subscribe(event => {
|
|
events.push({
|
|
type: event.type,
|
|
payload: event.payload as { status?: string },
|
|
})
|
|
})
|
|
|
|
runDisconnectMonitorSweep()
|
|
|
|
expect(events).toContainEqual({
|
|
type: 'session_status',
|
|
payload: { status: 'inactive' },
|
|
})
|
|
})
|
|
})
|