xpeditis2.0/apps/backend/src/domain/value-objects/money.vo.spec.ts
2025-10-27 20:54:01 +01:00

134 lines
4.1 KiB
TypeScript

/**
* Money Value Object Unit Tests
*/
import { Money } from './money.vo';
describe('Money Value Object', () => {
describe('create', () => {
it('should create money with valid amount and currency', () => {
const money = Money.create(100, 'USD');
expect(money.getAmount()).toBe(100);
expect(money.getCurrency()).toBe('USD');
});
it('should round to 2 decimal places', () => {
const money = Money.create(100.999, 'USD');
expect(money.getAmount()).toBe(101);
});
it('should throw error for negative amount', () => {
expect(() => Money.create(-100, 'USD')).toThrow('Amount cannot be negative');
});
it('should throw error for invalid currency', () => {
expect(() => Money.create(100, 'XXX')).toThrow('Invalid currency code');
});
it('should normalize currency to uppercase', () => {
const money = Money.create(100, 'usd');
expect(money.getCurrency()).toBe('USD');
});
});
describe('zero', () => {
it('should create zero amount', () => {
const money = Money.zero('USD');
expect(money.getAmount()).toBe(0);
expect(money.isZero()).toBe(true);
});
});
describe('add', () => {
it('should add two money amounts', () => {
const money1 = Money.create(100, 'USD');
const money2 = Money.create(50, 'USD');
const result = money1.add(money2);
expect(result.getAmount()).toBe(150);
});
it('should throw error for currency mismatch', () => {
const money1 = Money.create(100, 'USD');
const money2 = Money.create(50, 'EUR');
expect(() => money1.add(money2)).toThrow('Currency mismatch');
});
});
describe('subtract', () => {
it('should subtract two money amounts', () => {
const money1 = Money.create(100, 'USD');
const money2 = Money.create(30, 'USD');
const result = money1.subtract(money2);
expect(result.getAmount()).toBe(70);
});
it('should throw error for negative result', () => {
const money1 = Money.create(50, 'USD');
const money2 = Money.create(100, 'USD');
expect(() => money1.subtract(money2)).toThrow('negative amount');
});
});
describe('multiply', () => {
it('should multiply money amount', () => {
const money = Money.create(100, 'USD');
const result = money.multiply(2);
expect(result.getAmount()).toBe(200);
});
it('should throw error for negative multiplier', () => {
const money = Money.create(100, 'USD');
expect(() => money.multiply(-2)).toThrow('Multiplier cannot be negative');
});
});
describe('divide', () => {
it('should divide money amount', () => {
const money = Money.create(100, 'USD');
const result = money.divide(2);
expect(result.getAmount()).toBe(50);
});
it('should throw error for zero divisor', () => {
const money = Money.create(100, 'USD');
expect(() => money.divide(0)).toThrow('Divisor must be positive');
});
});
describe('comparisons', () => {
it('should compare greater than', () => {
const money1 = Money.create(100, 'USD');
const money2 = Money.create(50, 'USD');
expect(money1.isGreaterThan(money2)).toBe(true);
expect(money2.isGreaterThan(money1)).toBe(false);
});
it('should compare less than', () => {
const money1 = Money.create(50, 'USD');
const money2 = Money.create(100, 'USD');
expect(money1.isLessThan(money2)).toBe(true);
expect(money2.isLessThan(money1)).toBe(false);
});
it('should compare equality', () => {
const money1 = Money.create(100, 'USD');
const money2 = Money.create(100, 'USD');
const money3 = Money.create(50, 'USD');
expect(money1.isEqualTo(money2)).toBe(true);
expect(money1.isEqualTo(money3)).toBe(false);
});
});
describe('format', () => {
it('should format USD with $ symbol', () => {
const money = Money.create(100.5, 'USD');
expect(money.format()).toBe('$100.50');
});
it('should format EUR with € symbol', () => {
const money = Money.create(100.5, 'EUR');
expect(money.format()).toBe('€100.50');
});
});
});