// Generated, do not edit. sha256:e3545bf95485dc067f72c9e5c3b65d89fe5d9d0cb4f65e196bb3a28c383f4229 import { describe, it, beforeEach, mock } from 'node:test'; import assert from 'node:assert/strict'; import { mkdtempSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { createDbHarness } from '../helpers/db-node.mjs'; process.env.ASSETAPP_DATA_DIR = mkdtempSync(join(tmpdir(), 'assetapp-control-')); const { setInstallLocale } = await import('../../server/installation.mjs'); setInstallLocale('nl'); const harness = createDbHarness(); mock.module('../../server/db.js', { namedExports: harness.exports }); const echteConfig = await import('../../shared/config.js'); mock.module('../../shared/config.js', { namedExports: { ...echteConfig, CONFIG: Object.freeze({ ...echteConfig.CONFIG, COMMANDS: Object.freeze({ ...echteConfig.CONFIG.COMMANDS, CLAIM_SECONDS: 1 }), }), }, }); const { CONTROL_TOOLS } = await import('../../server/mcp/control-tools.mjs'); const { claimNextCommand, resolveCommand } = await import('../../server/data/commands.js'); const { setPref } = await import('../../server/data/preferences.js'); const { TARGETS, targetHash } = await import('../../shared/config.js'); const tool = CONTROL_TOOLS.find(t => t.name === 'navigate_to'); const waar = { scope: tool.scope, run: () => tool.run({}) }; const zetAan = async (control = true) => { await setPref('ai', 'allow_read', 1); await setPref('ai', 'allow_control', control ? 1 : 0); }; let busTijdensWachten = []; function browserDoet(uitkomst, detail = null, na = 60) { setTimeout(async () => { busTijdensWachten = harness.exports.all(`SELECT name FROM BusSignal ORDER BY id`).map(r => r.name); const c = await claimNextCommand('tab-1'); if (c) await resolveCommand(c.id, 'tab-1', uitkomst, detail); }, na); } beforeEach(async () => { harness.recreate(); busTijdensWachten = []; await zetAan(); }); describe('navigate_to: de poort', () => { it('declareert scope control, en niet read of write', () => { assert.equal(tool.scope, 'control'); }); it('weigert als het besturen uit staat, en verandert dan niets', async () => { await zetAan(false); await assert.rejects(() => tool.run({ target: 'AI_ACTIVITY' }), /niet besturen/); assert.equal(await claimNextCommand('tab-1'), null, 'er is geen opdracht klaargezet'); }); }); describe('navigate_to: het doel', () => { it('zet een opdracht klaar met het adres van de gekozen plek', async () => { browserDoet('done'); const r = await tool.run({ target: 'AI_ACTIVITY' }); assert.match(r.text, /Gedaan/); assert.match(r.text, new RegExp(targetHash(TARGETS.AI_ACTIVITY).replace('#', '#'))); }); it('deelt geen enkel administratieveld', async () => { browserDoet('done'); const r = await tool.run({ target: 'HOME' }); assert.deepEqual(r.fieldsShared, []); }); it('wijst een onbekende plek af zonder om te vallen, en noemt wat er wél is', async () => { const r = await tool.run({ target: 'DE_KEUKEN' }); assert.match(r.text, /geen bekende plek/); assert.match(r.text, /AI_ACTIVITY/); assert.match(r.text, /TAXES - Belastingen/, r.text); assert.equal(await claimNextCommand('tab-1'), null, 'en er staat niets klaar'); }); it('wijst een leeg of verkeerd getypt doel net zo af als een verzonnen doel', async () => { for (const args of [{ target: '' }, { target: 42 }, { target: null }]) { const r = await tool.run(args); assert.match(r.text, /geen bekende plek/, `${JSON.stringify(args)} hoort netjes afgewezen te worden`); } }); }); describe('navigate_to: het signaal gaat vóóruit', () => { it('zet het signaal op de bus vóórdat hij gaat wachten', async () => { browserDoet('done'); await tool.run({ target: 'AI_ACTIVITY' }); assert.ok(busTijdensWachten.includes('commands-changed'), `de bus was ${JSON.stringify(busTijdensWachten)} toen het tabblad keek`); }); }); describe('navigate_to: de uitkomst', () => { it('meldt het als de gebruiker het tegenhoudt, mét de reden', async () => { browserDoet('rejected', 'Tegengehouden door de gebruiker.'); const r = await tool.run({ target: 'AI_ACTIVITY' }); assert.match(r.text, /Niet uitgevoerd/); assert.match(r.text, /Tegengehouden door de gebruiker/); assert.match(r.text, /niet genavigeerd/); }); it('geeft de schuld niet aan de gebruiker als het tabblad zelf afwees', async () => { browserDoet('rejected', 'De opdracht wees niet naar een geldige plek in de app.'); const r = await tool.run({ target: 'HOME' }); assert.doesNotMatch(r.text, /de gebruiker/i); assert.match(r.text, /geldige plek/); }); it('zegt dat de app niet openstaat als niemand de opdracht oppakt', async () => { const r = await tool.run({ target: 'HOME' }); assert.match(r.text, /niet open/); assert.match(r.text, /niet genavigeerd/); }); }); describe('navigate_to zonder target: waar de gebruiker kijkt', () => { it('staat achter dezelfde schuif als navigeren', async () => { assert.equal(waar.scope, 'control'); await zetAan(false); await assert.rejects(() => waar.run({}), /niet besturen/); }); it('geeft de NAAM terug die navigate_to kent, niet alleen het adres', async () => { browserDoet('done', targetHash(TARGETS.CHARTS)); const r = await waar.run({}); assert.match(r.text, /CHARTS/); assert.match(r.text, new RegExp(targetHash(TARGETS.CHARTS))); }); it('noemt de belastingpagina bij naam en niet alleen bij adres', async () => { browserDoet('done', targetHash(TARGETS.TAXES)); const r = await waar.run({}); assert.match(r.text, /Belastingen/, r.text); assert.match(r.text, /TAXES/); }); it('geeft bij een plek buiten de registry het adres, en zegt erbij dat het geen naam is', async () => { browserDoet('done', '#/events/2026/detail'); const r = await waar.run({}); assert.match(r.text, /#\/events\/2026\/detail/); assert.match(r.text, /geen van de plekken/); }); it('deelt geen enkel administratieveld', async () => { browserDoet('done', targetHash(TARGETS.HOME)); const r = await waar.run({}); assert.deepEqual(r.fieldsShared, []); }); it('zegt dat de app niet openstaat als niemand antwoordt', async () => { const r = await waar.run({}); assert.match(r.text, /niet open/); }); it('verzint niets als het tabblad wel antwoordt maar zonder plek', async () => { browserDoet('done', ''); const r = await waar.run({}); assert.match(r.text, /liet niet weten/); }); });