import 'reflect-metadata'; import { validate } from 'class-validator'; import { CreateScheduleDto, UpdateScheduleDto } from './schedule.dto'; const createSchedule = (notes: string) => Object.assign(new CreateScheduleDto(), { classId: 1, classroomId: 2, weekDay: 1, startTime: '09:00', endTime: '10:00', startDate: '2026-07-01', endDate: '2026-07-31', subject: '语文', notes, }); describe('schedule attendance window validation', () => { it('accepts a configurable number of minutes before class', async () => { const dto = createSchedule(''); dto.attendanceAdvanceMinutes = 45; const errors = await validate(dto); expect(errors.some((error) => error.property === 'attendanceAdvanceMinutes')).toBe(false); }); it('rejects values outside 0 to 1440 minutes', async () => { const dto = Object.assign(new UpdateScheduleDto(), { attendanceAdvanceMinutes: 1441 }); const errors = await validate(dto); expect(errors.some((error) => error.property === 'attendanceAdvanceMinutes')).toBe(true); }); }); describe('schedule notes validation', () => { it('rejects notes longer than 500 characters when creating', async () => { const errors = await validate(createSchedule('a'.repeat(501))); expect(errors.some((error) => error.property === 'notes')).toBe(true); }); it('rejects notes longer than 500 characters when updating', async () => { const dto = Object.assign(new UpdateScheduleDto(), { notes: 'a'.repeat(501) }); const errors = await validate(dto); expect(errors.some((error) => error.property === 'notes')).toBe(true); }); }); it('removes the retired departmentId field from create requests', async () => { const dto = Object.assign(new CreateScheduleDto(), { classId: 1, classroomId: 2, weekDay: 1, startTime: '09:00', endTime: '10:00', startDate: '2026-07-01', endDate: '2026-07-31', subject: '语文', departmentId: 99, }); await validate(dto, { whitelist: true }); expect(dto).not.toHaveProperty('departmentId'); });