PPPAIMT-Crest/backend/test/reminders.test.js

81 lines
2.6 KiB
JavaScript

import { randomUUID } from 'node:crypto';
import { afterEach, describe, expect, it } from 'vitest';
import { db } from '../src/db/knex.js';
import { runReminders, selectDrafts, selectSurveys } from '../src/services/reminders.js';
import { truncateTables } from './truncate.js';
const day = 24 * 60 * 60 * 1000;
/**
* @param {number} days
* @param {Date} [from]
*/
function daysAgo(days, from = new Date()) {
return new Date(from.getTime() - days * day);
}
describe('reminder selection', () => {
const now = new Date('2026-09-30T10:00:00.000Z');
it('selects a draft untouched for 3 days and skips recent, maxed, and rejected rows', () => {
const applications = [
{ id: 1, status: 'DRAFT', updated_at: daysAgo(3, now) },
{ id: 2, status: 'DRAFT', updated_at: daysAgo(4, now) },
{ id: 3, status: 'DRAFT', updated_at: daysAgo(10, now) },
{ id: 4, status: 'REJECTED', updated_at: daysAgo(10, now) },
{ id: 5, status: 'SUBMITTED', updated_at: daysAgo(10, now) },
];
const reminders = new Map([
[2, [{ status: 'logged', created_at: daysAgo(1, now) }]],
[
3,
[
{ status: 'logged', created_at: daysAgo(9, now) },
{ status: 'logged', created_at: daysAgo(6, now) },
{ status: 'logged', created_at: daysAgo(3, now) },
],
],
]);
const selected = selectDrafts(applications, reminders, now, 3).map((row) => row.id);
expect(selected).toEqual([1]);
});
it('selects an unfinished approved survey after 5 days and skips a completed one', () => {
const applications = [
{ id: 1, status: 'APPROVED', decided_at: daysAgo(5, now) },
{ id: 2, status: 'APPROVED', decided_at: daysAgo(8, now) },
];
const selected = selectSurveys(applications, new Set([2]), new Map(), now, 5).map(
(row) => row.id,
);
expect(selected).toEqual([1]);
});
});
describe('reminder delivery', () => {
afterEach(async () => {
await truncateTables();
});
it('records one reminder and does not send it again the same day', async () => {
const [id] = await db('applications').insert({
public_id: randomUUID(),
email: 'draft@example.com',
status: 'DRAFT',
full_name: 'Asha Rao',
version: 1,
});
await db('applications')
.where({ id })
.update({ updated_at: daysAgo(4) });
await runReminders();
await runReminders();
const emails = await db('email_log').where({ application_id: id, template: 'reminder_draft' });
expect(emails).toHaveLength(1);
expect(emails[0].reminder_count).toBe(1);
expect(emails[0].status).not.toBe('failed');
});
});