71 lines
2.3 KiB
TypeScript
71 lines
2.3 KiB
TypeScript
|
|
import { describe, expect, it } from 'vitest';
|
||
|
|
|
||
|
|
import { isReminderDue } from '@/lib/services/document-reminders';
|
||
|
|
|
||
|
|
const now = new Date('2026-04-28T12:00:00Z');
|
||
|
|
|
||
|
|
function args(overrides: Partial<Parameters<typeof isReminderDue>[0]> = {}) {
|
||
|
|
return {
|
||
|
|
status: 'sent' as const,
|
||
|
|
documensoId: 'doc-1',
|
||
|
|
remindersDisabled: false,
|
||
|
|
reminderCadenceOverride: null,
|
||
|
|
templateCadenceDays: 7,
|
||
|
|
lastReminderAt: null,
|
||
|
|
now,
|
||
|
|
...overrides,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('isReminderDue', () => {
|
||
|
|
it('returns true when no prior reminder exists and cadence is set', () => {
|
||
|
|
expect(isReminderDue(args())).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('returns false when document is completed', () => {
|
||
|
|
expect(isReminderDue(args({ status: 'completed' }))).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('returns false when document has no Documenso id', () => {
|
||
|
|
expect(isReminderDue(args({ documensoId: null }))).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('returns false when reminders are disabled per-doc', () => {
|
||
|
|
expect(isReminderDue(args({ remindersDisabled: true }))).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('returns false when neither override nor template cadence is set', () => {
|
||
|
|
expect(isReminderDue(args({ templateCadenceDays: null }))).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('respects per-doc override over template default', () => {
|
||
|
|
// 1-day override, last fired 12h ago → not due
|
||
|
|
const lastReminderAt = new Date(now.getTime() - 12 * 60 * 60 * 1000);
|
||
|
|
expect(
|
||
|
|
isReminderDue(args({ templateCadenceDays: 7, reminderCadenceOverride: 1, lastReminderAt })),
|
||
|
|
).toBe(false);
|
||
|
|
|
||
|
|
// 1-day override, last fired 25h ago → due
|
||
|
|
const earlier = new Date(now.getTime() - 25 * 60 * 60 * 1000);
|
||
|
|
expect(
|
||
|
|
isReminderDue(
|
||
|
|
args({
|
||
|
|
templateCadenceDays: 7,
|
||
|
|
reminderCadenceOverride: 1,
|
||
|
|
lastReminderAt: earlier,
|
||
|
|
}),
|
||
|
|
),
|
||
|
|
).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('treats template cadence as the fallback when no override', () => {
|
||
|
|
// 7-day template, last fired 6 days ago → not due
|
||
|
|
const lastReminderAt = new Date(now.getTime() - 6 * 24 * 60 * 60 * 1000);
|
||
|
|
expect(isReminderDue(args({ lastReminderAt }))).toBe(false);
|
||
|
|
|
||
|
|
// 7 days exactly → due
|
||
|
|
const sevenDays = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
||
|
|
expect(isReminderDue(args({ lastReminderAt: sevenDays }))).toBe(true);
|
||
|
|
});
|
||
|
|
});
|