feat: add Settings live stream analysis button and diagnose Laya batch failure (#14)
Add a Settings action to manually rerun Live TV stream analysis: it triggers an admin-guarded projection rebuild endpoint that groups streams into logical channels (covering channels present before the projection existed) and reruns language/Laya detection, with progress presented via liveAnalysisPresentation. Harden the Laya batch path that failed with 'Local AI language matching failed' by surfacing the underlying cause and falling back to standard matching cleanly. Guard admin-only rebuild through a new authz helper and cover routes, service and presentation with tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
39
test/liveAnalysisPresentation.test.js
Normal file
39
test/liveAnalysisPresentation.test.js
Normal file
@ -0,0 +1,39 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const { layaFallbackMessage, present } = require('../public/js/services/liveAnalysisPresentation.js');
|
||||
|
||||
test('presents determinate channel analysis progress', () => {
|
||||
const view = present({ status: 'building', processed: 25, total: 100 });
|
||||
assert.equal(view.busy, true);
|
||||
assert.equal(view.progressIndeterminate, false);
|
||||
assert.equal(view.progressPercent, 25);
|
||||
assert.equal(view.progressText, '25 of 100 · 25%');
|
||||
});
|
||||
|
||||
test('presents indeterminate progress when totals are unavailable', () => {
|
||||
const view = present({ status: 'queued', processed: null, total: null });
|
||||
assert.equal(view.busy, true);
|
||||
assert.equal(view.progressIndeterminate, true);
|
||||
assert.equal(view.buttonLabel, 'Analyze channels');
|
||||
assert.equal(present({ status: 'running', processed: null, total: 100 }).progressIndeterminate, true);
|
||||
});
|
||||
|
||||
test('presents success and retry states', () => {
|
||||
assert.deepEqual(
|
||||
{ label: present({ status: 'success', projectedCount: 12 }).statusLabel, button: present({ status: 'success' }).buttonLabel },
|
||||
{ label: 'Analysis complete', button: 'Analyze again' }
|
||||
);
|
||||
const failed = present({ status: 'error', error: 'Safe projection error' });
|
||||
assert.equal(failed.statusLabel, 'Analysis failed');
|
||||
assert.equal(failed.buttonLabel, 'Try again');
|
||||
assert.equal(failed.errorDetail, 'Safe projection error');
|
||||
});
|
||||
|
||||
test('mentions Standard fallback only for unavailable active Local AI modes', () => {
|
||||
assert.equal(layaFallbackMessage('algo', { modelPresent: false, runtimeAvailable: false }), '');
|
||||
assert.equal(layaFallbackMessage('hybrid', { modelPresent: true, runtimeAvailable: true }), '');
|
||||
assert.equal(
|
||||
layaFallbackMessage('laya', { modelPresent: true, runtimeAvailable: false }),
|
||||
'Local AI is unavailable. Standard channel matching will be used for this analysis.'
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user