// Generated, do not edit. sha256:d705db22a94bcceb849648fab7596bd5a84e34d8b58a472ec9dc677c8db0cc0a import { describe, it, before, after } from 'node:test'; import assert from 'node:assert/strict'; import { spawn } from 'node:child_process'; import { DatabaseSync } from 'node:sqlite'; import { mkdtemp, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { fileURLToPath } from 'node:url'; const WORTEL = join(fileURLToPath(import.meta.url), '..', '..', '..'); const STDIO = join(WORTEL, 'server', 'mcp', 'stdio.mjs'); let dir, dbPad, proc, buffer = '', wachtenden = []; function stuur(bericht) { return new Promise((resolve, reject) => { wachtenden.push(resolve); const klaar = setTimeout(() => reject(new Error('geen antwoord binnen 10s')), 10_000); wachtenden[wachtenden.length - 1] = (a) => { clearTimeout(klaar); resolve(a); }; proc.stdin.write(`${JSON.stringify(bericht)}\n`); }); } before(async () => { dir = await mkdtemp(join(tmpdir(), 'assetapp-mcp-stdio-')); dbPad = join(dir, 'MyAssets', 'db.sqlite'); const env = { ...process.env, ASSETAPP_DATA_DIR: dir, ASSETAPP_DB_FILE: dbPad }; const eerste = spawn(process.execPath, [STDIO], { env, stdio: 'ignore' }); assert.equal(await new Promise((klaar) => eerste.once('exit', klaar)), 0, 'een verse installatie stopt met de koppeling uit'); const db = new DatabaseSync(dbPad); db.exec(`UPDATE Preference SET value = '1' WHERE scope = 'ai' AND key = 'enabled'`); db.close(); proc = spawn(process.execPath, [STDIO], { env, stdio: ['pipe', 'pipe', 'pipe'] }); proc.stdout.on('data', (brok) => { buffer += brok.toString(); let n; while ((n = buffer.indexOf('\n')) >= 0) { const regel = buffer.slice(0, n).trim(); buffer = buffer.slice(n + 1); if (regel) (wachtenden.shift() || (() => {}))(JSON.parse(regel)); } }); await new Promise((resolve) => proc.stderr.once('data', resolve)); }); after(async () => { proc.stdin.end(); await new Promise((resolve) => proc.once('exit', resolve)); await rm(dir, { recursive: true, force: true }); }); describe('mcp-stdio: het proces beantwoordt bericht na bericht', () => { it('antwoordt op initialize', async () => { const a = await stuur({ jsonrpc: '2.0', id: 1, method: 'initialize', params: {} }); assert.equal(a.id, 1); assert.ok(a.result.serverInfo.name, 'er hoort een servernaam in te staan'); }); it('geeft de toollijst, en doet dat twee keer achter elkaar', async () => { const een = await stuur({ jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} }); assert.ok(een.result.tools.length > 0, 'er hoort minstens één tool te zijn'); const twee = await stuur({ jsonrpc: '2.0', id: 3, method: 'tools/list', params: {} }); assert.deepEqual(twee.result.tools.map(t => t.name), een.result.tools.map(t => t.name)); }); it('voert een tool uit en legt hem vast in het auditlog', async () => { const a = await stuur({ jsonrpc: '2.0', id: 4, method: 'tools/call', params: { name: 'connection_test', arguments: {} }, }); assert.equal(a.id, 4); assert.equal(a.error, undefined, `geen fout verwacht: ${JSON.stringify(a.error)}`); assert.ok(a.result.content[0].text, 'er hoort een antwoord in te staan'); }); }); describe('mcp-stdio: de schuif "Actief" zet dit proces uit', () => { it('stopt bij het eerstvolgende bericht zodra de schuif uit gaat', async () => { const db = new DatabaseSync(dbPad); db.exec(`PRAGMA busy_timeout = 5000`); db.exec(`INSERT INTO Preference (scope, key, value) VALUES ('ai', 'enabled', '0') ON CONFLICT (scope, key) DO UPDATE SET value = '0'`); db.close(); const antwoord = await stuur({ jsonrpc: '2.0', id: 99, method: 'tools/list', params: {} }); assert.ok(antwoord.error, 'het laatste bericht hoort nog een antwoord te krijgen'); assert.match(antwoord.error.message, /Actief/, 'en dat antwoord wijst de juiste schuif aan'); const code = await new Promise((klaar) => proc.once('exit', klaar)); assert.equal(code, 0, 'een uitgezette koppeling is een keuze en geen storing'); }); });