118 lines
3.2 KiB
JavaScript
118 lines
3.2 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { classifyAllMovements } from '../src/classifier.js';
|
|
import { normalizeLedger } from '../src/domain.js';
|
|
import { buildMoneyGraph, originTree } from '../src/moneyGraph.js';
|
|
|
|
const ledgerFixture = normalizeLedger({
|
|
entities: [
|
|
{ id: 'darwin', name: 'Darwin Bruna', kind: 'person' },
|
|
{ id: 'muralla', name: 'Muralla SpA', kind: 'company' },
|
|
],
|
|
accounts: [
|
|
{
|
|
id: 'darwin-cc',
|
|
ownerEntityId: 'darwin',
|
|
institution: 'Banco de Chile',
|
|
instrument: 'checking_account',
|
|
currency: 'CLP',
|
|
},
|
|
{
|
|
id: 'darwin-visa',
|
|
ownerEntityId: 'darwin',
|
|
institution: 'Visa',
|
|
instrument: 'credit_card',
|
|
currency: 'CLP',
|
|
},
|
|
],
|
|
movements: [
|
|
{
|
|
id: 'income',
|
|
date: '2025-12-01',
|
|
accountId: 'darwin-cc',
|
|
direction: 'in',
|
|
amount: { currency: 'CLP', value: 200000 },
|
|
description: 'Ingreso puro',
|
|
economicType: 'pure_income',
|
|
},
|
|
{
|
|
id: 'pay-card',
|
|
date: '2026-01-15',
|
|
accountId: 'darwin-cc',
|
|
cardAccountId: 'darwin-visa',
|
|
direction: 'out',
|
|
amount: { currency: 'CLP', value: 150000 },
|
|
description: 'PAGO TARJETA VISA',
|
|
},
|
|
{
|
|
id: 'card-charge',
|
|
date: '2025-12-30',
|
|
accountId: 'darwin-visa',
|
|
direction: 'out',
|
|
amount: { currency: 'CLP', value: 126616 },
|
|
description: 'CAFE CULTURA BLACK SPA',
|
|
},
|
|
],
|
|
documents: [
|
|
{
|
|
id: 'black-spa-10804',
|
|
kind: 'dte_invoice',
|
|
issuerName: 'BLACK SPA',
|
|
receiverEntityId: 'muralla',
|
|
amount: { currency: 'CLP', value: 126616 },
|
|
},
|
|
],
|
|
events: [
|
|
{
|
|
id: 'black-spa-10804',
|
|
kind: 'real_expense',
|
|
entityId: 'muralla',
|
|
amount: { currency: 'CLP', value: 126616 },
|
|
description: 'Gasto Muralla BLACK SPA',
|
|
},
|
|
],
|
|
links: [
|
|
{
|
|
from: 'mov:card-charge',
|
|
to: 'event:black-spa-10804',
|
|
type: 'finances_event',
|
|
amount: { currency: 'CLP', value: 126616 },
|
|
method: 'manual',
|
|
},
|
|
{
|
|
from: 'doc:black-spa-10804',
|
|
to: 'event:black-spa-10804',
|
|
type: 'documents_event',
|
|
amount: { currency: 'CLP', value: 126616 },
|
|
method: 'exact',
|
|
},
|
|
],
|
|
});
|
|
|
|
test('builds origin tree from real expense to card, card payment and pure income', () => {
|
|
const ledger = classifyAllMovements(ledgerFixture);
|
|
const graph = buildMoneyGraph(ledger);
|
|
const tree = originTree(graph, 'event:black-spa-10804');
|
|
const json = JSON.stringify(tree);
|
|
|
|
assert.match(json, /mov:card-charge/);
|
|
assert.match(json, /mov:pay-card/);
|
|
assert.match(json, /mov:income/);
|
|
assert.match(json, /settles_card_charge/);
|
|
assert.match(json, /funds/);
|
|
});
|
|
|
|
test('classifies untyped credit-card outflow as card charge', () => {
|
|
const ledger = classifyAllMovements(ledgerFixture);
|
|
const charge = ledger.movements.find((movement) => movement.id === 'mov:card-charge');
|
|
|
|
assert.equal(charge.economicType, 'card_charge');
|
|
});
|
|
|
|
test('classifies card payment by description', () => {
|
|
const ledger = classifyAllMovements(ledgerFixture);
|
|
const payment = ledger.movements.find((movement) => movement.id === 'mov:pay-card');
|
|
|
|
assert.equal(payment.economicType, 'card_payment');
|
|
});
|