52 lines
1.8 KiB
JavaScript
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)
|
|
})
|