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:
@@ -252,4 +252,37 @@ describe('ControllerPage.vue', () => {
|
||||
expect(wrapper.find('.conn-bar').text()).toContain('Connesso')
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// OVERLAY SET FINITO
|
||||
// =============================================
|
||||
describe('Overlay set finito', () => {
|
||||
it('non mostra l\'overlay se setFinito è null', () => {
|
||||
const wrapper = mountController()
|
||||
expect(wrapper.find('.overlay').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('mostra l\'overlay quando setFinito è impostato', async () => {
|
||||
const wrapper = mountController()
|
||||
wrapper.vm.state.sp.setFinito = { vincitore: 'home' }
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.find('.overlay').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('l\'overlay mostra il nome del vincitore del set', async () => {
|
||||
const wrapper = mountController()
|
||||
wrapper.vm.state.sp.setFinito = { vincitore: 'home' }
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.find('.overlay').text()).toContain('Antoniana')
|
||||
})
|
||||
|
||||
it('click su CONFERMA invia l\'azione confermaSet', async () => {
|
||||
const wrapper = mountController()
|
||||
wrapper.vm.state.sp.setFinito = { vincitore: 'guest' }
|
||||
await wrapper.vm.$nextTick()
|
||||
const spy = vi.spyOn(wrapper.vm, 'sendAction')
|
||||
await wrapper.find('.btn-confirm').trigger('click')
|
||||
expect(spy).toHaveBeenCalledWith({ type: 'confermaSet' })
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -192,4 +192,39 @@ describe('DisplayPage.vue', () => {
|
||||
expect(guestStyle).toContain('display: none')
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// OVERLAY PARTITA FINITA
|
||||
// =============================================
|
||||
describe('Overlay partita finita', () => {
|
||||
it('non mostra l\'overlay se partitaFinita è null', () => {
|
||||
const wrapper = mountDisplay()
|
||||
expect(wrapper.find('.partita-finita-overlay').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('mostra l\'overlay quando partitaFinita è impostato', async () => {
|
||||
const wrapper = mountDisplay()
|
||||
wrapper.vm.state.sp.partitaFinita = { vincitore: 'home' }
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.find('.partita-finita-overlay').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('l\'overlay mostra il nome del vincitore della partita', async () => {
|
||||
const wrapper = mountDisplay()
|
||||
wrapper.vm.state.sp.nomi = { home: 'Antoniana', guest: 'Rivali' }
|
||||
wrapper.vm.state.sp.partitaFinita = { vincitore: 'guest' }
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.find('.partita-finita-overlay').text()).toContain('Rivali')
|
||||
})
|
||||
|
||||
it('l\'overlay mostra il punteggio dei set', async () => {
|
||||
const wrapper = mountDisplay()
|
||||
wrapper.vm.state.sp.set = { home: 3, guest: 1 }
|
||||
wrapper.vm.state.sp.partitaFinita = { vincitore: 'home' }
|
||||
await wrapper.vm.$nextTick()
|
||||
const text = wrapper.find('.partita-finita-overlay').text()
|
||||
expect(text).toContain('3')
|
||||
expect(text).toContain('1')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
145
tests/unit/db.test.js
Normal file
145
tests/unit/db.test.js
Normal file
@@ -0,0 +1,145 @@
|
||||
import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'
|
||||
|
||||
// Il modulo db.js apre il DB a livello di modulo (top-level).
|
||||
// Per isolarlo usiamo un DB in memoria: vi.stubEnv + vi.resetModules + import dinamico.
|
||||
let salvaPartita, getPartite, getPartita
|
||||
|
||||
beforeAll(async () => {
|
||||
vi.stubEnv('DB_PATH', ':memory:')
|
||||
vi.resetModules()
|
||||
const mod = await import('../../src/db.js')
|
||||
salvaPartita = mod.salvaPartita
|
||||
getPartite = mod.getPartite
|
||||
getPartita = mod.getPartita
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
vi.unstubAllEnvs()
|
||||
})
|
||||
|
||||
// Stato minimo valido da passare a salvaPartita
|
||||
function makeState({ vincitore = 'home', setHome = 3, setGuest = 1, strisce = [] } = {}) {
|
||||
return {
|
||||
modalitaPartita: '3/5',
|
||||
sp: {
|
||||
nomi: { home: 'Antoniana', guest: 'Ospiti' },
|
||||
set: { home: setHome, guest: setGuest },
|
||||
partitaFinita: vincitore ? { vincitore } : null,
|
||||
strisce,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
describe('db.js', () => {
|
||||
|
||||
// =============================================
|
||||
// salvaPartita
|
||||
// =============================================
|
||||
describe('salvaPartita', () => {
|
||||
it('ritorna un ID numerico intero positivo', () => {
|
||||
const id = salvaPartita(makeState())
|
||||
expect(typeof id).toBe('number')
|
||||
expect(id).toBeGreaterThan(0)
|
||||
expect(Number.isInteger(id)).toBe(true)
|
||||
})
|
||||
|
||||
it('IDs sono incrementali su inserimenti multipli', () => {
|
||||
const id1 = salvaPartita(makeState())
|
||||
const id2 = salvaPartita(makeState())
|
||||
expect(id2).toBeGreaterThan(id1)
|
||||
})
|
||||
|
||||
it('il record ha i campi corretti: modalita, nomi, set, vincitore', () => {
|
||||
const state = makeState({ vincitore: 'guest', setHome: 1, setGuest: 3 })
|
||||
const id = salvaPartita(state)
|
||||
const row = getPartita(Number(id))
|
||||
|
||||
expect(row.modalita).toBe('3/5')
|
||||
expect(row.nome_home).toBe('Antoniana')
|
||||
expect(row.nome_guest).toBe('Ospiti')
|
||||
expect(row.set_home).toBe(1)
|
||||
expect(row.set_guest).toBe(3)
|
||||
expect(row.vincitore).toBe('guest')
|
||||
})
|
||||
|
||||
it('il campo json è una stringa JSON parsabile', () => {
|
||||
const id = salvaPartita(makeState())
|
||||
const row = getPartita(Number(id))
|
||||
expect(() => JSON.parse(row.json)).not.toThrow()
|
||||
})
|
||||
|
||||
it('il JSON contiene nomi, set, strisce, vincitore e data', () => {
|
||||
const strisce = [{ set: 1, vincitore: 'home', punt: { home: 25, guest: 20 } }]
|
||||
const state = makeState({ strisce })
|
||||
const id = salvaPartita(state)
|
||||
const row = getPartita(Number(id))
|
||||
const json = JSON.parse(row.json)
|
||||
|
||||
expect(json.nomi).toEqual({ home: 'Antoniana', guest: 'Ospiti' })
|
||||
expect(json.set).toEqual({ home: 3, guest: 1 })
|
||||
expect(json.vincitore).toBe('home')
|
||||
expect(json.strisce).toEqual(strisce)
|
||||
expect(typeof json.data).toBe('string')
|
||||
expect(() => new Date(json.data)).not.toThrow()
|
||||
})
|
||||
|
||||
it('vincitore nel DB è null se partitaFinita è null', () => {
|
||||
const state = makeState({ vincitore: null })
|
||||
const id = salvaPartita(state)
|
||||
const row = getPartita(Number(id))
|
||||
expect(row.vincitore).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// getPartite
|
||||
// =============================================
|
||||
describe('getPartite', () => {
|
||||
it('ritorna tutte le partite inserite', () => {
|
||||
const prima = getPartite().length
|
||||
salvaPartita(makeState())
|
||||
salvaPartita(makeState())
|
||||
const dopo = getPartite()
|
||||
expect(dopo.length).toBe(prima + 2)
|
||||
})
|
||||
|
||||
it('ordina per ID discendente (più recente prima)', () => {
|
||||
const id1 = Number(salvaPartita(makeState()))
|
||||
const id2 = Number(salvaPartita(makeState()))
|
||||
const partite = getPartite()
|
||||
const ids = partite.map(p => p.id)
|
||||
const idx1 = ids.indexOf(id1)
|
||||
const idx2 = ids.indexOf(id2)
|
||||
// id2 (inserito dopo) deve apparire prima (indice minore)
|
||||
expect(idx2).toBeLessThan(idx1)
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// getPartita
|
||||
// =============================================
|
||||
describe('getPartita', () => {
|
||||
it('ritorna undefined per ID inesistente', () => {
|
||||
const result = getPartita(999999)
|
||||
expect(result).toBeUndefined()
|
||||
})
|
||||
|
||||
it('ritorna il record corretto per ID valido', () => {
|
||||
const id = Number(salvaPartita(makeState({ vincitore: 'home', setHome: 3, setGuest: 0 })))
|
||||
const row = getPartita(id)
|
||||
expect(row).toBeDefined()
|
||||
expect(row.id).toBe(id)
|
||||
expect(row.set_home).toBe(3)
|
||||
expect(row.set_guest).toBe(0)
|
||||
})
|
||||
|
||||
it('il record ha tutti i campi attesi', () => {
|
||||
const id = Number(salvaPartita(makeState()))
|
||||
const row = getPartita(id)
|
||||
const campi = ['id', 'data', 'modalita', 'nome_home', 'nome_guest', 'set_home', 'set_guest', 'vincitore', 'json']
|
||||
for (const campo of campi) {
|
||||
expect(row).toHaveProperty(campo)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest'
|
||||
import { createInitialState, applyAction, checkVittoria } from '../../src/gameState.js'
|
||||
import { createInitialState, applyAction, checkVittoria, checkVittoriaPartita } from '../../src/gameState.js'
|
||||
|
||||
describe('Game Logic (gameState.js)', () => {
|
||||
let state
|
||||
@@ -31,9 +31,10 @@ describe('Game Logic (gameState.js)', () => {
|
||||
expect(state.sp.form.guest).toEqual(["1", "2", "3", "4", "5", "6"])
|
||||
})
|
||||
|
||||
it('dovrebbe avere la striscia iniziale a [0]', () => {
|
||||
it('dovrebbe avere la striscia iniziale a [0] per home e [" "] per guest', () => {
|
||||
// home serve per primo → home parte con [0], guest con [" "]
|
||||
expect(state.sp.striscia.home).toEqual([0])
|
||||
expect(state.sp.striscia.guest).toEqual([0])
|
||||
expect(state.sp.striscia.guest).toEqual([" "])
|
||||
})
|
||||
|
||||
it('dovrebbe avere storico servizio vuoto', () => {
|
||||
@@ -116,13 +117,15 @@ describe('Game Logic (gameState.js)', () => {
|
||||
|
||||
it('dovrebbe aggiornare la striscia per punto Home', () => {
|
||||
const s = applyAction(state, { type: 'incPunt', team: 'home' })
|
||||
// Lo stato iniziale ha striscia = { home: [0], guest: [" "] }
|
||||
expect(s.sp.striscia.home).toEqual([0, 1])
|
||||
expect(s.sp.striscia.guest).toEqual([0, " "])
|
||||
expect(s.sp.striscia.guest).toEqual([" ", " "])
|
||||
})
|
||||
|
||||
it('dovrebbe aggiornare la striscia per punto Guest', () => {
|
||||
const s = applyAction(state, { type: 'incPunt', team: 'guest' })
|
||||
expect(s.sp.striscia.guest).toEqual([0, 1])
|
||||
// Lo stato iniziale ha striscia = { home: [0], guest: [" "] }
|
||||
expect(s.sp.striscia.guest).toEqual([" ", 1])
|
||||
expect(s.sp.striscia.home).toEqual([0, " "])
|
||||
})
|
||||
|
||||
@@ -133,9 +136,11 @@ describe('Game Logic (gameState.js)', () => {
|
||||
expect(s.sp.storicoServizio[0]).toHaveProperty('cambioPalla')
|
||||
})
|
||||
|
||||
it('non dovrebbe incrementare i punti dopo vittoria', () => {
|
||||
it('non dovrebbe incrementare i punti dopo vittoria (setFinito impostato)', () => {
|
||||
// Il guard controlla setFinito: va impostato come farebbe il ciclo di gioco reale
|
||||
state.sp.punt.home = 25
|
||||
state.sp.punt.guest = 23
|
||||
state.sp.setFinito = { vincitore: 'home' }
|
||||
const s = applyAction(state, { type: 'incPunt', team: 'home' })
|
||||
expect(s.sp.punt.home).toBe(25)
|
||||
})
|
||||
@@ -619,10 +624,11 @@ describe('Game Logic (gameState.js)', () => {
|
||||
})
|
||||
|
||||
it('dovrebbe resettare la striscia', () => {
|
||||
state.sp.striscia = { home: [0, 1, 2, 3], guest: [0, " ", " ", 1] }
|
||||
state.sp.striscia = { home: [0, 1, 2, 3], guest: [" ", " ", " ", 1] }
|
||||
const s = applyAction(state, { type: 'resetta' })
|
||||
// servHome è true di default → home parte con [0], guest con [" "]
|
||||
expect(s.sp.striscia.home).toEqual([0])
|
||||
expect(s.sp.striscia.guest).toEqual([0])
|
||||
expect(s.sp.striscia.guest).toEqual([" "])
|
||||
})
|
||||
|
||||
it('dovrebbe resettare lo storico servizio', () => {
|
||||
@@ -656,4 +662,278 @@ describe('Game Logic (gameState.js)', () => {
|
||||
expect(s.sp.punt.guest).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// FORMAZIONEINIZIOSET
|
||||
// =============================================
|
||||
describe('formInizioSet', () => {
|
||||
it('dovrebbe esistere nello stato iniziale con valori di default', () => {
|
||||
expect(state.sp.formInizioSet.home).toEqual(["1", "2", "3", "4", "5", "6"])
|
||||
expect(state.sp.formInizioSet.guest).toEqual(["1", "2", "3", "4", "5", "6"])
|
||||
})
|
||||
|
||||
it('setFormazione aggiorna sia form che formInizioSet per il team indicato', () => {
|
||||
const nuova = ["10", "11", "12", "13", "14", "15"]
|
||||
const s = applyAction(state, { type: 'setFormazione', team: 'home', form: nuova })
|
||||
expect(s.sp.form.home).toEqual(nuova)
|
||||
expect(s.sp.formInizioSet.home).toEqual(nuova)
|
||||
})
|
||||
|
||||
it('setFormazione non tocca formInizioSet dell\'altro team', () => {
|
||||
const nuova = ["10", "11", "12", "13", "14", "15"]
|
||||
const s = applyAction(state, { type: 'setFormazione', team: 'home', form: nuova })
|
||||
expect(s.sp.formInizioSet.guest).toEqual(["1", "2", "3", "4", "5", "6"])
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// CONFERMASET
|
||||
// =============================================
|
||||
describe('confermaSet', () => {
|
||||
// Helper: porta lo stato a fine set (home vince 25-0)
|
||||
function stateConSetFinito(modalita = '3/5') {
|
||||
let s = createInitialState()
|
||||
s.modalitaPartita = modalita
|
||||
// Aggiungiamo 25 punti a home: a 24-0 il prossimo punto vince il set
|
||||
for (let i = 0; i < 25; i++) {
|
||||
s = applyAction(s, { type: 'incPunt', team: 'home' })
|
||||
}
|
||||
// Ora setFinito dovrebbe essere impostato
|
||||
return s
|
||||
}
|
||||
|
||||
it('non fa nulla se setFinito è null', () => {
|
||||
expect(state.sp.setFinito).toBeNull()
|
||||
const s = applyAction(state, { type: 'confermaSet' })
|
||||
expect(s.sp.strisce).toEqual([])
|
||||
expect(s.sp.set.home).toBe(0)
|
||||
})
|
||||
|
||||
it('aggiunge una entry in strisce con i campi corretti', () => {
|
||||
const s = applyAction(stateConSetFinito(), { type: 'confermaSet' })
|
||||
expect(s.sp.strisce).toHaveLength(1)
|
||||
const striscia = s.sp.strisce[0]
|
||||
expect(striscia).toHaveProperty('set')
|
||||
expect(striscia).toHaveProperty('formInizio')
|
||||
expect(striscia).toHaveProperty('home')
|
||||
expect(striscia).toHaveProperty('guest')
|
||||
expect(striscia).toHaveProperty('vincitore')
|
||||
expect(striscia).toHaveProperty('punt')
|
||||
})
|
||||
|
||||
it('il numero set è 1 per il primo set, 2 per il secondo', () => {
|
||||
let s = stateConSetFinito()
|
||||
s = applyAction(s, { type: 'confermaSet' })
|
||||
expect(s.sp.strisce[0].set).toBe(1)
|
||||
|
||||
// Secondo set
|
||||
for (let i = 0; i < 25; i++) {
|
||||
s = applyAction(s, { type: 'incPunt', team: 'home' })
|
||||
}
|
||||
s = applyAction(s, { type: 'confermaSet' })
|
||||
expect(s.sp.strisce[1].set).toBe(2)
|
||||
})
|
||||
|
||||
it('formInizio nella striscia corrisponde a formInizioSet prima del conferma', () => {
|
||||
const formazioneInizio = ["7", "8", "9", "10", "11", "12"]
|
||||
let s = createInitialState()
|
||||
s = applyAction(s, { type: 'setFormazione', team: 'home', form: formazioneInizio })
|
||||
// porta a fine set
|
||||
for (let i = 0; i < 25; i++) {
|
||||
s = applyAction(s, { type: 'incPunt', team: 'home' })
|
||||
}
|
||||
s = applyAction(s, { type: 'confermaSet' })
|
||||
expect(s.sp.strisce[0].formInizio.home).toEqual(formazioneInizio)
|
||||
})
|
||||
|
||||
it('incrementa set[vincitore]', () => {
|
||||
const s = applyAction(stateConSetFinito(), { type: 'confermaSet' })
|
||||
expect(s.sp.set.home).toBe(1)
|
||||
expect(s.sp.set.guest).toBe(0)
|
||||
})
|
||||
|
||||
it('resetta punt a 0', () => {
|
||||
const s = applyAction(stateConSetFinito(), { type: 'confermaSet' })
|
||||
expect(s.sp.punt.home).toBe(0)
|
||||
expect(s.sp.punt.guest).toBe(0)
|
||||
})
|
||||
|
||||
it('svuota storicoServizio', () => {
|
||||
const s = applyAction(stateConSetFinito(), { type: 'confermaSet' })
|
||||
expect(s.sp.storicoServizio).toEqual([])
|
||||
})
|
||||
|
||||
it('azzera setFinito', () => {
|
||||
const s = applyAction(stateConSetFinito(), { type: 'confermaSet' })
|
||||
expect(s.sp.setFinito).toBeNull()
|
||||
})
|
||||
|
||||
it('aggiorna formInizioSet con la form corrente post-conferma', () => {
|
||||
const preConferma = stateConSetFinito()
|
||||
// La form potrebbe essere ruotata durante il set
|
||||
const formDopoSet = [...preConferma.sp.form.home]
|
||||
const s = applyAction(preConferma, { type: 'confermaSet' })
|
||||
expect(s.sp.formInizioSet.home).toEqual(formDopoSet)
|
||||
})
|
||||
|
||||
it('NON imposta partitaFinita se la partita non è ancora vinta (3/5)', () => {
|
||||
const s = applyAction(stateConSetFinito('3/5'), { type: 'confermaSet' })
|
||||
// 1 set vinto su 3 necessari → partita non finita
|
||||
expect(s.sp.partitaFinita).toBeNull()
|
||||
})
|
||||
|
||||
it('imposta partitaFinita quando home vince 3 set (modalità 3/5)', () => {
|
||||
let s = createInitialState()
|
||||
s.modalitaPartita = '3/5'
|
||||
// Vinci 3 set
|
||||
for (let set = 0; set < 3; set++) {
|
||||
for (let i = 0; i < 25; i++) s = applyAction(s, { type: 'incPunt', team: 'home' })
|
||||
s = applyAction(s, { type: 'confermaSet' })
|
||||
}
|
||||
expect(s.sp.partitaFinita).not.toBeNull()
|
||||
expect(s.sp.partitaFinita.vincitore).toBe('home')
|
||||
})
|
||||
|
||||
it('imposta partitaFinita quando home vince 2 set (modalità 2/3)', () => {
|
||||
let s = createInitialState()
|
||||
s.modalitaPartita = '2/3'
|
||||
for (let set = 0; set < 2; set++) {
|
||||
for (let i = 0; i < 25; i++) s = applyAction(s, { type: 'incPunt', team: 'home' })
|
||||
s = applyAction(s, { type: 'confermaSet' })
|
||||
}
|
||||
expect(s.sp.partitaFinita).not.toBeNull()
|
||||
expect(s.sp.partitaFinita.vincitore).toBe('home')
|
||||
})
|
||||
|
||||
it('resetta striscia per il set successivo con 0 per chi serve', () => {
|
||||
const s = applyAction(stateConSetFinito(), { type: 'confermaSet' })
|
||||
// servHome era true (home segna per primo → resta home a servire)
|
||||
expect(s.sp.striscia.home).toEqual([0])
|
||||
expect(s.sp.striscia.guest).toEqual([" "])
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// GUARDIE setFinito / partitaFinita
|
||||
// =============================================
|
||||
describe('Guardie setFinito e partitaFinita', () => {
|
||||
it('incPunt non incrementa se setFinito è impostato', () => {
|
||||
state.sp.setFinito = { vincitore: 'home' }
|
||||
const s = applyAction(state, { type: 'incPunt', team: 'home' })
|
||||
expect(s.sp.punt.home).toBe(0)
|
||||
})
|
||||
|
||||
it('incPunt non incrementa se partitaFinita è impostata', () => {
|
||||
state.sp.partitaFinita = { vincitore: 'home' }
|
||||
const s = applyAction(state, { type: 'incPunt', team: 'guest' })
|
||||
expect(s.sp.punt.guest).toBe(0)
|
||||
})
|
||||
|
||||
it('decPunt azzera setFinito se era impostato', () => {
|
||||
state.sp.setFinito = { vincitore: 'home' }
|
||||
const s = applyAction(state, { type: 'decPunt' })
|
||||
expect(s.sp.setFinito).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// RESETTA — nuovi campi
|
||||
// =============================================
|
||||
describe('resetta (nuovi campi)', () => {
|
||||
it('azzera strisce', () => {
|
||||
state.sp.strisce = [{ set: 1, vincitore: 'home', punt: { home: 25, guest: 20 } }]
|
||||
const s = applyAction(state, { type: 'resetta' })
|
||||
expect(s.sp.strisce).toEqual([])
|
||||
})
|
||||
|
||||
it('azzera setFinito', () => {
|
||||
state.sp.setFinito = { vincitore: 'home' }
|
||||
const s = applyAction(state, { type: 'resetta' })
|
||||
expect(s.sp.setFinito).toBeNull()
|
||||
})
|
||||
|
||||
it('azzera partitaFinita', () => {
|
||||
state.sp.partitaFinita = { vincitore: 'guest' }
|
||||
const s = applyAction(state, { type: 'resetta' })
|
||||
expect(s.sp.partitaFinita).toBeNull()
|
||||
})
|
||||
|
||||
it('reimposta formInizioSet ai valori di default', () => {
|
||||
state.sp.formInizioSet = { home: ["7", "8", "9", "10", "11", "12"], guest: ["7", "8", "9", "10", "11", "12"] }
|
||||
const s = applyAction(state, { type: 'resetta' })
|
||||
expect(s.sp.formInizioSet.home).toEqual(["1", "2", "3", "4", "5", "6"])
|
||||
expect(s.sp.formInizioSet.guest).toEqual(["1", "2", "3", "4", "5", "6"])
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// checkVittoriaPartita
|
||||
// =============================================
|
||||
describe('checkVittoriaPartita', () => {
|
||||
it('ritorna null se nessuno ha vinto (3/5, 1-1)', () => {
|
||||
state.sp.set.home = 1
|
||||
state.sp.set.guest = 1
|
||||
expect(checkVittoriaPartita(state)).toBeNull()
|
||||
})
|
||||
|
||||
it('ritorna "home" con 3 set in modalità 3/5', () => {
|
||||
state.modalitaPartita = '3/5'
|
||||
state.sp.set.home = 3
|
||||
state.sp.set.guest = 1
|
||||
expect(checkVittoriaPartita(state)).toBe('home')
|
||||
})
|
||||
|
||||
it('ritorna "guest" con 3 set in modalità 3/5', () => {
|
||||
state.modalitaPartita = '3/5'
|
||||
state.sp.set.home = 0
|
||||
state.sp.set.guest = 3
|
||||
expect(checkVittoriaPartita(state)).toBe('guest')
|
||||
})
|
||||
|
||||
it('ritorna null con 2 set in modalità 3/5 (non ancora vinto)', () => {
|
||||
state.modalitaPartita = '3/5'
|
||||
state.sp.set.home = 2
|
||||
state.sp.set.guest = 2
|
||||
expect(checkVittoriaPartita(state)).toBeNull()
|
||||
})
|
||||
|
||||
it('ritorna "home" con 2 set in modalità 2/3', () => {
|
||||
state.modalitaPartita = '2/3'
|
||||
state.sp.set.home = 2
|
||||
state.sp.set.guest = 0
|
||||
expect(checkVittoriaPartita(state)).toBe('home')
|
||||
})
|
||||
|
||||
it('ritorna "guest" con 2 set in modalità 2/3', () => {
|
||||
state.modalitaPartita = '2/3'
|
||||
state.sp.set.home = 1
|
||||
state.sp.set.guest = 2
|
||||
expect(checkVittoriaPartita(state)).toBe('guest')
|
||||
})
|
||||
|
||||
it('ritorna null con 1 set in modalità 2/3 (non ancora vinto)', () => {
|
||||
state.modalitaPartita = '2/3'
|
||||
state.sp.set.home = 1
|
||||
state.sp.set.guest = 0
|
||||
expect(checkVittoriaPartita(state)).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
// =============================================
|
||||
// confermaSet con servHome=false
|
||||
// =============================================
|
||||
describe('confermaSet — striscia con servHome=false', () => {
|
||||
it('resetta striscia con guest a [0] se è guest a servire', () => {
|
||||
let s = createInitialState()
|
||||
// guest serve
|
||||
s = applyAction(s, { type: 'cambiaPalla' })
|
||||
expect(s.sp.servHome).toBe(false)
|
||||
// porta a fine set (guest segna 25 volte)
|
||||
for (let i = 0; i < 25; i++) s = applyAction(s, { type: 'incPunt', team: 'guest' })
|
||||
s = applyAction(s, { type: 'confermaSet' })
|
||||
// dopo il set, continua a servire guest
|
||||
expect(s.sp.striscia.guest).toEqual([0])
|
||||
expect(s.sp.striscia.home).toEqual([" "])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -109,6 +109,7 @@ describe('Server Utils', () => {
|
||||
const allLogs = consoleSpy.mock.calls.map(c => c[0]).join('\n')
|
||||
expect(allLogs).toContain('5173')
|
||||
expect(allLogs).toContain('3001')
|
||||
expect(allLogs).toContain('3002')
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
|
||||
@@ -122,17 +123,27 @@ describe('Server Utils', () => {
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
|
||||
it('dovrebbe mostrare gli URL remoti se ci sono IP di rete', () => {
|
||||
it('dovrebbe stampare storicoPort personalizzato', () => {
|
||||
os.networkInterfaces.mockReturnValue({})
|
||||
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
|
||||
printServerInfo(3000, 3001, 5000)
|
||||
const allLogs = consoleSpy.mock.calls.map(c => c[0]).join('\n')
|
||||
expect(allLogs).toContain('5000')
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
|
||||
it('dovrebbe mostrare gli URL remoti per controller e storico', () => {
|
||||
os.networkInterfaces.mockReturnValue({
|
||||
eth0: [
|
||||
{ family: 'IPv4', internal: false, address: '192.168.1.50' }
|
||||
]
|
||||
})
|
||||
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
|
||||
printServerInfo(3000, 3001)
|
||||
printServerInfo(3000, 3001, 3002)
|
||||
const allLogs = consoleSpy.mock.calls.map(c => c[0]).join('\n')
|
||||
expect(allLogs).toContain('192.168.1.50')
|
||||
expect(allLogs).toContain('remoti')
|
||||
expect(allLogs).toContain('3001')
|
||||
expect(allLogs).toContain('3002')
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user