Files
2026-10-29 11:57:29 +01:00

141 lines
6.3 KiB
JavaScript

// Generated, do not edit. sha256:9bbc954e336de37a55fc73310bcc550947a6f91fd3fa5c98c1be9921acfadb2d
import { describe, it, before, mock } from 'node:test';
import assert from 'node:assert/strict';
import { createDbHarness } from '../helpers/db-node.mjs';
import { fieldClass } from '../../server/ai/policy.js';
import { createTranslator } from '../../server/ai/translate.js';
const TEST_GEHEIM = 'test-geheim-voor-de-suite-0123456789abcdef';
const harness = createDbHarness({ seedPreferences: true });
mock.module('../../server/db.js', { namedExports: harness.exports });
const modules = {
accounts: await import('../../server/data/accounts.js'),
assets: await import('../../server/data/assets.js'),
'api-metrics': await import('../../server/data/api-metrics.js'),
connections: await import('../../server/data/connections.js'),
counts: await import('../../server/data/counts.js'),
dashboard: await import('../../server/data/dashboard.js'),
events: await import('../../server/data/events.js'),
'interest-credits': await import('../../server/data/interest-credits.js'),
'interest-schedules': await import('../../server/data/interest-schedules.js'),
labels: await import('../../server/data/labels.js'),
metals: await import('../../server/data/metals.js'),
notifications: await import('../../server/data/notifications.js'),
'price-history': await import('../../server/data/price-history.js'),
'price-source': await import('../../server/data/price-source.js'),
proposals: await import('../../server/data/proposals.js'),
providers: await import('../../server/data/providers.js'),
'scan-logs': await import('../../server/data/scan-logs.js'),
'tx-links': await import('../../server/data/tx-links.js'),
valuations: await import('../../server/data/valuations.js'),
'wallet-addresses': await import('../../server/data/wallet-addresses.js'),
'wallet-sources': await import('../../server/data/wallet-sources.js'),
'wallet-txs': await import('../../server/data/wallet-txs.js'),
};
const LOK = Object.freeze({
xpub: 'xpubLOKVOGEL66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666',
adres: 'bc1qlokvogel99999999999999999999999999zzzz',
txid: 'lokvogel4444444444444444444444444444444444444444444444444444beef',
extern: 'bc1qlokvogelextern9999999999999999999zzzzz',
notitie: 'LOKVOGELNOTITIE',
rekening: 'LOKVOGELREKENING',
});
const LOKWAARDEN = Object.values(LOK);
const MUTEERT = /^(create|update|delete|upsert|set|purge|merge|assert|emit|forget|take|sync|book|restore|import|save|apply|resolve|dismiss|link|unlink|reset|seed|ensure|add|remove|move|rename|record|log|mark|clear|prune|revert)/;
let ids = {};
let resultaten = [];
let overgeslagen = [];
before(async () => {
harness.recreate();
const asset = await modules.assets.createAsset(
{ symbol: 'BTC', name: 'Bitcoin', kind: 'crypto', unit: 'BTC', subunit: 'sat', decimals: 8, displayUnit: 'unit' });
const account = await modules.accounts.createAccount(
{ name: LOK.rekening, kind: 'wallet', isOwnCustody: 1, scanEnabled: 1 });
ids = { asset: idVan(asset), account: idVan(account) };
const bron = await modules['wallet-sources'].createWalletSource(
{ accountId: ids.account, kind: 'xpub', value: LOK.xpub, name: LOK.rekening, scriptType: 'p2wpkh' });
ids.bron = idVan(bron);
await modules['wallet-addresses'].upsertWalletAddresses([{
accountId: ids.account, sourceId: ids.bron, address: LOK.adres,
chainIndex: 0, derivationIndex: 3, balanceSats: 123456789, transactionCount: 2,
}]);
await modules['wallet-txs'].upsertWalletTxs([{
accountId: ids.account, sourceId: ids.bron, txid: LOK.txid,
direction: 'in', valueSats: 123456789, feeSats: 250, blockHeight: 800000,
blockTime: '2026-01-02T03:04:05Z', address: LOK.adres,
}]);
await modules.events.createEvent({
assetId: ids.asset, type: 'buy', occurredAt: '2026-01-02T03:04:05Z', amount: 123456789,
fiatPrice: 54321.5, toAccountId: ids.account, source: 'manual',
note: LOK.notitie, externalAddress: LOK.extern,
});
for (const [mod, exports] of Object.entries(modules)) {
for (const [naam, fn] of Object.entries(exports)) {
if (typeof fn !== 'function' || MUTEERT.test(naam)) { overgeslagen.push(`${mod}.${naam}`); continue; }
let ruw, gelukt = false;
for (const args of [[], [ids.account], [ids.bron], [ids.asset]]) {
try { ruw = await fn(...args); gelukt = true; break; } catch { }
}
if (gelukt && ruw !== undefined) resultaten.push({ naam: `${mod}.${naam}`, ruw });
else overgeslagen.push(`${mod}.${naam}`);
}
}
});
function idVan(r) { return typeof r === 'object' && r !== null ? (r.id ?? r) : r; }
function bevat(structuur, naald) {
return JSON.stringify(structuur ?? null).includes(naald);
}
describe('AI-sweep, richting 1: geen lokvogel overleeft de vertaalslag', () => {
it('roept genoeg leesfuncties aan om iets te bewijzen', () => {
assert.ok(resultaten.length >= 30,
`te weinig aangeroepen om iets te bewijzen: ${resultaten.length} gelukt, ${overgeslagen.length} overgeslagen`);
});
it('ziet de lokvogels in de ONvertaalde uitvoer (anders bewijst de rest niets)', () => {
const gezien = LOKWAARDEN.filter(w => resultaten.some(r => bevat(r.ruw, w)));
assert.deepEqual(gezien.sort(), [...LOKWAARDEN].sort(),
'niet elke lokvogel kwam in de ruwe uitvoer voor; de sweep raakt die paden dus niet');
});
it('laat geen enkele lokvogel door de vertaalslag', () => {
const t = createTranslator({ secret: TEST_GEHEIM });
const lekken = [];
for (const { naam, ruw } of resultaten) {
const uit = t.toAi(ruw);
for (const w of LOKWAARDEN) if (bevat(uit, w)) lekken.push(`${naam} lekt ${w.slice(0, 16)}…`);
}
assert.deepEqual(lekken, []);
});
});
describe('AI-sweep, richting 2: elk veld in de uitvoer is gedeclareerd', () => {
it('kent voor elk veld in de vertaalde uitvoer een klasse', () => {
const t = createTranslator({ secret: TEST_GEHEIM });
const onbekend = new Set();
const loop = (v) => {
if (Array.isArray(v)) { v.forEach(loop); return; }
if (v === null || typeof v !== 'object') return;
for (const [k, w] of Object.entries(v)) {
if (fieldClass(k) === null) onbekend.add(k);
loop(w);
}
};
for (const { ruw } of resultaten) loop(t.toAi(ruw));
assert.deepEqual([...onbekend].sort(), []);
});
});