You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sims-hq/apps/hq/test/reminders.test.ts

49 lines
2.5 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import { openDb } from '../src/db'
import { reminderEmail } from '../src/reminder-templates'
import {
upsertReminder, listQueue, dismissReminder, setReminderStatus, getReminder,
getNumberSetting, setSetting,
} from '../src/repos-reminders'
describe('reminder templates', () => {
it('renders an overdue dunning email with the amount and a polite tone', () => {
const mail = reminderEmail('invoice_overdue', {
clientName: 'Malabar Stores', companyName: 'Tecnostac',
docNo: 'INV/26-27-0007', amountPaise: 11_800_00, daysOverdue: 12,
})
expect(mail.subject).toContain('INV/26-27-0007')
expect(mail.bodyText).toContain('₹11,800.00')
expect(mail.bodyText).toContain('12 day')
})
})
describe('reminder repo', () => {
it('is idempotent on (rule_kind, subject_id, due_period)', () => {
const db = openDb(':memory:')
const a = upsertReminder(db, { ruleKind: 'invoice_overdue', subjectId: 'inv1', duePeriod: '2026-07', clientId: 'c1', docId: 'inv1', now: '2026-07-10T00:00:00Z' })
expect(a.created).toBe(true)
const b = upsertReminder(db, { ruleKind: 'invoice_overdue', subjectId: 'inv1', duePeriod: '2026-07', clientId: 'c1', docId: 'inv1', now: '2026-07-10T06:00:00Z' })
expect(b.created).toBe(false)
expect(b.id).toBe(a.id) // same row returned, not a duplicate
expect(listQueue(db)).toHaveLength(1)
expect(db.prepare(`SELECT COUNT(*) AS n FROM audit_log WHERE entity='reminder'`).get()).toMatchObject({ n: 1 })
})
it('transitions and dismisses, refusing to dismiss a sent reminder', () => {
const db = openDb(':memory:')
const { id } = upsertReminder(db, { ruleKind: 'follow_up', subjectId: 'i1', duePeriod: '2026-07-08', clientId: 'c1', now: '2026-07-10T00:00:00Z' })
const dismissed = dismissReminder(db, 'u1', id)
expect(dismissed.status).toBe('dismissed')
const { id: id2 } = upsertReminder(db, { ruleKind: 'invoice_overdue', subjectId: 'inv2', duePeriod: '2026-07', clientId: 'c1', docId: 'inv2', now: '2026-07-10T00:00:00Z' })
setReminderStatus(db, 'u1', id2, 'sent', { sentAt: '2026-07-10T09:00:00Z' })
expect(getReminder(db, id2)!.status).toBe('sent')
expect(() => dismissReminder(db, 'u1', id2)).toThrow(/sent/i)
})
it('reads number settings with a fallback', () => {
const db = openDb(':memory:')
expect(getNumberSetting(db, 'reminders.overdue_days', 7)).toBe(7)
setSetting(db, 'u1', 'reminders.overdue_days', '10')
expect(getNumberSetting(db, 'reminders.overdue_days', 7)).toBe(10)
})
})