test(wsMixin): copri cleanup, riconnessione e guardie residue
Aggiunge test per beforeUnmount con connessione OPEN e con ws.close che lancia, l'annullamento del reconnectTimeout allo smontaggio, la guardia isConnecting, la chiusura della WebSocket precedente prima di riconnettersi (incluso il caso in cui close lancia), gli errori di registrazione/parsing nei gestori onopen/onmessage e la guardia di scheduleReconnect contro timer doppi.
This commit is contained in:
@@ -224,5 +224,102 @@ describe('createWsMixin (wsMixin.js)', () => {
|
|||||||
wrapper.unmount()
|
wrapper.unmount()
|
||||||
expect(ws.close).toHaveBeenCalled()
|
expect(ws.close).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('beforeUnmount con connessione OPEN chiude con codice 1000', () => {
|
||||||
|
const wrapper = mountWith()
|
||||||
|
const ws = ultimaWs()
|
||||||
|
ws.readyState = MockWebSocket.OPEN
|
||||||
|
wrapper.unmount()
|
||||||
|
expect(ws.close).toHaveBeenCalledWith(1000, 'Component unmounting')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('beforeUnmount non lancia se ws.close lancia', () => {
|
||||||
|
const wrapper = mountWith()
|
||||||
|
const ws = ultimaWs()
|
||||||
|
ws.readyState = MockWebSocket.OPEN
|
||||||
|
ws.close.mockImplementation(() => { throw new Error('già chiusa') })
|
||||||
|
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||||
|
expect(() => wrapper.unmount()).not.toThrow()
|
||||||
|
expect(consoleSpy).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('beforeUnmount annulla un reconnectTimeout pendente', () => {
|
||||||
|
vi.useFakeTimers()
|
||||||
|
try {
|
||||||
|
const wrapper = mountWith()
|
||||||
|
wrapper.vm.isConnecting = false
|
||||||
|
wrapper.vm.scheduleReconnect()
|
||||||
|
expect(wrapper.vm.reconnectTimeout).not.toBe(null)
|
||||||
|
wrapper.unmount()
|
||||||
|
// se il timer non fosse stato annullato, allo scoccare del delay
|
||||||
|
// verrebbe creata una nuova connessione anche a componente smontato
|
||||||
|
const primaDelTimeout = MockWebSocket.instances.length
|
||||||
|
vi.advanceTimersByTime(30000)
|
||||||
|
expect(MockWebSocket.instances.length).toBe(primaDelTimeout)
|
||||||
|
} finally {
|
||||||
|
vi.useRealTimers()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('rami aggiuntivi', () => {
|
||||||
|
it('connectWebSocket non fa nulla se è già in corso un tentativo di connessione', () => {
|
||||||
|
const wrapper = mountWith()
|
||||||
|
const primaDelTimeout = MockWebSocket.instances.length
|
||||||
|
wrapper.vm.isConnecting = true
|
||||||
|
wrapper.vm.connectWebSocket()
|
||||||
|
expect(MockWebSocket.instances.length).toBe(primaDelTimeout)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('riconnettendosi con la WebSocket precedente OPEN, la chiude con codice 1000', () => {
|
||||||
|
const wrapper = mountWith()
|
||||||
|
const prima = ultimaWs()
|
||||||
|
prima.readyState = MockWebSocket.OPEN
|
||||||
|
wrapper.vm.isConnecting = false
|
||||||
|
wrapper.vm.connectWebSocket()
|
||||||
|
expect(prima.close).toHaveBeenCalledWith(1000, 'Reconnecting')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('se la chiusura della WebSocket precedente lancia, logga e continua a riconnettersi', () => {
|
||||||
|
const wrapper = mountWith()
|
||||||
|
const prima = ultimaWs()
|
||||||
|
prima.readyState = MockWebSocket.OPEN
|
||||||
|
prima.close.mockImplementation(() => { throw new Error('già chiusa') })
|
||||||
|
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||||
|
wrapper.vm.isConnecting = false
|
||||||
|
|
||||||
|
expect(() => wrapper.vm.connectWebSocket()).not.toThrow()
|
||||||
|
expect(consoleSpy).toHaveBeenCalled()
|
||||||
|
expect(ultimaWs()).not.toBe(prima)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('onopen non lancia se il registro fallisce (send che lancia)', () => {
|
||||||
|
const wrapper = mountWith()
|
||||||
|
const ws = ultimaWs()
|
||||||
|
ws.readyState = MockWebSocket.OPEN
|
||||||
|
ws.send.mockImplementation(() => { throw new Error('boom') })
|
||||||
|
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||||
|
|
||||||
|
expect(() => ws.onopen()).not.toThrow()
|
||||||
|
expect(wrapper.vm.wsConnected).toBe(true)
|
||||||
|
expect(consoleSpy).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('onmessage non lancia su JSON non valido', () => {
|
||||||
|
mountWith()
|
||||||
|
const ws = ultimaWs()
|
||||||
|
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||||
|
|
||||||
|
expect(() => ws.onmessage({ data: 'non è JSON {{{' })).not.toThrow()
|
||||||
|
expect(consoleSpy).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('scheduleReconnect non arma un secondo timer se uno è già pendente', () => {
|
||||||
|
const wrapper = mountWith()
|
||||||
|
const spy = vi.spyOn(globalThis, 'setTimeout')
|
||||||
|
wrapper.vm.reconnectTimeout = 123 // timer già pendente (valore fittizio)
|
||||||
|
wrapper.vm.scheduleReconnect()
|
||||||
|
expect(spy).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user