Files
AtreidesAssetsFree/tests/repo/counts-scanlogs.test.mjs
2026-10-29 11:57:29 +01:00

166 lines
6.8 KiB
JavaScript

// Generated, do not edit. sha256:dddfdfd366ef82253787978dcf8368fdcb9f0cf259774eee0d63e666ef6c597c
import { describe, it, beforeEach, mock } from 'node:test';
import assert from 'node:assert/strict';
import { createDbHarness } from '../helpers/db-node.mjs';
import { CONFIG, ENUMS } from '../../shared/config.js';
const harness = createDbHarness();
mock.module('../../server/db.js', { namedExports: harness.exports });
const { counts, tableCounts } = await import('../../server/data/counts.js');
const { createScanLog, latestScanLog, listScanLogs } = await import('../../server/data/scan-logs.js');
let ctx;
beforeEach(() => {
harness.recreate();
harness.exports.run(
`INSERT INTO Asset (symbol, name, searchName, kind, unit, subunit, decimals, displayUnit) VALUES ('BTC','Bitcoin','bitcoin','crypto','BTC','sat',8,'subunit')`);
const btc = harness.exports.lastId();
harness.exports.run(
`INSERT INTO Account (name, searchName, kind, isOwnCustody, scanEnabled, isActive, closedAt) VALUES ('Kluis','kluis','wallet',1,1,1,NULL)`);
ctx = { btc, account: harness.exports.lastId() };
});
function gebeurtenis() {
harness.exports.run(
`INSERT INTO Event (assetId, type, occurredAt, amount, fiatPrice, toAccountId, source, createdAt)
VALUES (?, 'buy', '2024-01-01T00:00:00', 100000, 50000, ?, 'manual', '2024-01-01T00:00:00')`,
[ctx.btc, ctx.account]);
}
describe('counts', () => {
it('telt de vier hoofd-entiteiten', () => {
gebeurtenis();
harness.exports.run(
`INSERT INTO Valuation (assetId, valuedOn, accountId, balance, fiatRate, rateAt, source)
VALUES (?, '2024-12-31', ?, 1, 1, '2024-12-31T23:00:00', 'manual')`, [ctx.btc, ctx.account]);
assert.deepEqual(counts(), { assets: 1, accounts: 1, events: 1, valuations: 1 });
});
it('geeft nullen op een lege database in plaats van niets', () => {
harness.exports.run(`DELETE FROM Asset`);
harness.exports.run(`DELETE FROM Account`);
assert.deepEqual(counts(), { assets: 0, accounts: 0, events: 0, valuations: 0 });
});
});
describe('tableCounts', () => {
it('geeft een rij per tabel uit de whitelist, in dezelfde volgorde', () => {
const rijen = tableCounts();
assert.deepEqual(rijen.map(r => r.name), [...CONFIG.DB_TABLES],
'de widget toont de lijst in configuratie-volgorde, dus die mag niet gesorteerd raken');
});
it('draait elke naam uit de whitelist echt af zonder te werpen', () => {
const rijen = tableCounts();
assert.ok(rijen.length >= 10, `verwacht een flinke whitelist, kreeg ${rijen.length}`);
for (const r of rijen) {
assert.equal(typeof r.n, 'number', `${r.name} gaf geen getal terug`);
assert.ok(r.n >= 0);
}
});
it('telt echt en geeft niet overal nul', () => {
gebeurtenis();
const perTabel = Object.fromEntries(tableCounts().map(r => [r.name, r.n]));
assert.equal(perTabel.Event, 1);
assert.equal(perTabel.Asset, 1);
assert.equal(perTabel.Valuation, 0);
});
});
describe('createScanLog', () => {
const scan = (extra = {}) => ({ accountId: ctx.account, status: 'success', ...extra });
const rij = (id) => harness.exports.one(`SELECT * FROM ScanLog WHERE id = ?`, [id]);
it('bewaart de velden en geeft het id terug', async () => {
const id = await createScanLog(scan({
scannedAt: '2024-05-01T12:00:00', addressesFound: 12, balanceFound: 750_000, proposalsCreated: 2,
}));
const s = rij(id);
assert.equal(s.accountId, ctx.account);
assert.equal(s.scannedAt, '2024-05-01T12:00:00');
assert.equal(s.status, 'success');
assert.equal(s.addressesFound, 12);
assert.equal(s.balanceFound, 750_000);
assert.equal(s.proposalsCreated, 2);
});
it('zet het tijdstip zelf als de aanroeper er geen geeft', async () => {
const id = await createScanLog(scan());
assert.ok(rij(id).scannedAt, 'een scan zonder tijdstip is niet te ordenen');
});
it('bewaart rawData als JSON-tekst', async () => {
const id = await createScanLog(scan({ rawData: { adressen: ['bc1q…'], saldo: 750_000 } }));
const ruw = rij(id).rawData;
assert.equal(typeof ruw, 'string');
assert.deepEqual(JSON.parse(ruw), { adressen: ['bc1q…'], saldo: 750_000 });
});
it('laat rawData leeg als er niets is', async () => {
const id = await createScanLog(scan());
assert.equal(rij(id).rawData, null, 'geen "null" als tekst, maar echt leeg');
});
it('accepteert elke status uit de registry en weigert de rest', async () => {
for (const status of ENUMS.SCAN_STATUS) {
const id = await createScanLog(scan({ status }));
assert.equal(rij(id).status, status);
}
await assert.rejects(() => createScanLog(scan({ status: 'bijna-goed' })), /status/);
});
it('persisteert', async () => {
const voor = harness.calls.persist;
await createScanLog(scan());
assert.equal(harness.calls.persist, voor + 1);
});
});
describe('latestScanLog en listScanLogs', () => {
const scan = (extra = {}) => createScanLog({ accountId: ctx.account, status: 'success', ...extra });
it('geeft de laatste scan van dat account', async () => {
await scan({ scannedAt: '2024-01-01T00:00:00' });
const laatste = await scan({ scannedAt: '2024-06-01T00:00:00' });
assert.equal(latestScanLog(ctx.account).id, laatste);
});
it('kiest bij een gelijk tijdstip de hoogste id', async () => {
await scan({ scannedAt: '2024-06-01T00:00:00', addressesFound: 1 });
const tweede = await scan({ scannedAt: '2024-06-01T00:00:00', addressesFound: 2 });
assert.equal(latestScanLog(ctx.account).id, tweede);
assert.equal(latestScanLog(ctx.account).addressesFound, 2);
});
it('geeft null als er nog nooit gescand is', () => {
assert.equal(latestScanLog(ctx.account), null);
});
it('kijkt alleen naar het gevraagde account', async () => {
harness.exports.run(
`INSERT INTO Account (name, searchName, kind, isOwnCustody, scanEnabled, isActive, closedAt) VALUES ('Ander','ander','wallet',1,1,1,NULL)`);
const ander = harness.exports.lastId();
await scan({ scannedAt: '2024-06-01T00:00:00' });
assert.equal(latestScanLog(ander), null);
assert.deepEqual(listScanLogs(ander), []);
});
it('geeft de volledige historie, nieuwste eerst', async () => {
await scan({ scannedAt: '2024-01-01T00:00:00' });
await scan({ scannedAt: '2024-06-01T00:00:00' });
await scan({ scannedAt: '2024-03-01T00:00:00' });
assert.deepEqual(listScanLogs(ctx.account).map(s => s.scannedAt),
['2024-06-01T00:00:00', '2024-03-01T00:00:00', '2024-01-01T00:00:00']);
});
it('is append-only: een tweede scan overschrijft de eerste niet', async () => {
await scan({ scannedAt: '2024-01-01T00:00:00', status: 'failed' });
await scan({ scannedAt: '2024-06-01T00:00:00', status: 'success' });
assert.equal(listScanLogs(ctx.account).length, 2);
assert.deepEqual(listScanLogs(ctx.account).map(s => s.status), ['success', 'failed']);
});
});