Files
Nodecast/test/layaStatusPresentation.test.js
blomios f39ee6ebd8 feat(laya): clarify unavailable runtime download flow (#28)
Explain how to start the optional Laya runtime when model download fails because the service is unavailable, while keeping generic failures concise.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-06 20:31:15 +02:00

113 lines
4.9 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const { channelListWarning, presentLayaStatus } = require('../public/js/services/layaStatusPresentation.js');
test('presents unknown-size downloads as indeterminate with downloaded bytes', () => {
const view = presentLayaStatus({
phase: 'downloading',
downloading: true,
progressPercent: null,
bytesDownloaded: 12 * 1024 * 1024,
totalBytes: null
});
assert.equal(view.progressIndeterminate, true);
assert.equal(view.progressPercent, null);
assert.equal(view.bytesDownloaded, 12 * 1024 * 1024);
assert.equal(view.showDownload, false);
assert.equal(view.showRemove, false);
});
test('presents known progress as a bounded percentage', () => {
const view = presentLayaStatus({ phase: 'downloading', downloading: true, progressPercent: 47.6 });
assert.equal(view.progressIndeterminate, false);
assert.equal(view.progressPercent, 48);
});
test('failed downloads expose retry, safe details and Standard fallback', () => {
const view = presentLayaStatus({
phase: 'failed',
modelPresent: false,
error: { message: 'Model download failed', detail: 'The optional Laya runtime is unavailable.' }
}, 'hybrid');
assert.equal(view.downloadLabel, 'Retry download');
assert.equal(view.showDownload, true);
assert.equal(view.showUseStandard, true);
assert.equal(view.errorMessage, 'Model download failed');
assert.equal(view.errorDetail, 'The optional Laya runtime is unavailable.');
});
test('failed Laya downloads explain how to start the unavailable runtime', () => {
const view = presentLayaStatus({
phase: 'failed',
modelPresent: false,
runtimeAvailable: false,
error: { message: 'Model download failed', detail: 'The optional Laya runtime is unavailable.' }
}, 'hybrid');
assert.match(view.errorDetail, /Nodecast cannot reach the optional Laya runtime/);
assert.match(view.errorDetail, /Standard matching remains available/);
assert.match(view.errorDetail, /Start the Laya service, then try again:/);
assert.match(view.errorDetail, /docker compose --profile laya up -d/);
assert.equal(view.showStartCommand, true);
});
test('generic Laya failures do not suggest Docker Compose', () => {
const view = presentLayaStatus({
phase: 'failed',
modelPresent: false,
runtimeAvailable: true,
error: { message: 'Model download failed', detail: 'Laya model operation failed (HTTP 500).' }
}, 'hybrid');
assert.doesNotMatch(view.errorDetail, /docker compose/);
assert.equal(view.showStartCommand, false);
});
test('ready models expose removal without download actions', () => {
const view = presentLayaStatus({ phase: 'idle', modelPresent: true, runtimeAvailable: true, sizeBytes: 678323814 });
assert.equal(view.statusLabel, 'Ready');
assert.equal(view.showRemove, true);
assert.equal(view.showDownload, false);
assert.equal(view.showCheckAgain, false);
assert.equal(view.showStartCommand, false);
assert.equal(view.availabilityMessage, '');
});
test('ChannelList warning only appears for active Laya modes when unavailable or failed', () => {
const ready = { modelPresent: true, runtimeAvailable: true };
assert.equal(channelListWarning('hybrid', ready), '');
assert.equal(channelListWarning('laya', ready), '');
assert.equal(channelListWarning('algo', { modelPresent: false, runtimeAvailable: false }), '');
assert.equal(
channelListWarning('hybrid', { modelPresent: true, runtimeAvailable: false }),
'Local AI service is unavailable. Standard channel matching is being used.'
);
assert.equal(
channelListWarning('laya', ready, true),
'Local AI language detection failed. Channels were grouped with Standard matching and remain available.'
);
});
test('installed model with unavailable service is not reported ready', () => {
const view = presentLayaStatus({
phase: 'idle',
modelPresent: true,
runtimeAvailable: false,
sizeBytes: 10
}, 'hybrid');
assert.equal(view.ready, false);
assert.equal(view.statusLabel, 'Local AI service unavailable');
assert.equal(view.modelLabel, 'Model: Downloaded');
assert.equal(view.serviceLabel, 'Local AI service: Unavailable');
assert.equal(view.showDownload, false);
assert.equal(view.showRemove, true);
assert.equal(view.showCheckAgain, true);
assert.equal(view.showStartCommand, true);
assert.equal(view.availabilityMessage, 'The model is installed, but the Local AI service is not running. Standard channel matching is being used.');
});
test('missing model keeps download available', () => {
const view = presentLayaStatus({ phase: 'idle', modelPresent: false, runtimeAvailable: false });
assert.equal(view.showDownload, true);
assert.equal(view.showRemove, false);
assert.equal(view.showCheckAgain, false);
});