Files
redefined-designs/backend/tests/unit/uploadLinkTemplate.test.ts
bermudalambandClaude Opus 5 eaecc43379 feat(intake): record where an upload link was sent, and how to say it (#260)
Adds upload_links.contact_email and the uploadLink mail template.

The column is nullable on purpose. Links already exist in QA and a migration cannot invent addresses for them, so they are grandfathered rather than backfilled with something untrue; the requirement belongs in the create route, which is where new links are actually made.

The template requires submitUrl, the same guard verification has on verifyUrl. An email inviting somebody to send in photos, with no way for them to do it, sends perfectly happily and looks fine in the log — it is the one failure here worth making impossible, and a test asserts the default body satisfies the guard it declares.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 17:50:11 -05:00

49 lines
1.8 KiB
TypeScript

import { TEMPLATES, missingPlaceholders, renderTemplate } from '../../src/emailTemplates';
/**
* The template that carries an upload link (#260).
*
* The one failure worth making impossible is a link email with no link in it:
* it sends, it looks fine in the log, and it is useless to the person who gets
* it. That is the same guard `verification` has on `verifyUrl`.
*/
describe('the upload link template', () => {
it('is offered in the admin like the others', () => {
expect(TEMPLATES.uploadLink.label).toBeTruthy();
});
it('requires the submit link', () => {
expect(TEMPLATES.uploadLink.required).toContain('submitUrl');
});
it('refuses a body that has no link in it', () => {
expect(missingPlaceholders('uploadLink', 'Hello, a link is on its way.')).toEqual(['submitUrl']);
});
it('accepts a body that has one', () => {
expect(missingPlaceholders('uploadLink', 'Send your items: {{submitUrl}}')).toEqual([]);
});
it('offers the label and the allowance as placeholders', () => {
expect(TEMPLATES.uploadLink.available).toEqual(
expect.arrayContaining(['submitUrl', 'label', 'submissionsAllowed'])
);
});
// The default body has to satisfy the guard it declares, or the feature ships
// unable to send its own default.
it('has a default body that satisfies its own requirement', () => {
expect(missingPlaceholders('uploadLink', TEMPLATES.uploadLink.defaultBody)).toEqual([]);
});
it('renders the link into the body', () => {
const rendered = renderTemplate(
'uploadLink',
{ subject: 'Send us your items', body: 'Here: {{submitUrl}}' },
{ submitUrl: 'https://example.com/submit/abc', label: 'Sarah', submissionsAllowed: '25 items' }
);
expect(rendered.html).toContain('https://example.com/submit/abc');
});
});