mirror of
https://github.com/EKKOLearnAI/hermes-web-ui.git
synced 2026-05-25 21:40:13 +00:00
82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
// @vitest-environment jsdom
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { __resetCompletionSoundForTests, playCompletionSound, primeCompletionSound } from '@/utils/completion-sound'
|
|
|
|
function installMockAudioContext(initialState: AudioContextState = 'running') {
|
|
const oscillator = {
|
|
type: 'sine' as OscillatorType,
|
|
frequency: {
|
|
setValueAtTime: vi.fn(),
|
|
exponentialRampToValueAtTime: vi.fn(),
|
|
},
|
|
connect: vi.fn(),
|
|
start: vi.fn(),
|
|
stop: vi.fn(),
|
|
}
|
|
|
|
const gain = {
|
|
gain: {
|
|
setValueAtTime: vi.fn(),
|
|
exponentialRampToValueAtTime: vi.fn(),
|
|
},
|
|
connect: vi.fn(),
|
|
}
|
|
|
|
const context = {
|
|
state: initialState,
|
|
currentTime: 10,
|
|
destination: {},
|
|
resume: vi.fn(async () => {
|
|
context.state = 'running'
|
|
}),
|
|
createOscillator: vi.fn(() => oscillator),
|
|
createGain: vi.fn(() => gain),
|
|
}
|
|
|
|
const AudioContextMock = vi.fn(() => context)
|
|
Object.defineProperty(window, 'AudioContext', {
|
|
configurable: true,
|
|
writable: true,
|
|
value: AudioContextMock,
|
|
})
|
|
|
|
return { AudioContextMock, context, oscillator, gain }
|
|
}
|
|
|
|
describe('completion sound', () => {
|
|
beforeEach(() => {
|
|
__resetCompletionSoundForTests()
|
|
vi.restoreAllMocks()
|
|
Object.defineProperty(window, 'AudioContext', {
|
|
configurable: true,
|
|
writable: true,
|
|
value: undefined,
|
|
})
|
|
})
|
|
|
|
it('returns false when Web Audio is unavailable', async () => {
|
|
await expect(playCompletionSound()).resolves.toBe(false)
|
|
})
|
|
|
|
it('primes a suspended audio context from user interaction', () => {
|
|
const { context } = installMockAudioContext('suspended')
|
|
|
|
primeCompletionSound()
|
|
|
|
expect(context.resume).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('plays a short tone through Web Audio', async () => {
|
|
const { context, oscillator, gain } = installMockAudioContext('running')
|
|
|
|
await expect(playCompletionSound()).resolves.toBe(true)
|
|
|
|
expect(context.createOscillator).toHaveBeenCalledTimes(1)
|
|
expect(context.createGain).toHaveBeenCalledTimes(1)
|
|
expect(oscillator.connect).toHaveBeenCalledWith(gain)
|
|
expect(gain.connect).toHaveBeenCalledWith(context.destination)
|
|
expect(oscillator.start).toHaveBeenCalledWith(10)
|
|
expect(oscillator.stop).toHaveBeenCalledWith(10.16)
|
|
})
|
|
})
|