Files
searchi/apps/desktop/tests/semantic-setup-state.test.mjs

64 lines
3.4 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { semanticIndexReady, semanticIndexKey, semanticRetryVisible, semanticMediaReady } from '../src/semantic-setup-state.ts';
import { AutomaticIndexGate, semanticAvailable } from '../src/search-state.ts';
const text = () => ({ ready: true, generation: 1, pending: 2, downloading: true,
warming: false, embedding: false, error: null, indexing_ready: true,
text_model_ready: true, media_model_ready: false, requested_coverage: 'text_only' });
test('warm verified text can index during media download but not concurrent warmup or indexing', () => {
assert.equal(semanticIndexReady(text()), true);
for (const patch of [{ready:false}, {warming:true}, {embedding:true}, {indexing_ready:false}])
assert.equal(semanticIndexReady({...text(), ...patch}), false);
});
test('media repair cannot authorize a text downgrade of an existing full index', () => {
const status = {...text(), requested_coverage:'full_media', indexing_ready:false};
assert.equal(semanticAvailable(status), true);
assert.equal(semanticIndexReady(status), false);
});
test('an incompatible or unprepared generation never claims semantic availability', () => {
assert.equal(semanticAvailable({...text(), coverage:null}), false);
assert.equal(semanticAvailable({...text(), coverage:'text_only'}), true);
assert.equal(semanticAvailable({...text(), coverage:'full_media'}), true);
});
test('coverage promotion gets one new automatic attempt without a repeated polling loop', () => {
const gate = new AutomaticIndexGate();
const early = semanticIndexKey(text(), 4);
const promoted = semanticIndexKey({...text(), requested_coverage:'full_media'}, 4);
assert.equal(gate.claim(early), true);
assert.equal(gate.claim(early), false);
assert.equal(gate.claim(promoted), true);
assert.equal(gate.claim(promoted), false);
});
test('failed media setup leaves text search available and retry visible', () => {
const failed = {...text(), downloading:false, media_model_error:'Download failed'};
assert.equal(semanticAvailable(failed), true);
assert.equal(semanticRetryVisible(failed), true);
assert.equal(semanticMediaReady(failed), false);
assert.equal(semanticRetryVisible({...text(), error:'Query failed'}), false);
assert.equal(semanticRetryVisible({...text(), ready:false, error:'Setup failed'}), true);
});
test('legacy full-pair status remains blocked during download and ready after setup', () => {
const legacy = {ready:true,generation:1,pending:2,downloading:true,warming:false,embedding:false,error:null};
assert.equal(semanticIndexReady(legacy), false);
assert.equal(semanticMediaReady(legacy), false);
assert.equal(semanticIndexReady({...legacy,downloading:false}), true);
assert.equal(semanticMediaReady({...legacy,downloading:false}), true);
});
test('partial speech publication cannot create an automatic retry loop', () => {
const gate = new AutomaticIndexGate();
const first = {...text(), speech:{ready:true,pending:true,requested_policy:'speech-v1-a',corpus_revision:7}};
assert.equal(gate.claim(semanticIndexKey(first,4)),true);
assert.equal(gate.claim(semanticIndexKey({...first,generation:99,pending:0},4)),false);
assert.equal(gate.claim(semanticIndexKey({...first,speech:{...first.speech,corpus_revision:8}},4)),true);
assert.equal(gate.claim(semanticIndexKey({...first,speech:{...first.speech,requested_policy:'speech-v1-b'}},4)),true);
});