Files
gridpilot.gg/apps/website/lib/view-models/WalletTransactionViewModel.test.ts
2025-12-20 00:31:31 +01:00

53 lines
1.7 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { WalletTransactionViewModel } from './WalletTransactionViewModel';
const createTx = (overrides: Partial<any> = {}): any => ({
id: 'tx-1',
type: 'sponsorship',
description: 'Test',
amount: 100,
fee: 10,
netAmount: 90,
date: new Date('2024-01-01T00:00:00Z'),
status: 'completed',
reference: 'ref-1',
...overrides,
});
describe('WalletTransactionViewModel', () => {
it('maps DTO fields into the view model', () => {
const vm = new WalletTransactionViewModel(createTx());
expect(vm.id).toBe('tx-1');
expect(vm.type).toBe('sponsorship');
expect(vm.amount).toBe(100);
expect(vm.netAmount).toBe(90);
expect(vm.status).toBe('completed');
});
it('formats amount with sign and currency symbol', () => {
const incoming = new WalletTransactionViewModel(createTx({ amount: 50 }));
const outgoing = new WalletTransactionViewModel(createTx({ amount: -20 }));
expect(incoming.formattedAmount).toBe('+$50.00');
expect(outgoing.formattedAmount).toBe('$20.00');
});
it('derives amount color and isIncoming from amount sign', () => {
const incoming = new WalletTransactionViewModel(createTx({ amount: 10 }));
const outgoing = new WalletTransactionViewModel(createTx({ amount: -5 }));
expect(incoming.amountColor).toBe('green');
expect(incoming.isIncoming).toBe(true);
expect(outgoing.amountColor).toBe('red');
expect(outgoing.isIncoming).toBe(false);
});
it('derives typeDisplay and formattedDate', () => {
const vm = new WalletTransactionViewModel(createTx({ type: 'membership' as any }));
expect(vm.typeDisplay).toBe('Membership');
expect(typeof vm.formattedDate).toBe('string');
});
});