Skip to content

Commit ed1f70e

Browse files
committed
Merge branch 'main' of https://github.com/NHSDigital/nhs-notify-web-template-management into feature/CCM-11492-create-edit-message-plans
2 parents 0639b36 + a04a5cf commit ed1f70e

File tree

42 files changed

+2090
-1225
lines changed

Some content is hidden

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

42 files changed

+2090
-1225
lines changed

frontend/src/__tests__/app/message-plans/create-message-plan/__snapshots__/page.test.tsx.snap

Lines changed: 354 additions & 163 deletions
Large diffs are not rendered by default.

frontend/src/__tests__/app/message-plans/create-message-plan/page.test.tsx

Lines changed: 88 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,100 @@
1-
import { render } from '@testing-library/react';
1+
import { render, screen, waitFor } from '@testing-library/react';
2+
import userEvent from '@testing-library/user-event';
23
import { redirect, RedirectType } from 'next/navigation';
34
import { MESSAGE_ORDER_OPTIONS_LIST } from 'nhs-notify-web-template-management-utils';
45
import CreateMessagePlanPage from '@app/message-plans/create-message-plan/page';
5-
import { MessagePlanForm } from '@forms/MessagePlan/MessagePlan';
6-
import { fetchClient } from '@utils/server-features';
6+
import { createMessagePlanServerAction } from '@app/message-plans/create-message-plan/server-action';
77
import { NextRedirectError } from '@testhelpers/next-redirect';
8+
import { verifyFormCsrfToken } from '@utils/csrf-utils';
9+
import { fetchClient } from '@utils/server-features';
810

911
jest.mock('next/navigation');
10-
jest.mock('@forms/MessagePlan/MessagePlan');
12+
jest.mocked(redirect).mockImplementation((url, type) => {
13+
throw new NextRedirectError(url, type);
14+
});
15+
16+
jest.mock('@app/message-plans/create-message-plan/server-action');
17+
18+
jest.mock('@utils/csrf-utils');
19+
jest.mocked(verifyFormCsrfToken).mockResolvedValue(true);
20+
1121
jest.mock('@utils/server-features');
22+
jest.mocked(fetchClient).mockResolvedValue({
23+
campaignIds: ['campaign-1', 'campaign-2'],
24+
features: {},
25+
});
1226

1327
beforeEach(() => {
14-
jest.resetAllMocks();
28+
jest.clearAllMocks();
29+
});
1530

16-
jest.mocked(redirect).mockImplementation((url, type) => {
17-
throw new NextRedirectError(url, type);
31+
describe('CreateMessagePlanPage', () => {
32+
test('renders the page', async () => {
33+
const ui = await CreateMessagePlanPage({
34+
searchParams: Promise.resolve({ messageOrder: 'NHSAPP' }),
35+
});
36+
37+
const container = render(ui);
38+
39+
expect(container.asFragment()).toMatchSnapshot();
1840
});
1941

20-
jest
21-
.mocked(MessagePlanForm)
22-
.mockImplementation(() => <div data-testid='mocked-message-plan-form' />);
42+
test('on submit it invokes the server action and renders error summary', async () => {
43+
const user = await userEvent.setup();
2344

24-
jest
25-
.mocked(fetchClient)
26-
.mockResolvedValue({ campaignIds: ['campaign-1'], features: {} });
27-
});
45+
jest.mocked(createMessagePlanServerAction).mockResolvedValue({
46+
errorState: {
47+
fieldErrors: {
48+
name: ['Name Error'],
49+
campaignId: ['Campaign Id Error'],
50+
},
51+
},
52+
});
53+
54+
const ui = await CreateMessagePlanPage({
55+
searchParams: Promise.resolve({ messageOrder: 'NHSAPP' }),
56+
});
57+
58+
const container = render(ui);
59+
60+
await user.click(screen.getByTestId('name-field'));
61+
62+
await user.keyboard('My Message Plan');
63+
64+
await user.selectOptions(
65+
screen.getByTestId('campaign-id-field'),
66+
'campaign-2'
67+
);
68+
69+
await user.click(screen.getByTestId('submit-button'));
70+
71+
expect(container.asFragment()).toMatchSnapshot();
72+
73+
expect(createMessagePlanServerAction).toHaveBeenCalledTimes(1);
74+
expect(createMessagePlanServerAction).toHaveBeenCalledWith(
75+
{},
76+
expect.any(FormData)
77+
);
78+
79+
const formData = jest
80+
.mocked(createMessagePlanServerAction)
81+
.mock.lastCall?.at(1) as FormData;
82+
83+
expect(Object.fromEntries(formData.entries())).toMatchObject({
84+
campaignId: 'campaign-2',
85+
messageOrder: 'NHSAPP',
86+
name: 'My Message Plan',
87+
});
88+
89+
const errorSummaryHeading = await screen.getByTestId('error-summary');
90+
91+
// "error-summary" test id targets the nested heading rather than the top level of the error summary
92+
// so we need to assert against the parent element
93+
await waitFor(() => {
94+
expect(errorSummaryHeading.parentElement).toHaveFocus();
95+
});
96+
});
2897

29-
describe('CreateMessagePlanPage', () => {
3098
test('redirects when there are no campaignIds', async () => {
3199
jest.mocked(fetchClient).mockResolvedValueOnce({ features: {} });
32100

@@ -64,18 +132,11 @@ describe('CreateMessagePlanPage', () => {
64132
test.each(MESSAGE_ORDER_OPTIONS_LIST)(
65133
'renders the page when messageOrder is "%s"',
66134
async (messageOrder) => {
67-
const ui = await CreateMessagePlanPage({
68-
searchParams: Promise.resolve({ messageOrder }),
69-
});
70-
71-
const container = render(ui);
72-
73-
expect(container.asFragment()).toMatchSnapshot();
74-
75-
expect(jest.mocked(MessagePlanForm).mock.calls[0][0]).toEqual({
76-
messageOrder,
77-
campaignIds: ['campaign-1'],
78-
});
135+
await expect(
136+
CreateMessagePlanPage({
137+
searchParams: Promise.resolve({ messageOrder }),
138+
})
139+
).resolves.not.toThrow();
79140
}
80141
);
81142
});

0 commit comments

Comments
 (0)