test(boardwalk): cover the build id, the reload banner and the chunk reload guard (quick-261028-rqb)

This commit is contained in:
Jakub Zych
2026-10-28 21:26:20 +01:00
parent 75e19dc153
commit c8a22e3e84
6 changed files with 720 additions and 1 deletions

View File

@@ -0,0 +1,99 @@
import { describe, expect, it, vi } from 'vitest'
import {
CHUNK_RELOAD_KEY,
CHUNK_RELOAD_WINDOW,
installChunkReloadGuard,
shouldReload,
} from '../../src/app/chunkReload'
/** An in-memory Storage. */
function memoryStorage(): Storage {
const items = new Map<string, string>()
return {
get length() {
return items.size
},
clear: () => items.clear(),
getItem: (key) => items.get(key) ?? null,
key: (index) => [...items.keys()][index] ?? null,
removeItem: (key) => void items.delete(key),
setItem: (key, value) => void items.set(key, String(value)),
}
}
describe('shouldReload', () => {
it('reloads once and records the time', () => {
const storage = memoryStorage()
expect(shouldReload(storage, 1000)).toBe(true)
expect(storage.getItem(CHUNK_RELOAD_KEY)).toBe('1000')
})
it('declines a second reload within the window and allows one after it', () => {
const storage = memoryStorage()
expect(shouldReload(storage, 1000)).toBe(true)
expect(shouldReload(storage, 1000 + CHUNK_RELOAD_WINDOW - 1)).toBe(false)
expect(shouldReload(storage, 1000 + CHUNK_RELOAD_WINDOW)).toBe(true)
expect(storage.getItem(CHUNK_RELOAD_KEY)).toBe(String(1000 + CHUNK_RELOAD_WINDOW))
})
it('reloads over a stored value that is not a timestamp', () => {
const storage = memoryStorage()
storage.setItem(CHUNK_RELOAD_KEY, 'garbage')
expect(shouldReload(storage, 1000)).toBe(true)
})
it('never reloads without storage', () => {
expect(shouldReload(null, 1000)).toBe(false)
})
it('never reloads when storage throws', () => {
const reading = memoryStorage()
reading.getItem = () => {
throw new Error('denied')
}
expect(shouldReload(reading, 1000)).toBe(false)
const writing = memoryStorage()
writing.setItem = () => {
throw new Error('quota')
}
expect(shouldReload(writing, 1000)).toBe(false)
})
it('keys the flag under summer-admin.* with a 60 second window', () => {
expect(CHUNK_RELOAD_KEY).toBe('summer-admin.chunk-reload')
expect(CHUNK_RELOAD_WINDOW).toBe(60_000)
})
})
describe('installChunkReloadGuard', () => {
it('reloads once on vite:preloadError and leaves the event to the importer', () => {
const target = new EventTarget()
const storage = memoryStorage()
const reload = vi.fn()
let clock = 5000
const uninstall = installChunkReloadGuard({ target, storage: () => storage, reload, now: () => clock })
const first = new Event('vite:preloadError', { cancelable: true })
target.dispatchEvent(first)
expect(reload).toHaveBeenCalledTimes(1)
expect(first.defaultPrevented).toBe(false)
clock += 1000
target.dispatchEvent(new Event('vite:preloadError', { cancelable: true }))
expect(reload).toHaveBeenCalledTimes(1)
uninstall()
clock += CHUNK_RELOAD_WINDOW
target.dispatchEvent(new Event('vite:preloadError', { cancelable: true }))
expect(reload).toHaveBeenCalledTimes(1)
})
it('does not reload when no storage is available', () => {
const target = new EventTarget()
const reload = vi.fn()
const uninstall = installChunkReloadGuard({ target, storage: () => null, reload })
target.dispatchEvent(new Event('vite:preloadError'))
expect(reload).not.toHaveBeenCalled()
uninstall()
})
})