Skip to content

Commit 7a7be81

Browse files
Merge pull request #178 from NHSDigital/feature/CCM-5630_add-template-status
CCM-5630: use one database table
2 parents 9e776f2 + 3961940 commit 7a7be81

File tree

171 files changed

+2664
-4664
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

171 files changed

+2664
-4664
lines changed

amplify/backend.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,3 @@ const attachPolicy = new PolicyStatement({
2020
});
2121

2222
sendEmailLambda.addToRolePolicy(attachPolicy);
23-
24-
backend.data.resources.cfnResources.amplifyDynamoDbTables.SessionStorage.timeToLiveAttribute =
25-
{
26-
attributeName: 'ttl',
27-
enabled: true,
28-
};

amplify/data/resource.ts

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,27 @@
11
import { type ClientSchema, a, defineData } from '@aws-amplify/backend';
22
import { sendEmail } from '../functions/send-email/resource';
33

4-
const templateTypes = ['NHS_APP', 'SMS', 'EMAIL', 'LETTER'] as const;
4+
enum TemplateType {
5+
NHS_APP = 'NHS_APP',
6+
SMS = 'SMS',
7+
EMAIL = 'EMAIL',
8+
LETTER = 'LETTER',
9+
}
510

6-
const SessionStorageModel = {
7-
id: a.string().required(),
8-
templateType: a.enum([...templateTypes, 'UNKNOWN']),
9-
nhsAppTemplateName: a.string().required(),
10-
nhsAppTemplateMessage: a.string().required(),
11-
emailTemplateName: a.string(),
12-
emailTemplateSubjectLine: a.string(),
13-
emailTemplateMessage: a.string(),
14-
smsTemplateName: a.string(),
15-
smsTemplateMessage: a.string(),
16-
ttl: a.integer().required(),
17-
};
11+
const templateTypes = [
12+
TemplateType.NHS_APP,
13+
TemplateType.SMS,
14+
TemplateType.EMAIL,
15+
TemplateType.LETTER,
16+
] as const;
1817

1918
const TemplateStorageModel = {
2019
id: a.string().required(),
21-
name: a.string().required(),
22-
type: a.enum(templateTypes),
20+
templateType: a.ref('TemplateType').required(),
2321
version: a.integer().required(),
24-
fields: a.customType({
25-
subjectLine: a.string(),
26-
content: a.string().required(),
27-
}),
22+
name: a.string().required(),
23+
subject: a.string(),
24+
message: a.string().required(),
2825
};
2926

3027
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -34,7 +31,7 @@ const authPermission = (allow: any) =>
3431
: [allow.guest()];
3532

