114 lines
3.2 KiB
TypeScript
114 lines
3.2 KiB
TypeScript
import { beforeEach, describe, expect, it, mock, vi } from 'bun:test';
|
|
import { Hono } from 'hono';
|
|
|
|
const db = {
|
|
group: {
|
|
findMany: mock(),
|
|
},
|
|
attendee: {
|
|
findMany: mock(),
|
|
},
|
|
classSession: {
|
|
findMany: mock(),
|
|
},
|
|
attendance: {
|
|
findMany: mock(),
|
|
},
|
|
};
|
|
|
|
mock.module('@/lib/prisma', () => ({
|
|
default: db,
|
|
getPrismaClient: mock(),
|
|
UnitOfWork: class {
|
|
executeResult = mock(async (cb: (tx: unknown) => Promise<unknown>) => cb(db));
|
|
execute = mock(async (cb: (tx: unknown) => Promise<unknown>) => cb(db));
|
|
},
|
|
}));
|
|
|
|
import { groupsRiskOverviewRoute } from '@/modules/analytics';
|
|
|
|
const userId = 'user-1';
|
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
const now = Date.now();
|
|
const at = (offsetDays: number) => new Date(now - offsetDays * DAY_MS);
|
|
|
|
function makeApp(userValue: unknown) {
|
|
const app = new Hono();
|
|
app.use('*', async (c, next) => {
|
|
c.set('user', userValue as never);
|
|
await next();
|
|
});
|
|
app.route('/groups-risk', groupsRiskOverviewRoute);
|
|
return app;
|
|
}
|
|
|
|
describe('GET /groups-risk/overview', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('devuelve items vacíos si el usuario no tiene grupos', async () => {
|
|
prismaFetchGroupFindMany([]);
|
|
prismaFetchAttendeeFindMany([]);
|
|
prismaFetchClassSessionFindMany([]);
|
|
prismaFetchAttendanceFindMany([]);
|
|
|
|
const res = await makeApp({ id: userId }).request('/groups-risk/overview');
|
|
|
|
expect(res.status).toBe(200);
|
|
expect(await res.json()).toEqual({ items: [] });
|
|
});
|
|
|
|
it('marca HIGH a un grupo con un alumno con 3 ausencias consecutivas', async () => {
|
|
prismaFetchGroupFindMany([
|
|
{ id: 'group-1', name: 'Funcional' },
|
|
{ id: 'group-2', name: 'Yoga' },
|
|
]);
|
|
prismaFetchAttendeeFindMany([
|
|
{ id: 'a-1', groupId: 'group-1' },
|
|
{ id: 'a-2', groupId: 'group-2' },
|
|
]);
|
|
prismaFetchClassSessionFindMany([
|
|
{ id: 's1', groupId: 'group-1', startsAt: at(-1) },
|
|
{ id: 's2', groupId: 'group-1', startsAt: at(-2) },
|
|
{ id: 's3', groupId: 'group-1', startsAt: at(-3) },
|
|
{ id: 's4', groupId: 'group-2', startsAt: at(-1) },
|
|
]);
|
|
prismaFetchAttendanceFindMany([
|
|
attendance('a-1', 'ABSENT', at(-1)),
|
|
attendance('a-1', 'ABSENT', at(-2)),
|
|
attendance('a-1', 'ABSENT', at(-3)),
|
|
attendance('a-2', 'PRESENT', at(-1)),
|
|
]);
|
|
|
|
const res = await makeApp({ id: userId }).request('/groups-risk/overview');
|
|
|
|
expect(res.status).toBe(200);
|
|
expect(await res.json()).toEqual({
|
|
items: [
|
|
{ groupId: 'group-1', groupName: 'Funcional', riskLevel: 'HIGH' },
|
|
{ groupId: 'group-2', groupName: 'Yoga', riskLevel: 'NONE' },
|
|
],
|
|
});
|
|
});
|
|
});
|
|
|
|
function prismaFetchGroupFindMany(rows: unknown[]) {
|
|
db.group.findMany.mockResolvedValue(rows);
|
|
}
|
|
|
|
function prismaFetchAttendeeFindMany(rows: unknown[]) {
|
|
db.attendee.findMany.mockResolvedValue(rows);
|
|
}
|
|
|
|
function prismaFetchClassSessionFindMany(rows: unknown[]) {
|
|
db.classSession.findMany.mockResolvedValue(rows);
|
|
}
|
|
|
|
function prismaFetchAttendanceFindMany(rows: unknown[]) {
|
|
db.attendance.findMany.mockResolvedValue(rows);
|
|
}
|
|
|
|
function attendance(attendeeId: string, status: string, startsAt: string) {
|
|
return { attendeeId, status, classSession: { startsAt } };
|
|
} |