Files
LangBot/web/tests/unit/wizard-page-bot.test.mjs
T

121 lines
3.2 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs';
import test from 'node:test';
import ts from 'typescript';
function load(source, deps = {}, globals = {}) {
const code = ts.transpileModule(
fs.readFileSync(new URL('../../src/' + source, import.meta.url), 'utf8'),
{
compilerOptions: {
module: ts.ModuleKind.CommonJS,
target: ts.ScriptTarget.ES2022,
},
},
).outputText;
const mod = { exports: {} };
new Function('require', 'module', 'exports', ...Object.keys(globals), code)(
(id) => {
assert.ok(id in deps, id);
return deps[id];
},
mod,
mod.exports,
...Object.values(globals),
);
return mod.exports;
}
test('wizard Runner recovery waits for the matching plugin registration without installing twice', async () => {
const scope = 'wizard-ai-runner';
const pending = {
scope,
taskId: 12,
pluginId: 'qa/runner',
pluginAuthor: 'qa',
pluginName: 'runner',
pluginLabel: 'QA Runner',
startedAt: -1000000,
};
const storage = new Map([
[`langbot-runner-install:alpha:${scope}`, JSON.stringify(pending)],
]);
const calls = [],
progress = [];
let workspace = 'beta',
tick = 0,
polls = 0;
const option = {
name: 'plugin:qa/runner/default',
label: { en_US: 'Registered Runner' },
};
const configTab = {
name: 'ai',
stages: [
{
name: 'runner',
config: [
{
name: 'id',
options: [{ name: 'plugin:qa/runner-neighbor/default' }],
},
],
},
],
};
const httpClient = {
getAsyncTask: async (id) => {
calls.push(['task', id]);
return { runtime: { done: ++polls >= 2 } };
},
getGeneralPipelineMetadata: async () => {
calls.push(['metadata']);
if (calls.filter((value) => value[0] === 'metadata').length === 2)
configTab.stages[0].config[0].options.push(option);
return { configs: [configTab] };
},
installPluginFromMarketplace: async () =>
assert.fail('recovery must not reinstall'),
};
const api = load(
'app/home/agents/runner-marketplace.ts',
{
'@/app/infra/http/HttpClient': { httpClient },
'@/app/infra/http': {},
'@/app/infra/http/workspaceContext': {
getActiveWorkspaceUuid: () => workspace,
},
'@/app/infra/entities/plugin': {},
},
{
window: new EventTarget(),
CustomEvent,
sessionStorage: {
getItem: (key) => storage.get(key) ?? null,
removeItem: (key) => storage.delete(key),
},
Date: { now: () => tick },
setTimeout: (callback, ms) => {
tick += ms;
queueMicrotask(callback);
},
},
);
assert.equal(await api.resumePendingRunnerInstall(scope), null);
workspace = 'alpha';
assert.equal(await api.resumePendingRunnerInstall('other'), null);
const recovered = await api.resumePendingRunnerInstall(scope, (task) =>
progress.push(task.runtime.done),
);
assert.equal(recovered.runner, option);
assert.equal(recovered.configTab, configTab);
assert.deepEqual(progress, [false, true]);
assert.deepEqual(calls, [
['task', 12],
['task', 12],
['metadata'],
['metadata'],
]);
assert.equal(storage.size, 0);
});