33 lines
2.2 KiB
JavaScript
33 lines
2.2 KiB
JavaScript
import test from 'node:test';
|
|||
|
|
import assert from 'node:assert/strict';
|
||
|
|
import {AiRevision,aiConfigurationProblem,aiQuestionProblem,aiEndpointLabel,aiSourceEligible} from '../src/ai-state.ts';
|
||
|
|
const config=()=>({enabled:false,base_url:'',model:'',api_key:null});
|
||
|
|
|
||
|
|
test('optional generation is disabled initially and requires an explicit endpoint/model',()=>{
|
||
|
|
assert.match(aiConfigurationProblem(config()),/disabled/);
|
||
|
|
assert.match(aiConfigurationProblem({...config(),enabled:true}),/endpoint/);
|
||
|
|
assert.equal(aiConfigurationProblem({...config(),enabled:true,base_url:'http://localhost:1234/v1',model:'local-model'}),null);
|
||
|
|
assert.equal(aiConfigurationProblem({...config(),enabled:true,base_url:'https://chosen.example/v1',model:'chosen-model',api_key:'session-key'}),null);
|
||
|
|
});
|
||
|
|
test('unsafe URL credentials and query parameters cannot leak through configuration errors',()=>{
|
||
|
|
const secret='private-session-key';
|
||
|
|
for(const base_url of [`https://user:${secret}@example.com/v1`,`https://example.com/v1?key=${secret}`,'file:///secret']){
|
||
|
|
const error=aiConfigurationProblem({...config(),enabled:true,base_url,model:'m'});
|
||
|
|
assert.ok(error);assert.ok(!error.includes(secret));
|
||
|
|
}
|
||
|
|
assert.equal(aiEndpointLabel(`https://user:${secret}@example.com/v1?key=${secret}`),'https://example.com');
|
||
|
|
});
|
||
|
|
test('UTF8 byte budgets and actual text source types gate explicit questions',()=>{
|
||
|
|
assert.ok(aiQuestionProblem('界'.repeat(700)));
|
||
|
|
assert.equal(aiQuestionProblem('What notice is required?'),null);
|
||
|
|
assert.equal(aiSourceEligible({kind:'page',number:2}),true);
|
||
|
|
assert.equal(aiSourceEligible({kind:'timestamp_ms',number:100}),false);
|
||
|
|
assert.equal(aiSourceEligible({kind:'page',number:2},true),false);
|
||
|
|
assert.equal(aiSourceEligible(undefined),false);
|
||
|
|
});
|
||
|
|
test('selection/configuration changes invalidate older preparation and answers',()=>{
|
||
|
|
const revision=new AiRevision();revision.select('first:page2');const old=revision.current();
|
||
|
|
revision.select('second:page1');assert.equal(revision.accepts(old),false);
|
||
|
|
const selected=revision.current();revision.select('second:page1');assert.equal(revision.accepts(selected),true);
|
||
|
|
revision.invalidate();assert.equal(revision.accepts(selected),false);
|
||
|
|
});
|