Skip to content

Commit f86a1e8

Browse files
CCM-11537: Backend filter
1 parent 94f9c46 commit f86a1e8

File tree

34 files changed

+1324
-573
lines changed

34 files changed

+1324
-573
lines changed

frontend/src/__tests__/components/forms/CopyTemplate/CopyTemplate.test.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { mockDeep } from 'jest-mock-extended';
55
import { render, screen, fireEvent } from '@testing-library/react';
66
import { CopyTemplate, ValidCopyType } from '@forms/CopyTemplate/CopyTemplate';
77
import { TemplateFormState } from 'nhs-notify-web-template-management-utils';
8-
import { ValidatedTemplateDto } from 'nhs-notify-backend-client';
8+
import { TemplateDto } from 'nhs-notify-backend-client';
99

1010
jest.mock('@utils/amplify-utils');
1111

@@ -32,9 +32,7 @@ describe('Choose template page', () => {
3232
it('selects one radio button at a time', () => {
3333
const container = render(
3434
<CopyTemplate
35-
template={mockDeep<
36-
ValidatedTemplateDto & { templateType: ValidCopyType }
37-
>()}
35+
template={mockDeep<TemplateDto & { templateType: ValidCopyType }>()}
3836
/>
3937
);
4038
expect(container.asFragment()).toMatchSnapshot();
@@ -84,9 +82,7 @@ describe('Choose template page', () => {
8482

8583
const container = render(
8684
<CopyTemplate
87-
template={mockDeep<
88-
ValidatedTemplateDto & { templateType: ValidCopyType }
89-
>()}
85+
template={mockDeep<TemplateDto & { templateType: ValidCopyType }>()}
9086
/>
9187
);
9288
expect(container.asFragment()).toMatchSnapshot();
@@ -95,9 +91,7 @@ describe('Choose template page', () => {
9591
test('Client-side validation triggers', () => {
9692
const container = render(
9793
<CopyTemplate
98-
template={mockDeep<
99-
ValidatedTemplateDto & { templateType: ValidCopyType }
100-
>()}
94+
template={mockDeep<TemplateDto & { templateType: ValidCopyType }>()}
10195
/>
10296
);
10397
const submitButton = screen.getByTestId('submit-button');

frontend/src/__tests__/utils/form-actions.test.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
createRoutingConfig,
1919
} from '@utils/form-actions';
2020
import { getSessionServer } from '@utils/amplify-utils';
21-
import { TemplateDto } from 'nhs-notify-backend-client';
21+
import { TemplateDto, TemplateStatus } from 'nhs-notify-backend-client';
2222
import { templateApiClient } from 'nhs-notify-backend-client/src/template-api-client';
2323
import { routingConfigurationApiClient } from 'nhs-notify-backend-client/src/routing-config-api-client';
2424
import { randomUUID } from 'node:crypto';
@@ -539,6 +539,39 @@ describe('form-actions', () => {
539539
expect(actualOrder).toEqual(expectedOrder);
540540
});
541541

542+
test('getTemplates - invalid templates are not listed', async () => {
543+
const validTemplate: TemplateDto = {
544+
templateType: 'SMS',
545+
templateStatus: 'SUBMITTED',
546+
name: 'Template',
547+
message: 'Message',
548+
createdAt: '2020-01-01T00:00:00.000Z',
549+
id: '02',
550+
updatedAt: '2021-01-01T00:00:00.000Z',
551+
lockNumber: 1,
552+
};
553+
554+
mockedTemplateClient.listTemplates.mockResolvedValueOnce({
555+
data: [
556+
{
557+
templateType: 'SMS',
558+
templateStatus: undefined as unknown as TemplateStatus,
559+
name: 'Template',
560+
message: 'Message',
561+
createdAt: '2020-01-01T00:00:00.000Z',
562+
id: '01',
563+
updatedAt: '2021-01-01T00:00:00.000Z',
564+
lockNumber: 1,
565+
},
566+
validTemplate,
567+
],
568+
});
569+
570+
const response = await getTemplates();
571+
572+
expect(response).toEqual([validTemplate]);
573+
});
574+
542575
describe('setTemplateToSubmitted', () => {
543576
test('submitTemplate successfully', async () => {
544577
const responseData = {

frontend/src/__tests__/utils/message-plans.test.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,17 +251,13 @@ describe('Message plans actions', () => {
251251
const completedCount = await countRoutingConfigs('COMPLETED');
252252

253253
expect(draftCount).toEqual(1);
254-
expect(routingConfigApiMock.count).toHaveBeenNthCalledWith(
255-
1,
256-
'token',
257-
'DRAFT'
258-
);
254+
expect(routingConfigApiMock.count).toHaveBeenNthCalledWith(1, 'token', {
255+
status: 'DRAFT',
256+
});
259257
expect(completedCount).toEqual(5);
260-
expect(routingConfigApiMock.count).toHaveBeenNthCalledWith(
261-
2,
262-
'token',
263-
'COMPLETED'
264-
);
258+
expect(routingConfigApiMock.count).toHaveBeenNthCalledWith(2, 'token', {
259+
status: 'COMPLETED',
260+
});
265261
});
266262
});
267263

frontend/src/app/copy-template/[templateId]/page.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22

33
import { redirect, RedirectType } from 'next/navigation';
44
import { CopyTemplate } from '@forms/CopyTemplate/CopyTemplate';
5-
import { TemplatePageProps } from 'nhs-notify-web-template-management-utils';
5+
import {
6+
TemplatePageProps,
7+
validateTemplate,
8+
} from 'nhs-notify-web-template-management-utils';
69
import { getTemplate } from '@utils/form-actions';
7-
import { isTemplateDtoValid } from 'nhs-notify-backend-client';
810

911
const CopyTemplatePage = async (props: TemplatePageProps) => {
1012
const { templateId } = await props.params;
1113

1214
const template = await getTemplate(templateId);
1315

14-
const validatedTemplate = isTemplateDtoValid(template);
16+
const validatedTemplate = validateTemplate(template);
1517

1618
if (!validatedTemplate) {
1719
return redirect('/invalid-template', RedirectType.replace);

frontend/src/components/forms/CopyTemplate/CopyTemplate.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import {
1010
} from 'nhs-notify-web-template-management-utils';
1111
import { NHSNotifyMain } from '@atoms/NHSNotifyMain/NHSNotifyMain';
1212
import { $CopyTemplate, copyTemplateAction } from './server-action';
13-
import { TemplateType, ValidatedTemplateDto } from 'nhs-notify-backend-client';
13+
import { TemplateDto, TemplateType } from 'nhs-notify-backend-client';
1414
import { validate } from '@utils/client-validate-form';
1515
import Link from 'next/link';
1616
import NotifyBackLink from '@atoms/NHSNotifyBackLink/NHSNotifyBackLink';
1717

1818
export type ValidCopyType = Exclude<TemplateType, 'LETTER'>;
1919

2020
type CopyTemplate = {
21-
template: ValidatedTemplateDto & { templateType: ValidCopyType };
21+
template: TemplateDto & { templateType: ValidCopyType };
2222
};
2323

2424
export const CopyTemplate = ({ template }: CopyTemplate) => {

frontend/src/components/forms/CopyTemplate/server-action.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { createTemplate } from '@utils/form-actions';
55
import { format } from 'date-fns/format';
66
import {
77
TEMPLATE_TYPE_LIST,
8+
TemplateDto,
89
TemplateType,
9-
ValidatedTemplateDto,
1010
} from 'nhs-notify-backend-client';
1111
import content from '@content/content';
1212

@@ -17,7 +17,7 @@ export const $CopyTemplate = z.object({
1717
});
1818

1919
type CopyTemplateActionState = FormState & {
20-
template: ValidatedTemplateDto & {
20+
template: TemplateDto & {
2121
templateType: Exclude<TemplateType, 'LETTER'>;
2222
};
2323
};

frontend/src/utils/form-actions.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
import { getSessionServer } from '@utils/amplify-utils';
44
import {
5+
$TemplateDto,
56
CreateUpdateTemplate,
6-
isTemplateDtoValid,
77
RoutingConfig,
88
TemplateDto,
9-
ValidatedTemplateDto,
109
} from 'nhs-notify-backend-client';
1110
import { logger } from 'nhs-notify-web-template-management-utils/logger';
1211
import { templateApiClient } from 'nhs-notify-backend-client/src/template-api-client';
@@ -191,13 +190,17 @@ export async function getTemplates(): Promise<TemplateDto[]> {
191190
return [];
192191
}
193192

194-
const sortedData = data
195-
.map((template) => isTemplateDtoValid(template))
196-
.filter(
197-
(template): template is ValidatedTemplateDto => template !== undefined
198-
);
193+
const valid = data.filter((d) => {
194+
const { error: validationError, success } = $TemplateDto.safeParse(d);
199195

200-
return sortAscByUpdatedAt(sortedData);
196+
if (!success) {
197+
logger.error('Listed invalid template', validationError);
198+
}
199+
200+
return success;
201+
});
202+
203+
return sortAscByUpdatedAt(valid);
201204
}
202205

203206
export async function createRoutingConfig(

frontend/src/utils/message-plans.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export async function countRoutingConfigs(
5353

5454
const { data, error } = await routingConfigurationApiClient.count(
5555
accessToken,
56-
status
56+
{ status }
5757
);
5858

5959
if (error) {

infrastructure/terraform/modules/backend-api/spec.tmpl.json

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@
766766
],
767767
"type": "object"
768768
},
769-
"TemplateStatus": {
769+
"TemplateStatusActive": {
770770
"enum": [
771771
"DELETED",
772772
"NOT_YET_SUBMITTED",
@@ -781,6 +781,19 @@
781781
],
782782
"type": "string"
783783
},
784+
"TemplateStatus": {
785+
"anyOf": [
786+
{
787+
"$ref": "#/components/schemas/TemplateStatusActive"
788+
},
789+
{
790+
"enum": [
791+
"DELETED"
792+
],
793+
"type": "string"
794+
}
795+
]
796+
},
784797
"TemplateSuccess": {
785798
"properties": {
786799
"data": {
@@ -1942,6 +1955,40 @@
19421955
"/v1/templates": {
19431956
"get": {
19441957
"description": "List all templates",
1958+
"parameters": [
1959+
{
1960+
"description": "Filter by a single active status",
1961+
"in": "query",
1962+
"name": "templateStatus",
1963+
"schema": {
1964+
"$ref": "#/components/schemas/TemplateStatusActive"
1965+
}
1966+
},
1967+
{
1968+
"description": "Filter by a single template type",
1969+
"in": "query",
1970+
"name": "templateType",
1971+
"schema": {
1972+
"$ref": "#/components/schemas/TemplateType"
1973+
}
1974+
},
1975+
{
1976+
"description": "Filter by a single language",
1977+
"in": "query",
1978+
"name": "language",
1979+
"schema": {
1980+
"$ref": "#/components/schemas/Language"
1981+
}
1982+
},
1983+
{
1984+
"description": "Filter by a single accessible letter type",
1985+
"in": "query",
1986+
"name": "letterType",
1987+
"schema": {
1988+
"$ref": "#/components/schemas/LetterType"
1989+
}
1990+
}
1991+
],
19451992
"responses": {
19461993
"200": {
19471994
"content": {

0 commit comments

Comments
 (0)