fix(voice): restore failed transcription recovery
This commit is contained in:
103
tests/voice-state.test.js
Normal file
103
tests/voice-state.test.js
Normal file
@@ -0,0 +1,103 @@
|
||||
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
|
||||
)
|
||||
})
|
||||
Reference in New Issue
Block a user