Changeset 0.37.17 (#229)
Co-authored-by: gobha <jasafpro@gmail.com> Co-committed-by: gobha <jasafpro@gmail.com>
This commit is contained in:
239
packages/sdk-test-runner/js/fixtures.js
Normal file
239
packages/sdk-test-runner/js/fixtures.js
Normal file
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
* SDK Test Runner — Fixtures
|
||||
*
|
||||
* Provisions reusable test resources before domains run and tears
|
||||
* them down afterward. Modeled on the ICD test runner's fixture
|
||||
* pattern.
|
||||
*
|
||||
* Fixture resources (all optional — domains degrade gracefully):
|
||||
*
|
||||
* providerConfig Global API config created from the first admin
|
||||
* config that has at least one embedding model.
|
||||
* Enables: knowledge.search, model preference tests.
|
||||
*
|
||||
* embeddingModel {model_id, provider_config_id} picked from the
|
||||
* enabled models list after the config is created.
|
||||
*
|
||||
* policies Policy toggles applied at setup, reverted at
|
||||
* teardown (e.g. allow_user_personas).
|
||||
*
|
||||
* team Test team (with current user as admin).
|
||||
*
|
||||
* Access: window.SDKR.fixtures.*
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
var T = window.SDKR;
|
||||
if (!T) return;
|
||||
|
||||
T.fixtures = {
|
||||
ready: false,
|
||||
providerConfig: null, // { id, name, provider }
|
||||
embeddingModel: null, // { model_id, provider_config_id }
|
||||
team: null, // { id, name }
|
||||
policies: {}, // key → original value (for revert)
|
||||
errors: []
|
||||
};
|
||||
|
||||
// ─── Policy helpers ──────────────────────────────────────
|
||||
|
||||
async function setPolicy(key, value) {
|
||||
var fix = T.fixtures;
|
||||
try {
|
||||
// Save original for revert
|
||||
if (!(key in fix.policies)) {
|
||||
try {
|
||||
var settings = await T.raw.get('/admin/settings');
|
||||
fix.policies[key] = settings.policies?.[key] ?? null;
|
||||
} catch (_) {
|
||||
fix.policies[key] = null;
|
||||
}
|
||||
}
|
||||
await T.raw.put('/admin/settings/' + key, { value: String(value) });
|
||||
} catch (e) {
|
||||
fix.errors.push('policy ' + key + ': ' + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function revertPolicies() {
|
||||
var fix = T.fixtures;
|
||||
var keys = Object.keys(fix.policies);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var val = fix.policies[keys[i]];
|
||||
try {
|
||||
await T.raw.put('/admin/settings/' + keys[i], {
|
||||
value: val === null ? 'false' : String(val)
|
||||
});
|
||||
} catch (_) { /* best effort */ }
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Provider / model discovery ──────────────────────────
|
||||
|
||||
async function provisionProvider() {
|
||||
var fix = T.fixtures;
|
||||
|
||||
// ── Read UI inputs (provider + API key) ──
|
||||
var ui = T._fixtureInput || {};
|
||||
var selectedProvider = ui.provSelect ? ui.provSelect.value : '';
|
||||
var apiKey = ui.keyInput ? ui.keyInput.value.trim() : '';
|
||||
var statusEl = ui.statusEl;
|
||||
|
||||
function setStatus(msg) {
|
||||
if (statusEl) statusEl.textContent = msg;
|
||||
console.log('[SDKR:fixtures] ' + msg);
|
||||
}
|
||||
|
||||
// Check if any configs already exist
|
||||
try {
|
||||
var configs = await T.raw.get('/admin/configs');
|
||||
var list = configs.data || configs.configs || [];
|
||||
if (list.length > 0) {
|
||||
fix.providerConfig = { id: list[0].id, name: list[0].name, provider: list[0].provider };
|
||||
setStatus('Using existing config: ' + list[0].name);
|
||||
}
|
||||
} catch (e) {
|
||||
fix.errors.push('config list: ' + e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
// If no config exists and user provided a provider + key, create one
|
||||
if (!fix.providerConfig && selectedProvider && apiKey) {
|
||||
try {
|
||||
var configData = {
|
||||
name: 'sdkr-fixture-' + selectedProvider,
|
||||
provider: selectedProvider,
|
||||
api_key: apiKey,
|
||||
scope: 'global'
|
||||
};
|
||||
setStatus('Creating ' + selectedProvider + ' config...');
|
||||
var created = await T.raw.post('/admin/configs', configData);
|
||||
if (created && created.id) {
|
||||
fix.providerConfig = { id: created.id, name: configData.name, provider: selectedProvider };
|
||||
fix._createdConfig = true; // mark for cleanup
|
||||
setStatus('Config created: ' + configData.name);
|
||||
T.registerCleanup(function () {
|
||||
if (fix._createdConfig && fix.providerConfig) {
|
||||
return T.safeDelete('/admin/configs/' + fix.providerConfig.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
setStatus('Config create failed: ' + e.message);
|
||||
fix.errors.push('config create: ' + e.message);
|
||||
}
|
||||
} else if (!fix.providerConfig && selectedProvider && !apiKey) {
|
||||
// Provider selected but no key — try creating without key (some providers
|
||||
// use server-side keys configured via env vars)
|
||||
try {
|
||||
var configData2 = {
|
||||
name: 'sdkr-fixture-' + selectedProvider,
|
||||
provider: selectedProvider,
|
||||
scope: 'global'
|
||||
};
|
||||
var created2 = await T.raw.post('/admin/configs', configData2);
|
||||
if (created2 && created2.id) {
|
||||
fix.providerConfig = { id: created2.id, name: configData2.name, provider: selectedProvider };
|
||||
fix._createdConfig = true;
|
||||
setStatus('Config created (server key): ' + configData2.name);
|
||||
T.registerCleanup(function () {
|
||||
if (fix._createdConfig && fix.providerConfig) {
|
||||
return T.safeDelete('/admin/configs/' + fix.providerConfig.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (_) {
|
||||
setStatus('No config — skipping model tests');
|
||||
}
|
||||
} else if (!fix.providerConfig) {
|
||||
setStatus('No provider selected — model tests will be skipped');
|
||||
}
|
||||
|
||||
// Fetch models if we have a config
|
||||
if (fix.providerConfig) {
|
||||
try {
|
||||
await T.raw.post('/admin/models/fetch', {});
|
||||
// Wait briefly for async model fetch
|
||||
await new Promise(function (r) { setTimeout(r, 1500); });
|
||||
} catch (_) { /* fetch may fail if no key */ }
|
||||
|
||||
// Look for an embedding model
|
||||
try {
|
||||
var models = await T.raw.get('/models/enabled');
|
||||
var list2 = models.data || [];
|
||||
for (var m = 0; m < list2.length; m++) {
|
||||
var caps = list2[m].capabilities || {};
|
||||
if (caps.embedding || list2[m].model_type === 'embedding') {
|
||||
fix.embeddingModel = {
|
||||
model_id: list2[m].model_id,
|
||||
provider_config_id: list2[m].provider_config_id
|
||||
};
|
||||
console.log('[SDKR:fixtures] Embedding model: ' + list2[m].model_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (_) { /* no models available */ }
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Team ────────────────────────────────────────────────
|
||||
|
||||
async function provisionTeam() {
|
||||
var fix = T.fixtures;
|
||||
try {
|
||||
var team = await T.raw.post('/admin/teams', {
|
||||
name: 'sdkr-fixture-' + Date.now(),
|
||||
description: 'SDK test runner fixture team'
|
||||
});
|
||||
if (team && team.id) {
|
||||
fix.team = { id: team.id, name: team.name };
|
||||
T.registerCleanup(function () {
|
||||
if (fix.team) return T.safeDelete('/admin/teams/' + fix.team.id);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
fix.errors.push('team: ' + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Provision / Teardown ────────────────────────────────
|
||||
|
||||
T.provisionFixtures = async function () {
|
||||
var fix = T.fixtures;
|
||||
if (fix.ready) return;
|
||||
|
||||
console.log('[SDKR:fixtures] Provisioning...');
|
||||
|
||||
// Policies
|
||||
await setPolicy('allow_user_personas', 'true');
|
||||
|
||||
// Provider + models
|
||||
await provisionProvider();
|
||||
|
||||
// Team
|
||||
await provisionTeam();
|
||||
|
||||
fix.ready = true;
|
||||
|
||||
if (fix.errors.length > 0) {
|
||||
console.warn('[SDKR:fixtures] ' + fix.errors.length + ' errors:', fix.errors);
|
||||
}
|
||||
console.log('[SDKR:fixtures] Ready —',
|
||||
'config:', fix.providerConfig ? fix.providerConfig.name : 'none',
|
||||
'| embedding:', fix.embeddingModel ? fix.embeddingModel.model_id : 'none',
|
||||
'| team:', fix.team ? fix.team.name : 'none'
|
||||
);
|
||||
};
|
||||
|
||||
T.teardownFixtures = async function () {
|
||||
await revertPolicies();
|
||||
// Cleanup functions registered via T.registerCleanup handle
|
||||
// the config + team deletion.
|
||||
T.fixtures = {
|
||||
ready: false, providerConfig: null, embeddingModel: null,
|
||||
team: null, policies: {}, errors: []
|
||||
};
|
||||
console.log('[SDKR:fixtures] Torn down');
|
||||
};
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user