import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { sendEventRegistrationEmail, sendEventCancellationEmail, sendWaitlistNotificationEmail, sendSeriesPassConfirmation, sendWelcomeEmail, } from '../../../server/utils/resend.js' // Hoisted spy so the resend mock and the assertions share one reference. const { sendSpy } = vi.hoisted(() => ({ sendSpy: vi.fn() })) vi.mock('resend', () => ({ Resend: class { constructor() { this.emails = { send: sendSpy } } }, })) const eventData = { title: 'Co-op Basics', startDate: '2026-06-01T17:00:00.000Z', endDate: '2026-06-01T18:00:00.000Z', location: 'Online', slug: 'co-op-basics', } const registration = { email: 'reg@example.com', name: 'Reg', ticketType: 'member', amountPaid: 0 } const seriesPassOptions = { to: 'pass@example.com', name: 'Pass Holder', series: { title: 'Workshop Series' }, ticket: { type: 'member', price: 0, currency: 'CAD', isFree: true }, events: [eventData], paymentId: null, } const member = { email: 'welcome@example.com', name: 'New Member', circle: 'Community' } describe('resend email wrappers — ALLOW_DEV_TEST_ENDPOINTS gate', () => { beforeEach(() => { sendSpy.mockReset() sendSpy.mockResolvedValue({ data: { id: 'email_1' }, error: null }) }) afterEach(() => { delete process.env.ALLOW_DEV_TEST_ENDPOINTS }) describe('when ALLOW_DEV_TEST_ENDPOINTS=true', () => { beforeEach(() => { process.env.ALLOW_DEV_TEST_ENDPOINTS = 'true' }) const cases = [ ['registration', () => sendEventRegistrationEmail(registration, eventData)], ['cancellation', () => sendEventCancellationEmail(registration, eventData)], ['waitlist', () => sendWaitlistNotificationEmail(registration, eventData)], ['series pass', () => sendSeriesPassConfirmation(seriesPassOptions)], ['welcome', () => sendWelcomeEmail(member)], ] it.each(cases)('skips the live send for %s', async (_label, call) => { const result = await call() expect(result).toEqual({ success: true, skipped: true }) expect(sendSpy).not.toHaveBeenCalled() }) }) describe('when the gate is off', () => { it('dispatches a live send and returns success', async () => { const result = await sendWelcomeEmail(member) expect(sendSpy).toHaveBeenCalledTimes(1) expect(result).toEqual({ success: true, data: { id: 'email_1' } }) }) it('includes the monthly-onboarding Slack-timing line in the welcome email', async () => { await sendWelcomeEmail(member) const sent = sendSpy.mock.calls[0][0] expect(sent.text).toContain('monthly onboarding waves') }) }) })