Files
teaching-feedback-assistant/tests/voice-state.test.js
2026-07-22 15:35:48 +08:00

104 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const assert = require('node:assert/strict')
const test = require('node:test')
const {
getVoiceFailureHint,
getVoicePrimaryAction,
getVoicePrimaryActionText
} = require('../.test-dist/pages/feedback/voice-state.js')
const { runWithSessionRefresh } = require('../.test-dist/pages/feedback/voice-actions.js')
function session(overrides = {}) {
return {
id: 'session-1',
profileId: null,
feedbackDate: '2026-07-22',
content: '',
status: 'active',
lessonCount: 1,
totalDurationMs: 2800,
processingSegmentCount: 0,
failedSegmentCount: 0,
needsGeneration: false,
lessons: [],
createdAt: 0,
updatedAt: 0,
...overrides
}
}
test('failed segments take priority over processing and generation', () => {
const value = session({
failedSegmentCount: 2,
processingSegmentCount: 1,
needsGeneration: true
})
const action = getVoicePrimaryAction(value)
assert.equal(action, 'retry')
assert.equal(getVoicePrimaryActionText(action, value.failedSegmentCount), '重试转录2')
})
test('voice primary action follows retry, processing, then generation states', () => {
assert.equal(getVoicePrimaryAction(session({ failedSegmentCount: 1 })), 'retry')
assert.equal(getVoicePrimaryAction(session({ processingSegmentCount: 1 })), 'processing')
assert.equal(getVoicePrimaryAction(session({ needsGeneration: true })), 'generate')
})
test('no clear speech failures provide an actionable explanation', () => {
const value = session({
failedSegmentCount: 1,
lessons: [
{
segments: [
{
id: 'segment-1',
sequence: 1,
durationMs: 2800,
status: 'failed',
errorMessage: 'FunASR HTTP 422: no clear speech was recognized'
}
]
}
]
})
const hint = getVoiceFailureHint(value)
assert.match(hint, /录音过短、静音或环境噪声/)
assert.match(hint, /放弃后重新录制/)
})
test('session refresh runs after a failed API action', async () => {
const expected = new Error('generation rejected')
let refreshCount = 0
await assert.rejects(
runWithSessionRefresh(
async () => {
throw expected
},
async () => {
refreshCount += 1
}
),
expected
)
assert.equal(refreshCount, 1)
})
test('refresh failure does not replace the original API error', async () => {
const expected = new Error('generation rejected with request id')
await assert.rejects(
runWithSessionRefresh(
async () => {
throw expected
},
async () => {
throw new Error('refresh failed')
}
),
expected
)
})