test: harden business boundary conditions

This commit is contained in:
2026-07-15 00:03:55 +08:00
parent 17a5046ea0
commit b1f35f9d1a
65 changed files with 2311 additions and 293 deletions

View File

@@ -593,3 +593,38 @@ describe('AttendanceService \u2014 DingTalk course attendance', () => {
expect(result.source).toBe('manual');
});
});
describe('AttendanceService — attendance window boundaries', () => {
it('crosses calendar boundaries only when the window requires it', () => {
const { service } = createService();
expect(service.getLessonAttendanceImportDateRange(
{ startTime: '00:30', endTime: '01:30', attendanceAdvanceMinutes: 30 }, '2026-07-13',
)).toEqual({ startDate: '2026-07-13', endDate: '2026-07-13' });
expect(service.getLessonAttendanceImportDateRange(
{ startTime: '00:30', endTime: '01:30', attendanceAdvanceMinutes: 31 }, '2026-07-13',
)).toEqual({ startDate: '2026-07-12', endDate: '2026-07-13' });
expect(service.getLessonAttendanceImportDateRange(
{ startTime: '22:00', endTime: '01:00', attendanceAdvanceMinutes: 30 }, '2026-07-13',
)).toEqual({ startDate: '2026-07-13', endDate: '2026-07-14' });
});
it('uses Asia/Shanghai time when deciding whether todays lesson has started', async () => {
const originalTz = process.env.TZ;
process.env.TZ = 'UTC';
jest.useFakeTimers().setSystemTime(new Date('2026-07-13T01:00:00.000Z'));
try {
const { service, scheduleRepo, sessionRepo, attendanceRepo } = createService();
scheduleRepo.findOne.mockResolvedValue({
...endedSchedule, weekDay: 1, startTime: '08:30', endTime: '10:00',
startDate: '2026-07-13', endDate: '2026-07-13',
});
sessionRepo.findOne.mockResolvedValue({ id: 90, status: 'completed' });
attendanceRepo.find.mockResolvedValue([]);
await expect(service.createLessonAttendanceFromDingTalk(4, '2026-07-13', 21))
.resolves.toMatchObject({ records: [] });
} finally {
jest.useRealTimers();
process.env.TZ = originalTz;
}
});
});