Versie 0.2.0
This commit is contained in:
commit
e77d8fd373
495 files changed
+81026
No files matched your search
@@ -0,0 +1,215 @@
|
||||
// Generated, do not edit. sha256:38c4b07d1566cda74ef6cac4d031f49fd52004b6938fdee8f13e3e7678fc12c7
|
||||
import { describe, it, beforeEach, mock } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { createDbHarness } from '../helpers/db-node.mjs';
|
||||
import { createNwcApiFake } from '../helpers/nwc-api.mjs';
|
||||
|
||||
const harness = createDbHarness({ seedPreferences: true });
|
||||
mock.module('../../server/db.js', { namedExports: harness.exports });
|
||||
createNwcApiFake().registreer();
|
||||
|
||||
let stand = { level: 'free', enforced: true, why: 'none' };
|
||||
const echt = await import('../../server/license.mjs');
|
||||
mock.module('../../server/license.mjs', {
|
||||
namedExports: {
|
||||
...echt,
|
||||
licenseState: () => stand,
|
||||
capacityReached: (soort, huidig) => echt.capacityReached(soort, huidig, stand),
|
||||
hasFeature: (naam) => echt.hasFeature(naam, stand),
|
||||
allowedAssets: () => echt.allowedAssets(stand),
|
||||
},
|
||||
});
|
||||
|
||||
const { createAsset, updateAsset, deleteAsset, listAssets } = await import('../../server/data/assets.js');
|
||||
const { createAccount, listAccounts } = await import('../../server/data/accounts.js');
|
||||
const { createValuation, listValuations } = await import('../../server/data/valuations.js');
|
||||
const { saveConnection, listConnections } = await import('../../server/data/connections.js');
|
||||
const { setPriceSourceRank } = await import('../../server/data/price-source.js');
|
||||
const { createWalletSource, updateWalletSource, listWalletSources } = await import('../../server/data/wallet-sources.js');
|
||||
|
||||
const EEN = {
|
||||
symbol: 'BTC', name: 'Bitcoin', kind: 'crypto', unit: 'BTC', subunit: 'sat',
|
||||
decimals: 8, displayUnit: 'unit', taxCategory: null,
|
||||
};
|
||||
const TWEE = { ...EEN, symbol: 'XAU', name: 'Goud', kind: 'metal', unit: 'g', subunit: 'mg', decimals: 3 };
|
||||
|
||||
beforeEach(() => {
|
||||
harness.recreate();
|
||||
stand = { level: 'free', enforced: true, why: 'none' };
|
||||
});
|
||||
|
||||
describe('de gratis stand op fiatrekeningen', () => {
|
||||
const bank = (name) => ({ name, kind: 'bank', isOwnCustody: false, scanEnabled: false, taxCategory: null });
|
||||
|
||||
it('laat de EERSTE bankrekening toe en weigert de tweede', async () => {
|
||||
await createAccount(bank('ING'));
|
||||
await assert.rejects(() => createAccount(bank('Rabo')), (fout) => {
|
||||
assert.equal(fout.key, 'accounts.maxFreeBank');
|
||||
assert.equal(fout.params.max, 1);
|
||||
return true;
|
||||
});
|
||||
assert.equal(listAccounts().length, 1);
|
||||
});
|
||||
|
||||
it('TELT ALLEEN kind bank, dus een exchange of wallet valt erbuiten', async () => {
|
||||
await createAccount(bank('ING'));
|
||||
await createAccount({ ...bank('Kraken'), kind: 'exchange' });
|
||||
await createAccount({ ...bank('Ledger'), kind: 'wallet' });
|
||||
assert.equal(listAccounts().length, 3);
|
||||
});
|
||||
|
||||
it('laat de tweede bankrekening WEL toe in de betaalde stand', async () => {
|
||||
await createAccount(bank('ING'));
|
||||
stand = { level: 'full', enforced: true, why: 'licensed' };
|
||||
await createAccount(bank('Rabo'));
|
||||
assert.equal(listAccounts().length, 2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('de gratis stand op assets', () => {
|
||||
it('TELT DE BASISVALUTA NIET MEE, anders is de gratis stand onbruikbaar', async () => {
|
||||
await createAsset({ ...EEN, symbol: 'EUR', name: 'Euro', kind: 'fiat', unit: 'EUR', subunit: 'cent', decimals: 2 });
|
||||
const id = await createAsset(EEN);
|
||||
assert.ok(id > 0);
|
||||
assert.equal(listAssets().length, 2);
|
||||
});
|
||||
|
||||
it('telt een munt die er alleen voor de KOERS is niet mee, en een munt in gebruik wel', async () => {
|
||||
const DOLLAR = { ...EEN, symbol: 'USD', name: 'Dollar', kind: 'fiat', unit: 'USD', subunit: 'cent', decimals: 2 };
|
||||
await createAsset(DOLLAR);
|
||||
await createAsset(EEN);
|
||||
assert.equal(listAssets().length, 2, 'bitcoin mag naast een ongebruikte dollar');
|
||||
|
||||
harness.recreate();
|
||||
const usd = await createAsset(DOLLAR);
|
||||
stand = { level: 'full', enforced: true, why: 'licensed' };
|
||||
await createValuation({ assetId: usd, valuedOn: '2026-01-01', accountId: null, balance: 100, fiatRate: 0.9,
|
||||
rateAt: '2026-01-01T00:00:00Z', source: 'manual' });
|
||||
stand = { level: 'free', enforced: true, why: 'none' };
|
||||
await assert.rejects(() => createAsset(EEN), (f) => f.key === 'assets.maxFree',
|
||||
'met een balans in dollars is de dollar het ene asset van de gratis stand');
|
||||
});
|
||||
|
||||
it('laat de EERSTE asset gewoon toe', async () => {
|
||||
const id = await createAsset(EEN);
|
||||
assert.ok(id > 0);
|
||||
assert.equal(listAssets().length, 1);
|
||||
});
|
||||
|
||||
it('weigert de TWEEDE, met een vertaalbare sleutel en niet met een SQL-fout', async () => {
|
||||
await createAsset(EEN);
|
||||
const POND = { ...EEN, symbol: 'GBP', name: 'Pond', kind: 'fiat', unit: 'GBP', subunit: 'pence', decimals: 2 };
|
||||
await assert.rejects(() => createAsset(POND), (fout) => {
|
||||
assert.equal(fout.key, 'assets.maxFree');
|
||||
assert.equal(fout.params.max, 1);
|
||||
assert.match(fout.message, /free version/i);
|
||||
return true;
|
||||
});
|
||||
assert.equal(listAssets().length, 1, 'er mag niets half zijn aangemaakt');
|
||||
});
|
||||
|
||||
it('ALLEEN BITCOIN: een ander asset wordt geweigerd, ook als het het eerste is', async () => {
|
||||
await assert.rejects(() => createAsset(TWEE), (fout) => {
|
||||
assert.equal(fout.key, 'assets.freeOnly');
|
||||
assert.equal(fout.params.list, 'BTC');
|
||||
return true;
|
||||
});
|
||||
assert.equal(listAssets().length, 0, 'er mag niets half zijn aangemaakt');
|
||||
});
|
||||
|
||||
it('laat een munt toe, want die valt onder de telling en niet onder de lijst', async () => {
|
||||
const id = await createAsset({ ...EEN, symbol: 'GBP', name: 'Pond', kind: 'fiat', unit: 'GBP', subunit: 'pence', decimals: 2 });
|
||||
assert.ok(id > 0);
|
||||
});
|
||||
|
||||
it('laat de tweede WEL toe in de betaalde stand', async () => {
|
||||
await createAsset(EEN);
|
||||
stand = { level: 'full', enforced: true, why: 'licensed' };
|
||||
await createAsset(TWEE);
|
||||
assert.equal(listAssets().length, 2);
|
||||
});
|
||||
|
||||
it('NEEMT NIETS AF: wijzigen en verwijderen blijven werken boven de grens', async () => {
|
||||
stand = { level: 'full', enforced: true, why: 'licensed' };
|
||||
const a = await createAsset(EEN);
|
||||
const b = await createAsset(TWEE);
|
||||
|
||||
stand = { level: 'free', enforced: true, why: 'none' };
|
||||
await updateAsset(a, { ...EEN, name: 'Bitcoin hernoemd' });
|
||||
assert.equal(listAssets().find((x) => x.id === a).name, 'Bitcoin hernoemd');
|
||||
await deleteAsset(b);
|
||||
assert.equal(listAssets().length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('de gratis stand op balansen', () => {
|
||||
const balans = (assetId, dag) => ({
|
||||
assetId, valuedOn: dag, accountId: null, balance: 100, fiatRate: 50000,
|
||||
rateAt: `${dag}T00:00:00Z`, source: 'manual',
|
||||
});
|
||||
|
||||
it('laat ÉÉN balans toe en weigert de tweede', async () => {
|
||||
const asset = await createAsset(EEN);
|
||||
await createValuation(balans(asset, '2026-01-01'));
|
||||
await assert.rejects(() => createValuation(balans(asset, '2026-02-01')), (fout) => {
|
||||
assert.equal(fout.key, 'valuations.maxFree');
|
||||
assert.equal(fout.params.max, 1);
|
||||
return true;
|
||||
});
|
||||
assert.equal(listValuations().length, 1);
|
||||
});
|
||||
|
||||
it('laat de tweede WEL toe in de betaalde stand', async () => {
|
||||
const asset = await createAsset(EEN);
|
||||
await createValuation(balans(asset, '2026-01-01'));
|
||||
stand = { level: 'full', enforced: true, why: 'licensed' };
|
||||
await createValuation(balans(asset, '2026-02-01'));
|
||||
assert.equal(listValuations().length, 2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('de features van de gratis stand', () => {
|
||||
it('weigert een lightning-verbinding en een eigen explorer', async () => {
|
||||
await assert.rejects(() => saveConnection({ kind: 'lnd', name: 'Node', url: 'https://x' }),
|
||||
(f) => f.key === 'connections.lightningPaid');
|
||||
await assert.rejects(() => saveConnection({ kind: 'nwc', name: 'Wallet', url: 'nostr+walletconnect://x' }),
|
||||
(f) => f.key === 'connections.lightningPaid');
|
||||
await assert.rejects(() => saveConnection({ kind: 'btc_explorer', name: 'Eigen node', url: 'https://x' }),
|
||||
(f) => f.key === 'connections.ownExplorerPaid');
|
||||
});
|
||||
|
||||
it('LEEST verbindingen gewoon, want de grens zit op opslaan en niet op kijken', async () => {
|
||||
stand = { level: 'full', enforced: true, why: 'licensed' };
|
||||
await saveConnection({ kind: 'btc_explorer', name: 'Eigen node', url: 'https://x' });
|
||||
stand = { level: 'free', enforced: true, why: 'none' };
|
||||
assert.equal(listConnections('btc_explorer').length, 1);
|
||||
});
|
||||
|
||||
it('laat die verbindingen WEL toe in de betaalde stand', async () => {
|
||||
stand = { level: 'full', enforced: true, why: 'licensed' };
|
||||
const id = await saveConnection({ kind: 'lnd', name: 'Node', url: 'https://x' });
|
||||
assert.ok(id);
|
||||
});
|
||||
|
||||
it('weigert een NWC- of LND-bron bij een account, ook via wijzigen, maar laat een bestaande staan', async () => {
|
||||
const accountId = await createAccount({ name: 'Wallet', kind: 'wallet', isOwnCustody: true, scanEnabled: false, taxCategory: null });
|
||||
await assert.rejects(() => createWalletSource({ accountId, kind: 'nwc', value: 'ab'.repeat(32), name: 'W', secret: 'nostr+walletconnect://x' }),
|
||||
(f) => f.key === 'connections.lightningPaid');
|
||||
await assert.rejects(() => createWalletSource({ accountId, kind: 'lnd', value: '', name: 'N', connectionId: 1 }),
|
||||
(f) => f.key === 'connections.lightningPaid');
|
||||
const adres = await createWalletSource({ accountId, kind: 'address', value: 'bc1qtest', name: 'A' });
|
||||
await assert.rejects(() => updateWalletSource(adres, { kind: 'nwc', value: 'ab'.repeat(32), name: 'A', secret: 'nostr+walletconnect://x' }),
|
||||
(f) => f.key === 'connections.lightningPaid');
|
||||
stand = { level: 'full', enforced: true, why: 'licensed' };
|
||||
const bron = await createWalletSource({ accountId, kind: 'nwc', value: 'cd'.repeat(32), name: 'W', secret: 'nostr+walletconnect://y' });
|
||||
stand = { level: 'free', enforced: true, why: 'none' };
|
||||
await updateWalletSource(bron, { kind: 'nwc', value: 'cd'.repeat(32), name: 'Nieuwe naam' });
|
||||
assert.equal(listWalletSources(accountId).find(s => s.id === bron).name, 'Nieuwe naam');
|
||||
});
|
||||
|
||||
it('weigert het wijzigen van de bronkeuze-matrix', async () => {
|
||||
const asset = await createAsset(EEN);
|
||||
await assert.rejects(() => setPriceSourceRank(asset, 'spot', 1),
|
||||
(f) => f.key === 'integrations.matrixPaid');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user