Skip to content

Commit fa3bb8c

Browse files
CCM-12090: Support multiple campaigns (#693)
1 parent 3500bca commit fa3bb8c

File tree

48 files changed

+1736
-456
lines changed

Some content is hidden

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

48 files changed

+1736
-456
lines changed

.gitleaksignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ b19d88d1d92b0530f065feefcf25d8cdd82a876a:tests/test-team/auth/user.json:jwt:15
77
b19d88d1d92b0530f065feefcf25d8cdd82a876a:tests/test-team/auth/user.json:jwt:25
88
bc79df4f82052918ae6bf69d36279e5dd391d61e:tests/test-team/auth/user.json:jwt:15
99
bc79df4f82052918ae6bf69d36279e5dd391d61e:tests/test-team/auth/user.json:jwt:25
10+
306d9ec55d3498b86d5506da9a90ac486fc66563:frontend/src/components/molecules/MessagePlanFallbackConditions/MessagePlanFallbackConditions.tsx:ipv4:92

frontend/src/__tests__/app/upload-letter-template/__snapshots__/page.test.tsx.snap

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,35 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`UploadLetterTemplatePage should render UploadLetterTemplatePage 1`] = `
3+
exports[`UploadLetterTemplatePage should render UploadLetterTemplatePage with campaignId field when campaignIds is not available 1`] = `
44
<LetterTemplateForm
5+
campaignIds={
6+
[
7+
"campaign-id",
8+
]
9+
}
10+
initialState={
11+
{
12+
"campaignId": "campaign-id",
13+
"language": "en",
14+
"letterType": "x0",
15+
"name": "",
16+
"templateType": "LETTER",
17+
}
18+
}
19+
/>
20+
`;
21+
22+
exports[`UploadLetterTemplatePage should render UploadLetterTemplatePage with campaignIds field when available 1`] = `
23+
<LetterTemplateForm
24+
campaignIds={
25+
[
26+
"campaign-id",
27+
"other-campaign-id",
28+
]
29+
}
530
initialState={
631
{
32+
"campaignId": "",
733
"language": "en",
834
"letterType": "x0",
935
"name": "",

frontend/src/__tests__/app/upload-letter-template/page.test.tsx

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('UploadLetterTemplatePage', () => {
2323
jest.resetAllMocks();
2424
});
2525

26-
it('should render UploadLetterTemplatePage', async () => {
26+
it('should check client ID and campaign ID', async () => {
2727
mockGetSessionServer.mockResolvedValueOnce({
2828
accessToken: 'mocktoken',
2929
clientId: 'client1',
@@ -35,28 +35,67 @@ describe('UploadLetterTemplatePage', () => {
3535
},
3636
});
3737

38+
await UploadLetterTemplatePage();
39+
40+
expect(mockGetSessionServer).toHaveBeenCalled();
41+
expect(mockFetchClient).toHaveBeenCalled();
42+
});
43+
44+
it('should render UploadLetterTemplatePage with campaignIds field when available', async () => {
45+
mockGetSessionServer.mockResolvedValueOnce({
46+
accessToken: 'mocktoken',
47+
clientId: 'client1',
48+
});
49+
mockFetchClient.mockResolvedValueOnce({
50+
data: {
51+
campaignIds: ['campaign-id', 'other-campaign-id'],
52+
campaignId: 'campaign-id',
53+
features: {},
54+
},
55+
});
56+
3857
const page = await UploadLetterTemplatePage();
3958

4059
expect(await generateMetadata()).toEqual({ title: pageTitle });
4160
expect(page).toMatchSnapshot();
4261
});
4362

44-
it('should check client ID and campaign ID', async () => {
63+
it('should render UploadLetterTemplatePage with campaignId field when campaignIds is not available', async () => {
4564
mockGetSessionServer.mockResolvedValueOnce({
4665
accessToken: 'mocktoken',
4766
clientId: 'client1',
4867
});
4968
mockFetchClient.mockResolvedValueOnce({
5069
data: {
51-
campaignId: 'campaign2',
70+
campaignIds: undefined,
71+
campaignId: 'campaign-id',
5272
features: {},
5373
},
5474
});
5575

76+
const page = await UploadLetterTemplatePage();
77+
78+
expect(await generateMetadata()).toEqual({ title: pageTitle });
79+
expect(page).toMatchSnapshot();
80+
});
81+
82+
it('should redirect to error page when client configuration is not present', async () => {
83+
const mockRedirect = jest.mocked(redirect);
84+
85+
mockGetSessionServer.mockResolvedValueOnce({
86+
accessToken: 'mocktoken',
87+
clientId: 'client-id',
88+
});
89+
mockFetchClient.mockResolvedValueOnce({
90+
data: null,
91+
});
92+
5693
await UploadLetterTemplatePage();
5794

58-
expect(mockGetSessionServer).toHaveBeenCalled();
59-
expect(mockFetchClient).toHaveBeenCalled();
95+
expect(mockRedirect).toHaveBeenCalledWith(
96+
'/upload-letter-template/client-id-and-campaign-id-required',
97+
RedirectType.replace
98+
);
6099
});
61100

62101
it('should redirect to error page when client ID is not present', async () => {
@@ -81,7 +120,30 @@ describe('UploadLetterTemplatePage', () => {
81120
);
82121
});
83122

84-
it('should redirect to error page when campaign ID is not present', async () => {
123+
it('should redirect to error page when campaignIds is present and empty', async () => {
124+
const mockRedirect = jest.mocked(redirect);
125+
126+
mockGetSessionServer.mockResolvedValueOnce({
127+
accessToken: 'mocktoken',
128+
clientId: 'client2',
129+
});
130+
mockFetchClient.mockResolvedValueOnce({
131+
data: {
132+
campaignIds: [],
133+
campaignId: 'campaign-id',
134+
features: {},
135+
},
136+
});
137+
138+
await UploadLetterTemplatePage();
139+
140+
expect(mockRedirect).toHaveBeenCalledWith(
141+
'/upload-letter-template/client-id-and-campaign-id-required',
142+
RedirectType.replace
143+
);
144+
});
145+
146+
it('should redirect to error page when neither campaignIds nor campaignId is present', async () => {
85147
const mockRedirect = jest.mocked(redirect);
86148

87149
mockGetSessionServer.mockResolvedValueOnce({
@@ -90,6 +152,7 @@ describe('UploadLetterTemplatePage', () => {
90152
});
91153
mockFetchClient.mockResolvedValueOnce({
92154
data: {
155+
campaignIds: undefined,
93156
campaignId: undefined,
94157
features: {},
95158
},

frontend/src/__tests__/components/forms/LetterTemplateForm.test.tsx/LetterTemplateForm.test.tsx renamed to frontend/src/__tests__/components/forms/LetterTemplateForm/LetterTemplateForm.test.tsx

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { fireEvent, render, screen } from '@testing-library/react';
22
import { mockDeep } from 'jest-mock-extended';
33
import {
44
TemplateFormState,
5-
LetterTemplate,
5+
UploadLetterTemplate,
66
} from 'nhs-notify-web-template-management-utils';
77
import { LetterTemplateForm } from '@forms/LetterTemplateForm/LetterTemplateForm';
88

@@ -26,12 +26,30 @@ jest.mock('react', () => {
2626
test('renders page with preloaded field values', () => {
2727
const container = render(
2828
<LetterTemplateForm
29-
initialState={mockDeep<TemplateFormState<LetterTemplate>>({
29+
initialState={mockDeep<TemplateFormState<UploadLetterTemplate>>({
30+
campaignId: 'campaign-id',
3031
errorState: undefined,
3132
name: 'template-name',
3233
letterType: 'x1',
3334
language: 'ar',
3435
})}
36+
campaignIds={['campaign-id']}
37+
/>
38+
);
39+
expect(container.asFragment()).toMatchSnapshot();
40+
});
41+
42+
test('renders page with multiple campaign ids', () => {
43+
const container = render(
44+
<LetterTemplateForm
45+
initialState={mockDeep<TemplateFormState<UploadLetterTemplate>>({
46+
campaignId: 'campaign-id',
47+
errorState: undefined,
48+
name: 'template-name',
49+
letterType: 'x1',
50+
language: 'ar',
51+
})}
52+
campaignIds={['campaign-id', 'other-campaign-id']}
3553
/>
3654
);
3755
expect(container.asFragment()).toMatchSnapshot();
@@ -43,12 +61,14 @@ test('shows right-to-left language warning when language changes', () => {
4361

4462
const container = render(
4563
<LetterTemplateForm
46-
initialState={mockDeep<TemplateFormState<LetterTemplate>>({
64+
initialState={mockDeep<TemplateFormState<UploadLetterTemplate>>({
65+
campaignId: 'campaign-id',
4766
errorState: undefined,
4867
name: 'template-name',
4968
letterType: 'x1',
5069
language: initialLanguage,
5170
})}
71+
campaignIds={['campaign-id']}
5272
/>
5373
);
5474

@@ -68,12 +88,14 @@ test('hides right-to-left language warning when language changes', () => {
6888

6989
const container = render(
7090
<LetterTemplateForm
71-
initialState={mockDeep<TemplateFormState<LetterTemplate>>({
91+
initialState={mockDeep<TemplateFormState<UploadLetterTemplate>>({
92+
campaignId: 'campaign-id',
7293
errorState: undefined,
7394
name: 'template-name',
7495
letterType: 'x1',
7596
language: initialLanguage,
7697
})}
98+
campaignIds={['campaign-id']}
7799
/>
78100
);
79101

@@ -90,7 +112,8 @@ test('hides right-to-left language warning when language changes', () => {
90112
test('renders page one error', () => {
91113
const container = render(
92114
<LetterTemplateForm
93-
initialState={mockDeep<TemplateFormState<LetterTemplate>>({
115+
initialState={mockDeep<TemplateFormState<UploadLetterTemplate>>({
116+
campaignId: 'campaign-id',
94117
errorState: {
95118
formErrors: [],
96119
fieldErrors: {
@@ -101,6 +124,7 @@ test('renders page one error', () => {
101124
letterType: 'x0',
102125
language: 'en',
103126
})}
127+
campaignIds={['campaign-id']}
104128
/>
105129
);
106130
expect(container.asFragment()).toMatchSnapshot();
@@ -109,7 +133,8 @@ test('renders page one error', () => {
109133
test('renders page with multiple errors', () => {
110134
const container = render(
111135
<LetterTemplateForm
112-
initialState={mockDeep<TemplateFormState<LetterTemplate>>({
136+
initialState={mockDeep<TemplateFormState<UploadLetterTemplate>>({
137+
campaignId: 'campaign-id',
113138
errorState: {
114139
formErrors: [],
115140
fieldErrors: {
@@ -124,6 +149,7 @@ test('renders page with multiple errors', () => {
124149
letterType: undefined,
125150
language: undefined,
126151
})}
152+
campaignIds={['campaign-id']}
127153
/>
128154
);
129155
expect(container.asFragment()).toMatchSnapshot();
@@ -132,12 +158,14 @@ test('renders page with multiple errors', () => {
132158
test('Client-side validation triggers', () => {
133159
const container = render(
134160
<LetterTemplateForm
135-
initialState={mockDeep<TemplateFormState<LetterTemplate>>({
161+
initialState={mockDeep<TemplateFormState<UploadLetterTemplate>>({
162+
campaignId: 'campaign-id',
136163
errorState: undefined,
137164
name: undefined,
138165
letterType: undefined,
139166
language: undefined,
140167
})}
168+
campaignIds={['campaign-id']}
141169
/>
142170
);
143171
const submitButton = screen.getByTestId('submit-button');

0 commit comments

Comments
 (0)