Files
aiturk-hermes-ide/apps/mobile/tests/voice-start-cancellation.test.mjs
T

52 lines
1.8 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { VoiceSession } from '../src/voice.mjs'
import { VOICE_PRICING } from '../src/voice-usage.mjs'
test('stopping during audio resume never requests microphone access afterward', async t => {
let resume, microphoneRequests = 0, closed = 0
const originalContext = globalThis.AudioContext
const originalNavigator = Object.getOwnPropertyDescriptor(globalThis, 'navigator')
globalThis.AudioContext = class {
resume() { return new Promise(resolve => { resume = resolve }) }
async close() { closed++ }
}
Object.defineProperty(globalThis, 'navigator', { configurable: true, value: {
mediaDevices: { async getUserMedia() {
microphoneRequests++
return { getTracks: () => [] }
} },
} })
t.after(() => {
globalThis.AudioContext = originalContext
if (originalNavigator) Object.defineProperty(globalThis, 'navigator', originalNavigator)
else delete globalThis.navigator
})
const voice = new VoiceSession({ model: VOICE_PRICING.model, onError() {} })
t.after(() => voice.stop())
const starting = voice.start()
voice.stop()
resume()
await starting
assert.equal(microphoneRequests, 0)
assert.equal(closed, 1)
assert.equal(voice.socket, undefined)
})
test('a stopped session cannot reopen audio resources', async t => {
let created = 0
const originalContext = globalThis.AudioContext
globalThis.AudioContext = class {
constructor() { created++ }
async resume() {}
async close() {}
}
t.after(() => { globalThis.AudioContext = originalContext })
const voice = new VoiceSession({ model: VOICE_PRICING.model, onError() {} })
voice.stop()
await voice.start(false)
// Clean up an incorrectly restarted interval even when this assertion fails.
clearInterval(voice.usageTimer)
assert.equal(created, 0)
})