test(timeout): copri startTimeout/stopTimeout e il timer server-side dei 30s
Unit: attivazione con squadra/video/inizio, rifiuto di squadre non valide, azzeramento completo con stopTimeout. Integration (fake timers): startedAt iniettato dal server, auto-chiusura a 30s con broadcast e persistenza, annullamento del timer su stop manuale e riarmo su nuovo avvio.
This commit is contained in:
@@ -164,6 +164,117 @@ describe('WebSocket Integration (websocket-handler.js)', () => {
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// TIME OUT (timer server-side)
|
||||
// =============================================
|
||||
describe('Time out', () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers()
|
||||
})
|
||||
|
||||
function inviaStartTimeout(controller, overrides = {}) {
|
||||
controller.emit('message', JSON.stringify({
|
||||
type: 'action',
|
||||
action: { type: 'startTimeout', team: 'home', video: 'spot.mp4', ...overrides }
|
||||
}))
|
||||
}
|
||||
|
||||
it('dovrebbe iniettare startedAt lato server (ignorando quello del client)', () => {
|
||||
vi.setSystemTime(50000)
|
||||
const controller = connectAndRegister(wss, 'controller')
|
||||
|
||||
inviaStartTimeout(controller, { startedAt: 12345 })
|
||||
|
||||
const state = handler.getState()
|
||||
expect(state.timeout).toBe(true)
|
||||
expect(state.timeoutStartedAt).toBe(50000)
|
||||
})
|
||||
|
||||
it('dovrebbe chiudere automaticamente il time out dopo 30 secondi', () => {
|
||||
const controller = connectAndRegister(wss, 'controller')
|
||||
const display = connectAndRegister(wss, 'display')
|
||||
|
||||
inviaStartTimeout(controller)
|
||||
expect(handler.getState().timeout).toBe(true)
|
||||
|
||||
vi.advanceTimersByTime(29999)
|
||||
expect(handler.getState().timeout).toBe(true)
|
||||
|
||||
vi.advanceTimersByTime(1)
|
||||
const state = handler.getState()
|
||||
expect(state.timeout).toBe(false)
|
||||
expect(state.timeoutTeam).toBe(null)
|
||||
expect(state.timeoutVideo).toBe(null)
|
||||
expect(state.timeoutStartedAt).toBe(null)
|
||||
|
||||
// La chiusura automatica viene broadcastata ai client
|
||||
const msg = lastSent(display)
|
||||
expect(msg.type).toBe('state')
|
||||
expect(msg.state.timeout).toBe(false)
|
||||
})
|
||||
|
||||
it('la chiusura automatica dovrebbe persistere lo stato (onStateChange)', () => {
|
||||
const onStateChange = vi.fn()
|
||||
wss = new MockWebSocketServer()
|
||||
handler = setupWebSocketHandler(wss, { onStateChange })
|
||||
const controller = connectAndRegister(wss, 'controller')
|
||||
|
||||
inviaStartTimeout(controller)
|
||||
onStateChange.mockClear()
|
||||
|
||||
vi.advanceTimersByTime(30000)
|
||||
expect(onStateChange).toHaveBeenCalledTimes(1)
|
||||
expect(onStateChange.mock.calls[0][0].timeout).toBe(false)
|
||||
})
|
||||
|
||||
it('stopTimeout manuale dovrebbe annullare il timer pendente', () => {
|
||||
const controller = connectAndRegister(wss, 'controller')
|
||||
|
||||
inviaStartTimeout(controller)
|
||||
controller.emit('message', JSON.stringify({
|
||||
type: 'action',
|
||||
action: { type: 'stopTimeout' }
|
||||
}))
|
||||
expect(handler.getState().timeout).toBe(false)
|
||||
controller.send.mockClear()
|
||||
|
||||
// Allo scadere dei 30s non deve partire nessun broadcast fantasma
|
||||
vi.advanceTimersByTime(30000)
|
||||
expect(controller.send).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('un nuovo startTimeout dovrebbe riarmare il timer da capo', () => {
|
||||
const controller = connectAndRegister(wss, 'controller')
|
||||
|
||||
inviaStartTimeout(controller)
|
||||
vi.advanceTimersByTime(20000)
|
||||
|
||||
// Riavvio: il timer riparte da zero
|
||||
inviaStartTimeout(controller, { team: 'guest' })
|
||||
vi.advanceTimersByTime(20000)
|
||||
expect(handler.getState().timeout).toBe(true)
|
||||
expect(handler.getState().timeoutTeam).toBe('guest')
|
||||
|
||||
vi.advanceTimersByTime(10000)
|
||||
expect(handler.getState().timeout).toBe(false)
|
||||
})
|
||||
|
||||
it('startTimeout con squadra non valida non dovrebbe armare il timer', () => {
|
||||
const controller = connectAndRegister(wss, 'controller')
|
||||
|
||||
inviaStartTimeout(controller, { team: 'arbitro' })
|
||||
expect(handler.getState().timeout).toBe(false)
|
||||
controller.send.mockClear()
|
||||
|
||||
vi.advanceTimersByTime(30000)
|
||||
expect(controller.send).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// BROADCAST MULTI-CLIENT
|
||||
// =============================================
|
||||
|
||||
Reference in New Issue
Block a user