import { Hono } from 'hono'; import { beforeEach, describe, expect, it, vi } from 'vitest'; vi.mock('@/lib/prisma', () => ({ default: { payment: { findMany: vi.fn(), count: vi.fn(), }, }, getPrismaClient: vi.fn(), UnitOfWork: class {}, })); import prisma from '@/lib/prisma'; import { paymentsRoutes } from '@/modules/payments'; const app = new Hono(); app.route('/payments', paymentsRoutes); const payment = { id: 'payment-1', groupId: 'group-1', studentId: 'student-1', amount: { toString: () => '150.50' } as { toString(): string }, currency: 'MXN', status: 'pending', dueDate: new Date('2026-09-01T10:00:00.000Z'), paidAt: null, createdAt: new Date('2026-08-01T10:00:00.000Z'), updatedAt: new Date('2026-08-01T10:00:00.000Z'), }; describe('payments routes', () => { beforeEach(() => { vi.clearAllMocks(); }); it('lists payments with pagination and converts Decimal amounts', async () => { vi.mocked(prisma.payment.findMany).mockResolvedValue([payment]); vi.mocked(prisma.payment.count).mockResolvedValue(1); const res = await app.request('/payments'); expect(res.status).toBe(200); expect(await res.json()).toEqual({ data: [ { id: 'payment-1', groupId: 'group-1', studentId: 'student-1', amount: 150.5, currency: 'MXN', status: 'pending', dueDate: payment.dueDate.toISOString(), paidAt: null, createdAt: payment.createdAt.toISOString(), updatedAt: payment.updatedAt.toISOString(), }, ], pagination: { page: 1, pageSize: 10, total: 1, totalPages: 1 }, }); expect(prisma.payment.findMany).toHaveBeenCalledWith({ skip: 0, take: 10, orderBy: { createdAt: 'desc' }, }); }); it('rejects invalid pagination query parameters', async () => { const res = await app.request('/payments?pageSize=101'); expect(res.status).toBe(400); }); });