Run full live catalog refreshes through live source sync, complete channel analysis, EPG source refresh, and persisted EPG rematching while keeping check-new incremental. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
102 lines
4.4 KiB
JavaScript
102 lines
4.4 KiB
JavaScript
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', phase: 'projecting', processed: 25, total: 100 });
|
|
assert.equal(view.busy, true);
|
|
assert.equal(view.statusLabel, 'Building channel catalog…');
|
|
assert.equal(view.progressIndeterminate, false);
|
|
assert.equal(view.progressPercent, 25);
|
|
assert.equal(view.progressText, '25 of 100 channels · 25%');
|
|
});
|
|
|
|
test('presents Laya identity progress using AI batch counters', () => {
|
|
const view = present({
|
|
status: 'building',
|
|
phase: 'laya_identity',
|
|
layaProcessed: 3,
|
|
layaTotal: 8,
|
|
processed: 0,
|
|
total: 39348
|
|
});
|
|
assert.equal(view.statusLabel, 'Analyzing with local AI…');
|
|
assert.equal(view.progressIndeterminate, false);
|
|
assert.equal(view.progressPercent, 38);
|
|
assert.equal(view.progressText, 'AI batch 3 of 8 · 38%');
|
|
});
|
|
|
|
test('presents local Laya language batch progress after projection', () => {
|
|
const view = present({
|
|
status: 'building',
|
|
phase: 'laya_language',
|
|
languageProcessed: 5,
|
|
languageTotal: 10
|
|
});
|
|
assert.equal(view.statusLabel, 'Detecting stream languages…');
|
|
assert.equal(view.progressIndeterminate, false);
|
|
assert.equal(view.progressPercent, 50);
|
|
assert.equal(view.progressText, 'Language batch 5 of 10 · 50%');
|
|
});
|
|
|
|
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.progressPercent, null);
|
|
assert.equal(view.progressText, 'In progress…');
|
|
assert.equal(view.buttonLabel, 'Analyze channels');
|
|
assert.equal(present({ status: 'running', processed: null, total: 100 }).progressIndeterminate, true);
|
|
});
|
|
|
|
test('presents writing as an indeterminate finalization phase', () => {
|
|
const view = present({ status: 'building', phase: 'writing', processed: 39348, total: 39348 });
|
|
assert.equal(view.statusLabel, 'Saving channel catalog…');
|
|
assert.equal(view.progressIndeterminate, true);
|
|
assert.equal(view.progressPercent, null);
|
|
assert.equal(view.progressText, 'Finalizing…');
|
|
});
|
|
|
|
test('presents full refresh and EPG matching phases with user-facing labels', () => {
|
|
assert.equal(
|
|
present({ status: 'building', phase: 'refreshing_live_sources' }).statusLabel,
|
|
'Refreshing IPTV sources…'
|
|
);
|
|
assert.equal(
|
|
present({ status: 'building', phase: 'refreshing_epg_sources' }).statusLabel,
|
|
'Refreshing EPG data…'
|
|
);
|
|
assert.equal(
|
|
present({ status: 'building', phase: 'matching_epg', processed: 4, total: 10 }).statusLabel,
|
|
'Matching channels to EPG data…'
|
|
);
|
|
assert.equal(
|
|
present({ status: 'building', phase: 'laya_epg_matching', processed: 4, total: 10 }).statusLabel,
|
|
'Matching channels to EPG data…'
|
|
);
|
|
const finalizing = present({ status: 'building', phase: 'writing_epg_matches', processed: 10, total: 10 });
|
|
assert.equal(finalizing.statusLabel, 'Finalizing…');
|
|
assert.equal(finalizing.progressIndeterminate, true);
|
|
assert.equal(finalizing.progressText, 'Finalizing…');
|
|
});
|
|
|
|
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.'
|
|
);
|
|
});
|