test: aggiunge copertura completa per le nuove funzionalità

- Nuovo db.test.js: 11 test per salvaPartita, getPartite, getPartita
  (isolamento con DB in memoria via vi.stubEnv + vi.resetModules)
- gameState.test.js: test per confermaSet, formInizioSet, partitaFinita,
  checkVittoriaPartita e guardie setFinito/partitaFinita; fix di 6 test
  pre-esistenti non allineati con la logica striscia aggiornata
- websocket.test.js: mock di db.js e 4 test per il salvataggio automatico
  su DB al termine della partita
- server-utils.test.js: 2 test aggiuntivi per storicoPort
- ControllerPage.test.js: 4 test per l'overlay di fine set (setFinito)
- DisplayPage.test.js: 4 test per l'overlay di fine partita (partitaFinita)
This commit is contained in:
2026-02-21 18:59:50 +01:00
parent 1df239ed3d
commit b3faf06477
6 changed files with 590 additions and 11 deletions

View File

@@ -1,6 +1,13 @@
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'
import { setupWebSocketHandler } from '../../src/websocket-handler.js'
import { EventEmitter } from 'events'
import { salvaPartita } from '../../src/db.js'
// Mock di db.js: evita connessioni reali al DB SQLite durante i test.
// vi.mock è automaticamente hoistato da Vitest all'inizio del file.
vi.mock('../../src/db.js', () => ({
salvaPartita: vi.fn().mockReturnValue(42n),
}))
// Mock parziale di una WebSocket e del Server
class MockWebSocket extends EventEmitter {
@@ -400,4 +407,72 @@ describe('WebSocket Integration (websocket-handler.js)', () => {
expect(handler.getClients().size).toBe(1)
})
})
// =============================================
// SALVATAGGIO DB
// =============================================
describe('Salvataggio DB', () => {
// Helper: inietta uno stato con setFinito già impostato e N set vinti da home
function injectPreFinaleState(setHomeVinti, modalita = '3/5') {
const base = handler.getState()
handler.setState({
...base,
modalitaPartita: modalita,
sp: {
...base.sp,
set: { home: setHomeVinti, guest: 0 },
punt: { home: 25, guest: 0 },
setFinito: { vincitore: 'home' },
partitaFinita: null,
storicoServizio: [],
strisce: [],
striscia: { home: [0], guest: [" "] },
},
})
}
afterEach(() => {
vi.mocked(salvaPartita).mockClear()
})
it('salvaPartita viene chiamata quando confermaSet porta partitaFinita a non-null', () => {
// 3/5: servono 3 set → inietta 2 già vinti + setFinito, poi confermaSet
injectPreFinaleState(2, '3/5')
const controller = connectAndRegister(wss, 'controller')
controller.emit('message', JSON.stringify({ type: 'action', action: { type: 'confermaSet' } }))
expect(salvaPartita).toHaveBeenCalledTimes(1)
})
it('salvaPartita NON viene chiamata per azioni normali (incPunt)', () => {
const controller = connectAndRegister(wss, 'controller')
controller.emit('message', JSON.stringify({ type: 'action', action: { type: 'incPunt', team: 'home' } }))
expect(salvaPartita).not.toHaveBeenCalled()
})
it('salvaPartita NON viene chiamata se partitaFinita era già impostata', () => {
// Inietta stato con partitaFinita già presente
const base = handler.getState()
handler.setState({
...base,
sp: { ...base.sp, partitaFinita: { vincitore: 'home' } },
})
const controller = connectAndRegister(wss, 'controller')
// Qualsiasi azione non dovrebbe triggerare un secondo salvataggio
controller.emit('message', JSON.stringify({ type: 'action', action: { type: 'incPunt', team: 'home' } }))
expect(salvaPartita).not.toHaveBeenCalled()
})
it('se salvaPartita lancia un errore il broadcast avviene comunque', () => {
vi.mocked(salvaPartita).mockImplementationOnce(() => { throw new Error('DB error') })
injectPreFinaleState(2, '3/5')
const display = connectAndRegister(wss, 'display')
const controller = connectAndRegister(wss, 'controller')
display.send.mockClear()
controller.emit('message', JSON.stringify({ type: 'action', action: { type: 'confermaSet' } }))
// Il broadcast deve avvenire anche se il DB ha fallito
expect(display.send).toHaveBeenCalled()
const msg = lastSent(display)
expect(msg.type).toBe('state')
})
})
})