Feature/260 email the upload link #292
@@ -281,7 +281,10 @@ export const SAMPLE_VALUES: Record<string, string> = {
|
|||||||
regenerateUrl: 'https://example.com/api/intake-actions/1/regenerate?expires=0&sig=sample',
|
regenerateUrl: 'https://example.com/api/intake-actions/1/regenerate?expires=0&sig=sample',
|
||||||
discardUrl: 'https://example.com/api/intake-actions/1/discard?expires=0&sig=sample',
|
discardUrl: 'https://example.com/api/intake-actions/1/discard?expires=0&sig=sample',
|
||||||
expiresIn: 'one hour',
|
expiresIn: 'one hour',
|
||||||
holdDuration: '24 hours'
|
holdDuration: '24 hours',
|
||||||
|
submitUrl: 'https://example.com/submit/sample-token',
|
||||||
|
label: 'Autumn drop-off',
|
||||||
|
submissionsAllowed: '25 items'
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface StoredTemplate {
|
export interface StoredTemplate {
|
||||||
|
|||||||
@@ -8,14 +8,11 @@ import {
|
|||||||
SAMPLE_VALUES
|
SAMPLE_VALUES
|
||||||
} from '../../src/emailTemplates';
|
} from '../../src/emailTemplates';
|
||||||
|
|
||||||
const KEYS: TemplateKey[] = [
|
// Derived from TEMPLATES rather than hardcoded, so a new template is covered
|
||||||
'verification',
|
// by every it.each below the moment it is added. A hardcoded list silently
|
||||||
'passwordReset',
|
// stops covering anything added after it was written — which is exactly how
|
||||||
'favoriteSold',
|
// intakeDraft and uploadLink went untested by the SAMPLE_VALUES guard below.
|
||||||
'favoriteWithdrawn',
|
const KEYS = Object.keys(TEMPLATES) as TemplateKey[];
|
||||||
'cartReminder',
|
|
||||||
'emailChanged'
|
|
||||||
];
|
|
||||||
|
|
||||||
describe('the built-in templates', () => {
|
describe('the built-in templates', () => {
|
||||||
it.each(KEYS)('%s has a default subject and body', (key) => {
|
it.each(KEYS)('%s has a default subject and body', (key) => {
|
||||||
@@ -268,7 +265,22 @@ describe('greeting, built from the configured format', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('every template can address the customer', () => {
|
describe('every template can address the customer', () => {
|
||||||
it.each(KEYS)('%s offers greeting, firstName and lastName', (key) => {
|
// Not KEYS: this is an invariant of the six customer-facing templates only.
|
||||||
|
// intakeDraft and uploadLink notify the shop and a contributor respectively,
|
||||||
|
// not a customer with a name on file, so they are deliberately not held to
|
||||||
|
// it — a hardcoded list is correct here rather than a staleness risk,
|
||||||
|
// because the set of templates this claim applies to does not grow just
|
||||||
|
// because TEMPLATES does.
|
||||||
|
const CUSTOMER_FACING_KEYS: TemplateKey[] = [
|
||||||
|
'verification',
|
||||||
|
'passwordReset',
|
||||||
|
'favoriteSold',
|
||||||
|
'favoriteWithdrawn',
|
||||||
|
'cartReminder',
|
||||||
|
'emailChanged'
|
||||||
|
];
|
||||||
|
|
||||||
|
it.each(CUSTOMER_FACING_KEYS)('%s offers greeting, firstName and lastName', (key) => {
|
||||||
expect(TEMPLATES[key].available).toEqual(
|
expect(TEMPLATES[key].available).toEqual(
|
||||||
expect.arrayContaining(['greeting', 'firstName', 'lastName'])
|
expect.arrayContaining(['greeting', 'firstName', 'lastName'])
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user