// Generated, do not edit. sha256:762784c61e8bb974ae7fcd7e502db20b12fd6098e6d5292355f3d348d4e202f7 import { describe, it, beforeEach, mock } from 'node:test'; import assert from 'node:assert/strict'; import { createDbHarness } from '../helpers/db-node.mjs'; const harness = createDbHarness(); mock.module('../../server/db.js', { namedExports: harness.exports }); for (const mod of ['providers', 'price-source', 'price-history', 'api-metrics', 'preferences']) { mock.module(`../../client/data/${mod}.js`, { namedExports: await import(`../../server/data/${mod}.js`) }); } const facade = await import('../../client/price/providers.js'); let fetchCalls = []; globalThis.fetch = async (url, opties) => { fetchCalls.push({ url, body: opties?.body }); throw new Error('geen netwerk in deze test'); }; const { run, all, one, lastId } = harness.exports; let eur; function vasteKoersProvider({ capabilities = ['spot', 'history_point'], koers = 1.0 } = {}) { run(`INSERT INTO Provider (key, name, searchName, baseUrl, authenticationKind, authenticationRequired, isActive, isSeed, isSystem, createdAt) VALUES ('fixed','Vaste koers','vaste koers','','none',0,1,1,1,'2026-08-20T10:00:00.000Z')`); const id = lastId(); run(`INSERT INTO ProviderFixedRate (providerId, fiatPrice) VALUES (?, ?)`, [id, koers]); run(`INSERT INTO ProviderCoverage (providerId, symbol) VALUES (?, 'EUR')`, [id]); for (const capability of capabilities) { run(`INSERT INTO ProviderEndpoint (providerId, capability, method, pathTemplate, queryTemplate) VALUES (?, ?, 'GET', '', NULL)`, [id, capability]); } return id; } function bronkeuze(providerId, capabilities) { for (const capability of capabilities) { run(`INSERT OR IGNORE INTO PriceSource (assetId, capability, providerId, rank, status) VALUES (?, ?, ?, 1, 'confirmed')`, [eur, capability === 'spot' ? 'spot' : 'history', providerId]); } } const asset = () => one(`SELECT * FROM Asset WHERE id = ?`, [eur]); const prijsrijen = () => all( `SELECT Asset.symbol, Provider.key AS bron, PriceHistory.fiatPrice, PriceHistory.resolution FROM PriceHistory JOIN Asset ON Asset.id = PriceHistory.assetId JOIN Provider ON Provider.id = PriceHistory.providerId ORDER BY PriceHistory.resolution, PriceHistory.observedAt`); beforeEach(() => { harness.recreate(); facade.clearSpotCache(); fetchCalls = []; run(`INSERT INTO Asset (symbol, name, searchName, kind, unit, subunit, decimals, displayUnit) VALUES ('EUR','Euro','euro','fiat','EUR','cent',2,'unit')`); eur = lastId(); }); describe('vaste koers: de spot komt uit de provider en niet van het netwerk', () => { it('geeft 1,00 als spot, in het ene prijsveld', () => { bronkeuze(vasteKoersProvider(), ['spot']); return facade.liveSpotFor(asset()).then(spot => { assert.deepEqual(spot, { price: 1 }); assert.deepEqual(fetchCalls, [], 'er is niets naar buiten gegaan'); }); }); it('meet geen api-call, want er is geen api-call', async () => { bronkeuze(vasteKoersProvider(), ['spot']); await facade.liveSpotFor(asset()); await facade.liveSpotFor(asset()); assert.deepEqual(all(`SELECT * FROM ApiCallMetric`), []); }); it('legt de huidige waarde wél vast als tijdstip-punt', async () => { bronkeuze(vasteKoersProvider(), ['spot']); await facade.liveSpotFor(asset()); assert.deepEqual(prijsrijen(), [{ symbol: 'EUR', bron: 'fixed', fiatPrice: 1, resolution: 'timestamp' }]); }); it('laat een gewone provider wél naar buiten gaan', async () => { run(`INSERT INTO Provider (key, name, searchName, baseUrl, authenticationKind, authenticationRequired, isActive, isSeed, isSystem, createdAt) VALUES ('mempool','mempool','mempool','https://voorbeeld.test','none',0,1,1,0,'2026-08-20T10:00:00.000Z')`); const id = lastId(); run(`INSERT INTO ProviderCoverage (providerId, symbol) VALUES (?, 'EUR')`, [id]); run(`INSERT INTO ProviderEndpoint (providerId, capability, method, pathTemplate, queryTemplate) VALUES (?, 'spot', 'GET', '/prijs', NULL)`, [id]); bronkeuze(id, ['spot']); assert.equal(await facade.liveSpotFor(asset()), null, 'de stub gooit, dus geen koers'); assert.equal(fetchCalls.length, 1, 'en er is wél een verzoek gedaan'); assert.equal(fetchCalls[0].url, '/api/price/call'); }); }); describe('vaste koers: de historie', () => { it('vult price_history met een dagpunt van 1,00 via de spot-keten', async () => { bronkeuze(vasteKoersProvider(), ['spot', 'history_point']); await facade.ensurePriceHistoryFor(asset()); assert.deepEqual(prijsrijen().filter(r => r.resolution === 'day'), [{ symbol: 'EUR', bron: 'fixed', fiatPrice: 1, resolution: 'day' }]); assert.deepEqual(fetchCalls, []); }); it('levert een punt voor élke datum uit het verleden, met het tijdstip van die dag erbij', async () => { bronkeuze(vasteKoersProvider(), ['history_point']); assert.deepEqual(await facade.historicalPointForVia(asset(), '2019-12-31'), { price: 1, time: Date.parse('2019-12-31T00:00:00Z') / 1000 }); assert.deepEqual(await facade.historicalPointForVia(asset(), '2026-01-01'), { price: 1, time: Date.parse('2026-01-01T00:00:00Z') / 1000 }); assert.deepEqual(fetchCalls, []); }); it('slaat een punt op voor elke gevraagde peildatum', async () => { bronkeuze(vasteKoersProvider(), ['history_point']); await facade.ensurePointsAtFor(asset(), ['2025-01-01', '2026-01-01']); assert.deepEqual( all(`SELECT observedAt, fiatPrice, resolution FROM PriceHistory ORDER BY observedAt`), [{ observedAt: '2025-01-01T00:00:00Z', fiatPrice: 1, resolution: 'day' }, { observedAt: '2026-01-01T00:00:00Z', fiatPrice: 1, resolution: 'day' }]); assert.deepEqual(fetchCalls, []); }); it('heeft geen daggrid, en zegt dat ook', async () => { bronkeuze(vasteKoersProvider(), ['spot', 'history_point']); assert.equal(await facade.hasDailyGridFor(asset()), false); }); it('weigert een reeks te verzinnen als een vaste koers tóch daily_history claimt', async () => { bronkeuze(vasteKoersProvider({ capabilities: ['daily_history'] }), ['daily_history']); await assert.rejects(() => facade.ensurePriceHistoryFor(asset()), /vaste koers/); assert.deepEqual(prijsrijen(), [], 'en er staat niets verzonnen in de historie'); }); it('gebruikt de koers uit de tabel en niet een 1 uit de code', async () => { bronkeuze(vasteKoersProvider({ koers: 0.5 }), ['spot']); assert.deepEqual(await facade.liveSpotFor(asset()), { price: 0.5 }); }); });