// Generated, do not edit. sha256:6f5b8502746b6ae69cfa949fb746f614f73c7a3a69761281686d9078e5f7285a 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 { listProviders, getProvider } = await import('../../server/data/providers.js'); const { listAssets } = await import('../../server/data/assets.js'); const { integrationsJson, INTEGRATIONS_FORMAT } = await import('../../server/integrations-export.mjs'); const { run, lastId } = harness.exports; function provider(key, { system = false, auth = 'none', required = 0, header = null, param = null } = {}) { run(`INSERT INTO Provider (key, name, searchName, baseUrl, authenticationKind, authenticationRequired, authenticationHeaderName, authenticationParameterName, isActive, isSeed, isSystem, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, 1, ?, '2026-10-10')`, [key, key, key, system ? '' : `https://${key}.example`, auth, required, header, param, system ? 1 : 0]); return lastId(); } const endpoint = (id, capability, path, query = null, quote = null, interval = null) => run(`INSERT INTO ProviderEndpoint (providerId, pathTemplate, queryTemplate, capability, method, quoteCurrency, minIntervalSeconds) VALUES (?, ?, ?, ?, 'GET', ?, ?)`, [id, path, query, capability, quote, interval]); const output = (id, capability, field, path, transform) => run(`INSERT INTO ProviderOutputMap (providerId, jsonPath, capability, internalField, transform) VALUES (?, ?, ?, ?, ?)`, [id, path, capability, field, transform]); const symbol = (id, sym, externalId, { catchAll = false, unit = null } = {}) => run(`INSERT INTO ProviderInputMap (providerId, symbol, externalId, quoteUnit, isCatchAll) VALUES (?, ?, ?, ?, ?)`, [id, catchAll ? null : sym, externalId, unit, catchAll ? 1 : 0]); const covers = (id, ...syms) => { for (const s of syms) run(`INSERT INTO ProviderCoverage (providerId, symbol) VALUES (?, ?)`, [id, s]); }; const asset = (sym, kind) => run(`INSERT INTO Asset (symbol, name, searchName, kind, unit, subunit, decimals, displayUnit) VALUES (?, ?, ?, ?, ?, NULL, 8, 'unit')`, [sym, sym, sym.toLowerCase(), kind, sym]); const exported = (base = 'EUR') => integrationsJson(listProviders().map(p => getProvider(p.key)), listAssets(), base); beforeEach(() => { harness.recreate(); for (const k of ['manual', 'atreides_services', 'fixed']) provider(k, { system: true }); asset('XAU', 'metal'); asset('LINK', 'crypto'); const gold = provider('goldapi', { auth: 'header_key', required: 1, header: 'x-access-token' }); endpoint(gold, 'spot', '/api/{symbol}/EUR', null, 'EUR', 3600); endpoint(gold, 'history_point', '/api/{symbol}/EUR/{date}', null, 'EUR'); output(gold, 'spot', 'price', 'price', 'troy_ounce_to_gram'); covers(gold, 'XAU'); run(`INSERT INTO ProviderCallLimit (providerId, callsPerMonth) VALUES (?, 100)`, [gold]); const euler = provider('eulerpool', { auth: 'query_key', required: 1, param: 'token' }); endpoint(euler, 'daily_history', '/api/1/{external_id}/quotes/{symbol}', null, 'USD'); symbol(euler, null, 'crypto', { catchAll: true }); symbol(euler, 'XAU', 'commodity', { unit: 'ozt' }); covers(euler, 'LINK', 'XAU', 'NOASSET'); const bitvavo = provider('bitvavo', { auth: 'hmac' }); run(`INSERT INTO ProviderAuthenticationHmac (providerId, messageParts, keyHeader, signatureHeader, timestampHeader, windowHeader, windowMs, hashAlgorithm, encoding) VALUES (?, 'timestamp,method,full_path,body', 'K', 'S', 'T', 'W', 10000, 'SHA-256', 'hex')`, [bitvavo]); endpoint(bitvavo, 'spot', '/v2/ticker/price', 'market={symbol}-EUR', null); covers(bitvavo, 'LINK'); }); describe('integrationsJson', () => { it('carries every source with all it has, and no system provider', () => { const e = exported(); assert.equal(e.format, INTEGRATIONS_FORMAT); assert.deepEqual(e.providers.map(p => p.key), ['bitvavo', 'eulerpool', 'goldapi']); const gold = e.providers.find(p => p.key === 'goldapi'); assert.deepEqual(gold.auth, { kind: 'header_key', required: true, headerName: 'x-access-token', parameterName: null, hmac: null }); assert.equal(gold.callsPerMonth, 100); assert.deepEqual(gold.endpoints.map(x => [x.capability, x.pathTemplate, x.minIntervalSeconds]), [['history_point', '/api/{symbol}/EUR/{date}', null], ['spot', '/api/{symbol}/EUR', 3600]]); assert.deepEqual(gold.outputs, [{ capability: 'spot', internalField: 'price', jsonPath: 'price', transform: 'troy_ounce_to_gram' }]); }); it('keeps the HMAC recipe and the catch-all, which only the reader can judge', () => { const e = exported(); assert.equal(e.providers.find(p => p.key === 'bitvavo').auth.hmac.messageParts, 'timestamp,method,full_path,body'); assert.deepEqual(e.providers.find(p => p.key === 'eulerpool').inputMap, [ { symbol: 'XAU', externalId: 'commodity', quoteUnit: 'ozt', isCatchAll: false }, { symbol: null, externalId: 'crypto', quoteUnit: null, isCatchAll: true }, ]); }); it('fills in the unit of account for a NULL quote, and the kind of a covered symbol', () => { const bitvavo = exported('USD').providers.find(p => p.key === 'bitvavo'); assert.equal(bitvavo.endpoints[0].quote, 'USD'); assert.deepEqual(exported().providers.find(p => p.key === 'eulerpool').coverage, [{ symbol: 'LINK', kind: 'crypto' }, { symbol: 'NOASSET', kind: null }, { symbol: 'XAU', kind: 'metal' }]); }); it('carries no secret and gives the same file twice', () => { const text = JSON.stringify(exported()); assert.ok(!/api_key|api_secret|secret"/i.test(text), 'a secret field is in the export'); assert.equal(JSON.stringify(exported()), text); }); });