test: add frontend composable tests and remaining test files
useNostr (9), useFightCache (5), useOnlineStatus (4) composable tests. Added fake-indexeddb dev dependency for IDB tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
806163c6c5
commit
1c296c6f1c
@@ -0,0 +1,142 @@
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest'
|
||||
import { waitForHumanResponse, clearAllPending } from './human-responses.js'
|
||||
import { fightEvents } from './events.js'
|
||||
import type { Challenge } from './challenges.js'
|
||||
|
||||
const factualChallenge: Challenge = {
|
||||
type: 'speed_blitz',
|
||||
label: 'Speed Blitz',
|
||||
prompt: 'What year was Bitcoin launched?',
|
||||
answers: ['2009'],
|
||||
scoring: 'factual',
|
||||
timeout_ms: 10000,
|
||||
baseDamage: 20,
|
||||
choices: ['2009', '2010', '2008'],
|
||||
}
|
||||
|
||||
const quickChallenge: Challenge = {
|
||||
type: 'math_blitz',
|
||||
label: 'Math Blitz',
|
||||
prompt: 'What is 2+2?',
|
||||
answers: ['4'],
|
||||
scoring: 'factual',
|
||||
timeout_ms: 5000,
|
||||
baseDamage: 18,
|
||||
choices: ['4', '3', '5'],
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
clearAllPending()
|
||||
})
|
||||
|
||||
describe('BUG-2: SSE uses challenge timeout, not hardcoded', () => {
|
||||
it('waitForHumanResponse uses challenge.timeout_ms', () => {
|
||||
const fightId = `bug2-${Date.now()}`
|
||||
vi.useFakeTimers()
|
||||
|
||||
// 10s challenge timeout + 5s human extra = 15s total
|
||||
const { promise } = waitForHumanResponse(fightId, 'bot1', factualChallenge, 1)
|
||||
|
||||
let resolved = false
|
||||
promise.then(() => { resolved = true })
|
||||
|
||||
// At 14s, should NOT have timed out yet
|
||||
vi.advanceTimersByTime(14_000)
|
||||
expect(resolved).toBe(false)
|
||||
|
||||
// At 16s, should have timed out (10s + 5s = 15s)
|
||||
vi.advanceTimersByTime(2_000)
|
||||
|
||||
vi.useRealTimers()
|
||||
})
|
||||
|
||||
it('different challenge type has different timeout', () => {
|
||||
const fightId = `bug2-quick-${Date.now()}`
|
||||
vi.useFakeTimers()
|
||||
|
||||
// 5s timeout + 5s human extra = 10s total
|
||||
const { promise } = waitForHumanResponse(fightId, 'bot2', quickChallenge, 1)
|
||||
|
||||
let resolved = false
|
||||
promise.then(() => { resolved = true })
|
||||
|
||||
// At 9s, should NOT have timed out yet
|
||||
vi.advanceTimersByTime(9_000)
|
||||
expect(resolved).toBe(false)
|
||||
|
||||
// At 11s, should have timed out (5s + 5s = 10s)
|
||||
vi.advanceTimersByTime(2_000)
|
||||
|
||||
vi.useRealTimers()
|
||||
})
|
||||
})
|
||||
|
||||
describe('BUG-3: shuffle return value used', () => {
|
||||
it('choices returned from waitForHumanResponse are shuffled (contain correct answer)', () => {
|
||||
vi.useFakeTimers()
|
||||
const fightId = `bug3-${Date.now()}`
|
||||
const { choices } = waitForHumanResponse(fightId, 'bot3', factualChallenge, 1)
|
||||
|
||||
// Must contain the correct answer
|
||||
expect(choices).toContain('2009')
|
||||
// Must have 3 choices
|
||||
expect(choices).toHaveLength(3)
|
||||
|
||||
clearAllPending()
|
||||
vi.useRealTimers()
|
||||
})
|
||||
})
|
||||
|
||||
describe('BUG-9: no TODO in prompt options', () => {
|
||||
it('no prompt contains TODO string', () => {
|
||||
vi.useFakeTimers()
|
||||
const fightId = `bug9-${Date.now()}`
|
||||
const { choices } = waitForHumanResponse(fightId, 'bot9', factualChallenge, 1)
|
||||
|
||||
for (const choice of choices) {
|
||||
expect(choice).not.toContain('TODO')
|
||||
expect(choice).not.toContain('pass #')
|
||||
}
|
||||
|
||||
clearAllPending()
|
||||
vi.useRealTimers()
|
||||
})
|
||||
})
|
||||
|
||||
describe('BUG-12: fightEvents.cleanup removes listeners', () => {
|
||||
it('cleanup removes fight listeners', () => {
|
||||
const fightId = 'bug12-test'
|
||||
let received = false
|
||||
fightEvents.on(fightId, () => { received = true })
|
||||
|
||||
fightEvents.cleanup(fightId)
|
||||
|
||||
// Emit after cleanup — should not fire
|
||||
fightEvents.emit({
|
||||
fightId,
|
||||
type: 'test',
|
||||
data: {},
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
expect(received).toBe(false)
|
||||
})
|
||||
|
||||
it('global listeners still fire after cleanup', () => {
|
||||
const fightId = 'bug12-global'
|
||||
let received = false
|
||||
const unsub = fightEvents.onAll(() => { received = true })
|
||||
|
||||
fightEvents.cleanup(fightId)
|
||||
|
||||
fightEvents.emit({
|
||||
fightId,
|
||||
type: 'test',
|
||||
data: {},
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
expect(received).toBe(true)
|
||||
unsub()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user