import { describe, expect, it, vi, beforeEach } from 'vitest';
const sendMock = vi.fn(async (_opts) => { });
const configHolder = { current: { platform: { email: { send: sendMock } } } };
vi.mock('../../config/runtime.js', () => ({
    getActuateConfig: () => configHolder.current,
}));
import { buildNotificationEmail, buildAutoresponderEmail, sendFormNotifications, } from '../../forms/notify.js';
function field(overrides) {
    return {
        id: 'f',
        label: 'Label',
        key: 'key',
        type: 'text',
        required: false,
        sortOrder: 0,
        ...overrides,
    };
}
function ctx(overrides = {}) {
    return {
        formId: 'form_1',
        formName: 'Contact Us',
        entryNumber: 42,
        submittedAt: '2026-01-01T00:00:00.000Z',
        fields: [
            field({ key: 'name', label: 'Name', type: 'text' }),
            field({ key: 'email', label: 'Email', type: 'email' }),
            field({ key: 'message', label: 'Message', type: 'textarea' }),
        ],
        data: { name: 'Ada Lovelace', email: 'ada@calc.io', message: 'Hello there' },
        senderName: 'Ada Lovelace',
        senderEmail: 'ada@calc.io',
        ...overrides,
    };
}
const baseSettings = { enabled: true, recipients: ['ops@example.com'] };
describe('buildNotificationEmail', () => {
    it('renders subject/message templates with placeholders and a fields table', () => {
        const email = buildNotificationEmail({
            ...baseSettings,
            subjectTemplate: 'New {{formName}} entry {{entryNumber}}',
            messageTemplate: 'From {{name}} <{{email}}>',
        }, ctx());
        expect(email.subject).toBe('New Contact Us entry #00042');
        expect(email.html).toContain('From Ada Lovelace');
        expect(email.html).toContain('Ada Lovelace');
        expect(email.html).toContain('Hello there');
        expect(email.text).toContain('Name: Ada Lovelace');
    });
    it('escapes HTML in field values to prevent injection', () => {
        const email = buildNotificationEmail(baseSettings, ctx({ data: { name: '<script>alert(1)</script>', email: 'x@y.z', message: 'hi' } }));
        expect(email.html).not.toContain('<script>');
        expect(email.html).toContain('&lt;script&gt;');
    });
    it('hides sensitive fields when excludeSensitiveFields is set', () => {
        const email = buildNotificationEmail({ ...baseSettings, excludeSensitiveFields: true }, ctx({
            fields: [field({ key: 'ssn', label: 'SSN', type: 'text', piiClassification: 'high' })],
            data: { ssn: '123-45-6789' },
        }));
        expect(email.html).not.toContain('123-45-6789');
        expect(email.html).toContain('[hidden]');
    });
    it('omits the fields table when includeFields is false', () => {
        const email = buildNotificationEmail({ ...baseSettings, includeFields: false }, ctx());
        expect(email.html).not.toContain('Hello there');
    });
});
describe('buildAutoresponderEmail', () => {
    it('uses a default thank-you body and personalizes the name', () => {
        const auto = buildAutoresponderEmail({ ...baseSettings, autoresponderEnabled: true }, ctx());
        expect(auto.subject).toBe('We received your submission');
        expect(auto.html).toContain('Ada Lovelace');
    });
});
describe('sendFormNotifications', () => {
    beforeEach(() => {
        sendMock.mockClear();
        configHolder.current = { platform: { email: { send: sendMock } } };
    });
    it('sends one email per recipient with a resolved reply-to', async () => {
        const result = await sendFormNotifications({ ...baseSettings, recipients: ['a@x.com', 'b@x.com'], replyToFieldKey: 'email' }, ctx());
        expect(result.notified).toBe(2);
        expect(sendMock).toHaveBeenCalledTimes(2);
        expect(sendMock.mock.calls[0][0]).toMatchObject({ to: 'a@x.com', replyTo: 'ada@calc.io' });
    });
    it('skips invalid recipient addresses', async () => {
        const result = await sendFormNotifications({ ...baseSettings, recipients: ['valid@x.com', 'not-an-email'] }, ctx());
        expect(result.notified).toBe(1);
        expect(sendMock).toHaveBeenCalledTimes(1);
    });
    it('sends an autoresponder to the submitter when enabled', async () => {
        const result = await sendFormNotifications({ ...baseSettings, autoresponderEnabled: true, autoresponderEmailFieldKey: 'email' }, ctx());
        expect(result.autoresponded).toBe(true);
        // 1 admin notification + 1 autoresponder
        expect(sendMock).toHaveBeenCalledTimes(2);
        expect(sendMock.mock.calls.some((c) => c[0].to === 'ada@calc.io')).toBe(true);
    });
    it('no-ops when notifications are disabled', async () => {
        const result = await sendFormNotifications({ ...baseSettings, enabled: false }, ctx());
        expect(result.skippedReason).toBe('notifications-disabled');
        expect(sendMock).not.toHaveBeenCalled();
    });
    it('no-ops when no email adapter is configured', async () => {
        configHolder.current = { platform: {} };
        const result = await sendFormNotifications(baseSettings, ctx());
        expect(result.skippedReason).toBe('no-email-adapter');
    });
    it('continues past a failing recipient without throwing', async () => {
        sendMock.mockRejectedValueOnce(new Error('smtp down'));
        const result = await sendFormNotifications({ ...baseSettings, recipients: ['a@x.com', 'b@x.com'] }, ctx());
        expect(result.notified).toBe(1);
    });
});
//# sourceMappingURL=notify.test.js.map