58 lines
2.8 KiB
JavaScript
58 lines
2.8 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const root = path.join(__dirname, '..');
|
|
|
|
function read(relativePath) {
|
|
return fs.readFileSync(path.join(root, relativePath), 'utf8');
|
|
}
|
|
|
|
test('api models endpoint preserves saved default in model list', () => {
|
|
const server = read('server.js');
|
|
assert.match(server, /var defaultOverride = await db\.getSetting\('models\.default'\)/);
|
|
assert.match(server, /models\.push\(\{ id: defaultOverride, name: defaultOverride \+ ' \(saved default\)'/);
|
|
assert.match(server, /defaultModel: defaultOverride \|\| DEFAULT_MODEL/);
|
|
});
|
|
|
|
test('lazy-loaded tab model selectors apply admin default', () => {
|
|
const app = read('public/js/app.js');
|
|
const index = read('public/index.html');
|
|
assert.match(app, /window\._defaultModelId = ''/);
|
|
assert.match(app, /window\._defaultModelId = defaultModelId/);
|
|
assert.match(app, /window\._buildModelOptions\(sel\)/);
|
|
assert.match(app, /selectEl\.value = window\._defaultModelId/);
|
|
assert.match(app, /saved\.textContent = window\._defaultModelId \+ ' \(saved default\)'/);
|
|
assert.doesNotMatch(index, /global-model-select|model-cost-badge/);
|
|
});
|
|
|
|
test('top bar model selector is removed and omitted selections use backend default', () => {
|
|
const app = read('public/js/app.js');
|
|
const selector = app.match(/function getSelectedModel\(\) \{[\s\S]*?\n\}/)[0];
|
|
assert.doesNotMatch(selector, /global-model-select|gemini-2\.5-flash/);
|
|
assert.match(selector, /return undefined/);
|
|
});
|
|
|
|
test('learning hub model selector uses shared tab model options', () => {
|
|
const learningHub = read('public/js/learningHub.js');
|
|
const aiPanelController = read('public/js/learningHub/aiPanelController.js');
|
|
assert.match(learningHub, /createAiPanelController\(/);
|
|
assert.match(aiPanelController, /window\._buildModelOptions\(sel\)/);
|
|
assert.doesNotMatch(learningHub, /global-model-select|globalSel\.innerHTML/);
|
|
assert.match(learningHub, /if \(model\) formData\.append\('model', model\)/);
|
|
});
|
|
|
|
test('backend AI calls use admin default when request omits model', () => {
|
|
const ai = read('src/utils/ai.js');
|
|
assert.match(ai, /async function resolveModel\(requestedModel\)/);
|
|
assert.match(ai, /await db\.getSetting\('models\.default'\)/);
|
|
assert.match(ai, /var model = await resolveModel\(requestedModel\)/g);
|
|
assert.match(ai, /await assertModelAllowed\(model, options\)/g);
|
|
});
|
|
|
|
test('personal notes voice generation sends selected model only when populated', () => {
|
|
const recorder = read('public/js/notes/recorder.js');
|
|
assert.match(recorder, /var modelEl = document\.getElementById\('notes-model-select'\)/);
|
|
assert.match(recorder, /options\.noteFromVoice\(\{ transcript: resp\.text, model: selectedModel \|\| undefined \}\)/);
|
|
});
|