import { BadRequestException } from '@nestjs/common'; import { DepositsService } from './deposits.service'; import { Deposit } from '../entities/deposit.entity'; function serviceWith(deposit?: Partial) { const record = deposit ? ({ id: 1, studentId: 2, ...deposit } as Deposit) : null; const repo = { findOne: jest.fn(async (options: any) => options?.where?.studentId ? record : record), create: jest.fn((value) => value), save: jest.fn(async (value) => value), }; const installmentRepo = { create: jest.fn((value) => value), save: jest.fn(async (value) => value), }; const studentRepo = { findOne: jest.fn().mockResolvedValue({ id: 2 }) }; return { service: new DepositsService(repo as any, installmentRepo as any, studentRepo as any), repo, installmentRepo }; } describe('DepositsService boundaries', () => { it('rejects an installment amount that rounds to zero', async () => { const { service, installmentRepo } = serviceWith({ amount: 500, status: 'paid' }); await expect(service.addInstallment(1, 0.004, '2026-08-01')).rejects.toBeInstanceOf(BadRequestException); expect(installmentRepo.save).not.toHaveBeenCalled(); }); it('rejects a repeated full refund', async () => { const { service, repo } = serviceWith({ amount: 0, status: 'refunded' }); await expect(service.refund(1, { refundDate: '2026-07-14' })).rejects.toBeInstanceOf(BadRequestException); expect(repo.save).not.toHaveBeenCalled(); }); it('rounds cumulative collections and clears stale refund audit fields', async () => { const { service } = serviceWith({ amount: 10.01, status: 'refunded', refundDate: '2026-07-01', refundAmount: 5, refundedBy: 9, refundedAt: new Date(), }); const result = await service.create({ studentId: 2, amount: 0.02, paidDate: '2026-07-14' }, 7); expect(result).toMatchObject({ amount: 10.03, status: 'paid', recordedBy: 7 }); expect(result.refundDate).toBeNull(); expect(result.refundAmount).toBeNull(); expect(result.refundedBy).toBeNull(); expect(result.refundedAt).toBeNull(); }); });