3633
const schema = a.schema({
37-
SessionStorage: a.model(SessionStorageModel).authorization(authPermission),
34+
TemplateType: a.enum(templateTypes),
3835
TemplateStorage: a.model(TemplateStorageModel).authorization(authPermission),
3936
sendEmail: a
4037
.query()

infrastructure/terraform/components/branch/module_amplify_branch.tf

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,5 @@ module "amplify_branch" {
2020
environment_variables = {
2121
NOTIFY_SUBDOMAIN = var.environment
2222
NEXT_PUBLIC_BASE_PATH = "/templates~${local.normalised_branch_name}"
23-
MAX_SESSION_LENGTH_IN_SECONDS = 432000 # 5 days in seconds
2423
}
2524
}

next.config.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ const nextConfig = {
66
basePath,
77
env: {
88
basePath,
9-
MAX_SESSION_LENGTH_IN_SECONDS:
10-
process.env.MAX_SESSION_LENGTH_IN_SECONDS ?? '432000', // 5 days in seconds
119
},
1210

1311
experimental: {
Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
11
import { render } from '@testing-library/react';
2-
import ChooseATemplateTypePage from '@app/choose-a-template-type/[sessionId]/page';
2+
import ChooseATemplateTypePage from '@app/choose-a-template-type/page';
33
import { TemplateFormState } from '@utils/types';
4-
import nav from 'next/navigation';
5-
6-
const mockSessionSupplier = {
7-
mockSession: {} as unknown,
8-
};
9-
10-
jest.mock('@utils/form-actions', () => ({
11-
getSession: () => Promise.resolve(mockSessionSupplier.mockSession),
12-
}));
134

145
jest.mock('next/navigation', () => ({
156
redirect: () => {
167
throw new Error('Simulated redirect');
178
},
18-
useRouter: () => {},
199

2010
RedirectType: {
2111
push: 'push',
@@ -39,35 +29,9 @@ jest.mock('react-dom', () => {
3929
});
4030

4131
test('ChooseATemplateTypePage', async () => {
42-
mockSessionSupplier.mockSession = {
43-
id: 'session-id',
44-
templateType: 'UNKNOWN',
45-
nhsAppTemplateName: '',
46-
nhsAppTemplateMessage: '',
47-
};
48-
49-
const page = await ChooseATemplateTypePage({
50-
params: {
51-
sessionId: 'session-id',
52-
},
53-
});
32+
const page = await ChooseATemplateTypePage();
5433

5534
const container = render(page);
5635

5736
expect(container.asFragment()).toMatchSnapshot();
5837
});
59-
60-
test('ChooseATemplateTypePage - should handle invalid session', async () => {
61-
mockSessionSupplier.mockSession = undefined;
62-
const redirectSpy = jest.spyOn(nav, 'redirect');
63-
64-
await expect(
65-
ChooseATemplateTypePage({
66-
params: {
67-
sessionId: 'session-id',
68-
},
69-
})
70-
).rejects.toThrow('Simulated redirect');
71-
72-
expect(redirectSpy).toHaveBeenCalledWith('/invalid-session', 'replace');
73-
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`CreateEmailTemplatePage should render CreateEmailTemplatePage 1`] = `
4+
<EmailTemplateForm
5+
initialState={
6+
{
7+
"message": "",
8+
"name": "",
9+
"subject": "",
10+
"templateType": "EMAIL",
11+
"version": 1,
12+
}
13+
}
14+
/>
15+
`;
Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,16 @@
1-
import CreateEmailTemplatePage from '@app/create-email-template/[sessionId]/page';
2-
import { getSession } from '@utils/form-actions';
3-
import { Session, TemplateType } from '@utils/types';
4-
import { redirect } from 'next/navigation';
5-
import { CreateEmailTemplate } from '@forms/CreateEmailTemplate/CreateEmailTemplate';
1+
/**
2+
* @jest-environment node
3+
*/
4+
import CreateEmailTemplatePage from '@app/create-email-template/page';
65

7-
jest.mock('@utils/form-actions');
8-
jest.mock('next/navigation');
9-
jest.mock('@forms/CreateEmailTemplate/CreateEmailTemplate');
10-
11-
const getSessionMock = jest.mocked(getSession);
12-
const redirectMock = jest.mocked(redirect);
13-
14-
const initialState: Session = {
15-
id: 'session-id',
16-
templateType: TemplateType.EMAIL,
17-
nhsAppTemplateName: '',
18-
nhsAppTemplateMessage: '',
19-
};
6+
jest.mock('@forms/EmailTemplateForm/EmailTemplateForm');
207

218
describe('CreateEmailTemplatePage', () => {
229
beforeEach(jest.resetAllMocks);
2310

24-
it('should redirect to invalid-session when no session is found', async () => {
25-
getSessionMock.mockResolvedValueOnce(undefined);
26-
27-
await CreateEmailTemplatePage({ params: { sessionId: 'session-id' } });
28-
29-
expect(getSessionMock).toHaveBeenCalledWith('session-id');
30-
31-
expect(redirectMock).toHaveBeenCalledWith('/invalid-session', 'replace');
32-
});
33-
34-
it('should redirect to invalid-session when sessions template type is not EMAIL', async () => {
35-
getSessionMock.mockResolvedValueOnce({
36-
...initialState,
37-
templateType: TemplateType.NHS_APP,
38-
});
39-
40-
await CreateEmailTemplatePage({ params: { sessionId: 'session-id' } });
41-
42-
expect(getSessionMock).toHaveBeenCalledWith('session-id');
43-
44-
expect(redirectMock).toHaveBeenCalledWith('/invalid-session', 'replace');
45-
});
46-
47-
it('should render CreateEmailTemplatePage component when session is found', async () => {
48-
getSessionMock.mockResolvedValueOnce(initialState);
49-
50-
const page = await CreateEmailTemplatePage({
51-
params: { sessionId: 'session-id' },
52-
});
53-
54-
expect(getSessionMock).toHaveBeenCalledWith('session-id');
11+
it('should render CreateEmailTemplatePage', async () => {
12+
const page = await CreateEmailTemplatePage();
5513

56-
expect(page).toEqual(<CreateEmailTemplate initialState={initialState} />);
14+
expect(page).toMatchSnapshot();
5715
});
5816
});

src/__tests__/app/create-letter-template/page.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import CreateLetterTemplatePage from '@app/create-letter-template/[sessionId]/page';
1+
import CreateLetterTemplatePage from '@app/create-letter-template/[templateId]/page';
22
import { render } from '@testing-library/react';
33

44
test('CreateLetterTemplatePage', async () => {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`CreateNHSAppTemplatePage should render CreateNHSAppTemplatePage 1`] = `
4+
<NhsAppTemplateForm
5+
initialState={
6+
{
7+
"message": "",
8+
"name": "",
9+
"templateType": "NHS_APP",
10+
"version": 1,
11+
}
12+
}
13+
/>
14+
`;
Lines changed: 9 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,16 @@
1-
import { redirect } from 'next/navigation';
2-
import { TemplateType } from '@utils/types';
3-
import { getSession } from '@utils/form-actions';
4-
import { CreateNhsAppTemplate } from '@forms/CreateNhsAppTemplate/CreateNhsAppTemplate';
5-
import CreateNhsAppTemplatePage from '@app/create-nhs-app-template/[sessionId]/page';
1+
/**
2+
* @jest-environment node
3+
*/
4+
import CreateNHSAppTemplatePage from '@app/create-nhs-app-template/page';
65

7-
jest.mock('@forms/CreateNhsAppTemplate/CreateNhsAppTemplate');
8-
jest.mock('@utils/form-actions');
9-
jest.mock('next/navigation');
6+
jest.mock('@forms/NhsAppTemplateForm/NhsAppTemplateForm');
107

11-
const getSessionMock = jest.mocked(getSession);
12-
const redirectMock = jest.mocked(redirect);
13-
14-
describe('CreateNhsAppTemplatePage', () => {
8+
describe('CreateNHSAppTemplatePage', () => {
159
beforeEach(jest.resetAllMocks);
1610

17-
test('page loads', async () => {
18-
const state = {
19-
id: 'session-id',
20-
templateType: TemplateType.NHS_APP,
21-
nhsAppTemplateName: '',
22-
nhsAppTemplateMessage: '',
23-
};
24-
25-
getSessionMock.mockResolvedValueOnce(state);
26-
27-
const page = await CreateNhsAppTemplatePage({
28-
params: { sessionId: 'session-id' },
29-
});
30-
31-
expect(page).toEqual(<CreateNhsAppTemplate initialState={state} />);
32-
});
33-
34-
test('should render invalid session, when session is not found', async () => {
35-
getSessionMock.mockResolvedValueOnce(undefined);
36-
37-
await CreateNhsAppTemplatePage({
38-
params: {
39-
sessionId: 'session-id',
40-
},
41-
});
11+
it('should render CreateNHSAppTemplatePage', async () => {
12+
const page = await CreateNHSAppTemplatePage();
4213

43-
expect(redirectMock).toHaveBeenCalledWith('/invalid-session', 'replace');
14+
expect(page).toMatchSnapshot();
4415
});
45-
46-
test.each([
47-
TemplateType.EMAIL,
48-
TemplateType.SMS,
49-
TemplateType.LETTER,
50-
'UNKNOWN',
51-
])(
52-
'should render invalid session, when session template type is %p',
53-
async (templateType) => {
54-
getSessionMock.mockResolvedValueOnce({
55-
id: 'session-id',
56-
templateType: templateType as TemplateType,
57-
nhsAppTemplateName: '',
58-
nhsAppTemplateMessage: '',
59-
});
60-
61-
await CreateNhsAppTemplatePage({
62-
params: {
63-
sessionId: 'session-id',
64-
},
65-
});
66-
67-
expect(redirectMock).toHaveBeenCalledWith('/invalid-session', 'replace');
68-
}
69-
);
7016
});

0 commit comments

Comments
 (0)