91 lines
4.6 KiB
JavaScript
91 lines
4.6 KiB
JavaScript
// Generated, do not edit. sha256:0be72af65d499e9d6366a58d1015da19ddfe0424554e9524fa644fdd737582f5
|
|
import { describe, it, beforeEach, mock } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import { createDbHarness } from '../helpers/db-node.mjs';
|
|
|
|
const harness = createDbHarness({ seedPreferences: true });
|
|
mock.module('../../server/db.js', { namedExports: harness.exports });
|
|
|
|
const { priceSeriesExport } = await import('../../server/data/price-history.js');
|
|
const { priceHistoryCsv, CSV_COLUMNS } = await import('../../server/price-export.mjs');
|
|
|
|
const { run, lastId } = harness.exports;
|
|
let btc, goud, eur;
|
|
|
|
function provider(key, { system = false, dekt = [] } = {}) {
|
|
run(`INSERT INTO Provider (key, name, searchName, baseUrl, authenticationKind, authenticationRequired, isActive, isSeed, isSystem, createdAt)
|
|
VALUES (?, ?, ?, '', 'none', 0, 1, 1, ?, '2026-10-09')`, [key, key, key, system ? 1 : 0]);
|
|
const id = lastId();
|
|
for (const s of dekt) run(`INSERT INTO ProviderCoverage (providerId, symbol) VALUES (?, ?)`, [id, s]);
|
|
return id;
|
|
}
|
|
function asset(symbol, kind) {
|
|
run(`INSERT INTO Asset (symbol, name, searchName, kind, unit, subunit, decimals, displayUnit)
|
|
VALUES (?, ?, ?, ?, ?, NULL, 8, 'unit')`, [symbol, symbol, symbol.toLowerCase(), kind, symbol]);
|
|
return lastId();
|
|
}
|
|
const koers = (assetId, providerId, prijs, observedAt, resolution = 'day', createdAt = null) =>
|
|
run(`INSERT INTO PriceHistory (assetId, providerId, fiatPrice, resolution, observedAt, createdAt) VALUES (?, ?, ?, ?, ?, ?)`,
|
|
[assetId, providerId, prijs, resolution, observedAt, createdAt]);
|
|
|
|
beforeEach(() => {
|
|
harness.recreate();
|
|
btc = asset('BTC', 'crypto');
|
|
goud = asset('XAU', 'metal');
|
|
eur = asset('EUR', 'fiat');
|
|
const bitvavo = provider('bitvavo', { dekt: ['BTC'] });
|
|
const goldapi = provider('goldapi', { dekt: ['XAU'] });
|
|
const manual = provider('manual', { system: true });
|
|
const dienst = provider('atreides_services', { system: true });
|
|
const vast = provider('fixed', { system: true, dekt: ['EUR'] });
|
|
koers(btc, bitvavo, 61000, '2026-10-02T00:00:00Z', 'day', '2026-10-03T01:00:00Z');
|
|
koers(btc, bitvavo, 60000, '2026-10-01T00:00:00Z');
|
|
koers(btc, bitvavo, 61500, '2026-10-02T14:32:00Z', 'timestamp');
|
|
koers(goud, goldapi, 105.5, '2026-10-01T00:00:00Z');
|
|
koers(btc, manual, 50000, '2026-09-30T00:00:00Z');
|
|
koers(btc, dienst, 61234.5, '2026-10-09T10:00:00Z', 'timestamp');
|
|
koers(eur, vast, 1, '2026-10-01T00:00:00Z');
|
|
koers(goud, bitvavo, 999, '2026-10-01T00:00:00Z');
|
|
});
|
|
|
|
describe('priceSeriesExport: wat meegaat', () => {
|
|
it('alleen de koersreeksen van echte bronnen, in een vaste volgorde', () => {
|
|
const rijen = priceSeriesExport().map(r => `${r.symbol}|${r.source}|${r.resolution}|${r.observedAt}`);
|
|
assert.deepEqual(rijen, [
|
|
'BTC|bitvavo|day|2026-10-01T00:00:00Z',
|
|
'BTC|bitvavo|day|2026-10-02T00:00:00Z',
|
|
'BTC|bitvavo|timestamp|2026-10-02T14:32:00Z',
|
|
'XAU|goldapi|day|2026-10-01T00:00:00Z',
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('priceHistoryCsv: het bestand', () => {
|
|
it('kolommen zoals de CSV van de dienst, met eenheid en resolutie erbij', () => {
|
|
const regels = priceHistoryCsv(priceSeriesExport(), 'EUR').trim().split('\n');
|
|
assert.equal(regels[0], CSV_COLUMNS.join(','));
|
|
assert.equal(regels[0], 'instrument,source,quote,unit,resolution,observed_at_utc,fetched_at_utc,price');
|
|
assert.equal(regels[2], 'crypto:BTC,bitvavo,EUR,,day,2026-10-02T00:00:00.000Z,2026-10-03T01:00:00.000Z,61000');
|
|
assert.equal(regels[4], 'metal:XAU,goldapi,EUR,g,day,2026-10-01T00:00:00.000Z,,105.5');
|
|
});
|
|
|
|
it('is herhaalbaar: twee keer exporteren geeft hetzelfde bestand', () => {
|
|
assert.equal(priceHistoryCsv(priceSeriesExport(), 'EUR'), priceHistoryCsv(priceSeriesExport(), 'EUR'));
|
|
});
|
|
|
|
it('noemt de rekenvaluta van de portefeuille, want daarin staat de historie', () => {
|
|
assert.match(priceHistoryCsv(priceSeriesExport(), 'USD').split('\n')[1], /^crypto:BTC,bitvavo,USD,/);
|
|
});
|
|
|
|
it('slaat een rij zonder bruikbare tijd of prijs over, en zet een lastige waarde tussen aanhalingstekens', () => {
|
|
const csv = priceHistoryCsv([
|
|
{ kind: 'crypto', symbol: 'BTC', source: 'a,b', resolution: 'day', observedAt: '2026-10-01', createdAt: null, fiatPrice: 1 },
|
|
{ kind: 'crypto', symbol: 'BTC', source: 'x', resolution: 'day', observedAt: 'geen datum', createdAt: null, fiatPrice: 1 },
|
|
{ kind: 'crypto', symbol: 'BTC', source: 'x', resolution: 'day', observedAt: '2026-10-01', createdAt: null, fiatPrice: 0 },
|
|
], 'EUR').trim().split('\n');
|
|
assert.equal(csv.length, 2);
|
|
assert.equal(csv[1], 'crypto:BTC,"a,b",EUR,,day,2026-10-01T00:00:00.000Z,,1');
|
|
});
|
|
});
|