forked from boos/BoosAPI
96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
const cronStopMock = vi.fn();
|
|
const scheduleMock = vi.fn(() => ({
|
|
stop: cronStopMock,
|
|
}));
|
|
const validateMock = vi.fn(() => true);
|
|
const allMock = vi.fn();
|
|
|
|
vi.mock('node-cron', () => ({
|
|
default: {
|
|
schedule: (...args: unknown[]) => scheduleMock(...args),
|
|
validate: (...args: unknown[]) => validateMock(...args),
|
|
},
|
|
}));
|
|
|
|
vi.mock('../db/index.js', () => {
|
|
const queryChain = {
|
|
where: () => queryChain,
|
|
get: () => undefined,
|
|
all: () => [],
|
|
from: () => queryChain,
|
|
innerJoin: () => queryChain,
|
|
};
|
|
|
|
return {
|
|
db: {
|
|
select: () => queryChain,
|
|
},
|
|
schema: {
|
|
settings: { key: 'key' },
|
|
accounts: { checkinEnabled: 'checkinEnabled', status: 'status' },
|
|
sites: { id: 'id' },
|
|
},
|
|
};
|
|
});
|
|
|
|
vi.mock('./checkinService.js', () => ({
|
|
checkinAll: (...args: unknown[]) => allMock(...args),
|
|
}));
|
|
|
|
describe('checkinScheduler', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
cronStopMock.mockReset();
|
|
scheduleMock.mockClear();
|
|
validateMock.mockClear();
|
|
allMock.mockReset();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
const scheduler = await import('./checkinScheduler.js');
|
|
scheduler.__resetCheckinSchedulerForTests();
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it('switches from cron mode to interval mode and back', async () => {
|
|
const setIntervalSpy = vi.spyOn(globalThis, 'setInterval');
|
|
const clearIntervalSpy = vi.spyOn(globalThis, 'clearInterval');
|
|
const scheduler = await import('./checkinScheduler.js');
|
|
|
|
scheduler.updateCheckinSchedule({
|
|
mode: 'cron',
|
|
cronExpr: '0 8 * * *',
|
|
intervalHours: 6,
|
|
});
|
|
expect(scheduleMock).toHaveBeenCalledTimes(1);
|
|
|
|
scheduler.updateCheckinSchedule({
|
|
mode: 'interval',
|
|
intervalHours: 6,
|
|
});
|
|
expect(cronStopMock).toHaveBeenCalledTimes(1);
|
|
expect(setIntervalSpy).toHaveBeenCalledTimes(1);
|
|
|
|
scheduler.updateCheckinSchedule({
|
|
mode: 'cron',
|
|
cronExpr: '5 9 * * *',
|
|
intervalHours: 6,
|
|
});
|
|
expect(clearIntervalSpy).toHaveBeenCalledTimes(1);
|
|
expect(scheduleMock).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it('selects due accounts from the last successful checkin time', async () => {
|
|
const scheduler = await import('./checkinScheduler.js');
|
|
const now = new Date('2026-03-20T12:00:00.000Z');
|
|
|
|
expect(scheduler.selectDueIntervalCheckinAccountIds([
|
|
{ id: 1, lastCheckinAt: null },
|
|
{ id: 2, lastCheckinAt: '2026-03-20T05:59:59.000Z' },
|
|
{ id: 3, lastCheckinAt: '2026-03-20T06:30:00.000Z' },
|
|
], 6, now)).toEqual([1, 2]);
|
|
});
|
|
});
|