Files
backend/src/modules/investments/operations/infrastructure/brokerage-operation.mapper.spec.ts
T
codex-bot 809936e62d
Backend verify / commits (push) Skipped
Backend verify / security (push) Successful in 1m32s
Backend verify / verify (push) Failing after 9m25s
refactor!: support RUB only (WealthLedger/main#55) (#204)
BREAKING CHANGE: per-currency API fields replaced with single RUB Money.
2026-11-11 10:07:11 +03:00

94 lines
2.6 KiB
TypeScript

import {
mapBrokerageOperation,
operationCategory,
} from './brokerage-operation.mapper';
describe('mapBrokerageOperation', () => {
it('keeps subsecond timestamps at persisted millisecond precision and the standalone epoch default', () => {
expect(
mapBrokerageOperation({
date: { seconds: '1768000000', nanos: 600999999 },
}).occurredAt,
).toBe('2026-01-09T23:06:40.600Z');
expect(mapBrokerageOperation({}).occurredAt).toBe(
'1970-01-01T00:00:00.000Z',
);
});
it.each([
['OPERATION_TYPE_COUPON', 'income'],
['OPERATION_TYPE_DIVIDEND', 'income'],
['OPERATION_TYPE_TAX', 'tax'],
['OPERATION_TYPE_BROKER_FEE', 'fee'],
['NEW_TYPE', 'other'],
])('maps %s to %s', (type, category) => {
expect(operationCategory(type)).toBe(category);
});
it('keeps a trade and its commission in one exact-money entry', () => {
expect(
mapBrokerageOperation({
id: 'trade',
date: { seconds: '1' },
type: 'OPERATION_TYPE_BUY',
payment: { currency: 'rub', units: '-1', nano: '-500000000' },
commission: { currency: 'RUB', nano: '-5000000' },
}),
).toMatchObject({
id: 'trade',
category: 'trade',
payment: { currency: 'RUB', value: '-1.5' },
commission: { currency: 'RUB', value: '-0.005' },
});
});
it('does not invent payment for an instrument-only movement', () => {
expect(
mapBrokerageOperation({
id: 'transfer',
date: { seconds: '1' },
type: 'OPERATION_TYPE_INPUT_SECURITIES',
quantity: '3',
}),
).toMatchObject({
category: 'transfer',
quantity: '3',
payment: null,
});
});
it('filters non-RUB money out of every money field at ingest', () => {
expect(
mapBrokerageOperation({
id: 'usd',
date: { seconds: '1' },
type: 'OPERATION_TYPE_DIVIDEND',
payment: { currency: 'usd', units: '21' },
price: { currency: 'USD', units: '10' },
commission: { currency: 'EUR', units: '1' },
}),
).toMatchObject({
id: 'usd',
payment: null,
price: null,
commission: null,
});
});
});
describe('executed trade quantity', () => {
it('uses the executed part, and does not invent execution quantity when absent', () => {
expect(
mapBrokerageOperation({
type: 'OPERATION_TYPE_BUY',
quantity: '100',
quantityDone: '7',
}).quantity,
).toBe('7');
expect(
mapBrokerageOperation({ type: 'OPERATION_TYPE_BUY', quantity: '100' })
.quantity,
).toBeNull();
});
});