Versie 0.2.0
This commit is contained in:
commit
e77d8fd373
495 files changed
+81026
No files matched your search
@@ -0,0 +1,143 @@
|
||||
// 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 });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user