import { beforeEach, describe, expect, it, mock, vi } from 'bun:test'; import { Hono } from 'hono'; mock.module('@/lib/prisma', () => ({ default: { student: { findMany: mock(), count: mock(), }, }, getPrismaClient: mock(), UnitOfWork: class {}, })); import prisma from '@/lib/prisma'; import { studentsRoutes } from '@/modules/students'; const app = new Hono(); app.route('/students', studentsRoutes); const student = { id: 'student-1', groupId: 'group-1', fullName: 'Ana Pérez', email: 'ana@example.com', phone: null, guardianName: 'Luis Pérez', guardianPhone: null, notes: null, createdAt: new Date('2026-08-01T10:00:00.000Z'), updatedAt: new Date('2026-08-01T10:00:00.000Z'), }; describe('students routes', () => { beforeEach(() => { vi.clearAllMocks(); }); it('lists students with pagination', async () => { prisma.student.findMany.mockResolvedValue([student]); prisma.student.count.mockResolvedValue(21); const res = await app.request('/students?page=2&pageSize=10'); expect(res.status).toBe(200); expect(await res.json()).toEqual({ data: [ { ...student, createdAt: student.createdAt.toISOString(), updatedAt: student.updatedAt.toISOString(), }, ], pagination: { page: 2, pageSize: 10, total: 21, totalPages: 3 }, }); expect(prisma.student.findMany).toHaveBeenCalledWith({ skip: 10, take: 10, orderBy: { createdAt: 'desc' }, }); expect(prisma.student.count).toHaveBeenCalledWith(); }); it('uses default pagination', async () => { prisma.student.findMany.mockResolvedValue([]); prisma.student.count.mockResolvedValue(0); const res = await app.request('/students'); expect(res.status).toBe(200); expect(await res.json()).toEqual({ data: [], pagination: { page: 1, pageSize: 10, total: 0, totalPages: 0 }, }); }); it('rejects invalid pagination query parameters', async () => { const res = await app.request('/students?page=0&pageSize=25'); expect(res.status).toBe(400); expect(await res.json()).toMatchObject({ status: 400, title: 'Bad Request' }); }); });