From 76f292ac408dd6d8f7f6ddbe59935deb12cdc5fc Mon Sep 17 00:00:00 2001 From: "muhammed.salaudeen1" Date: Tue, 10 Feb 2026 09:15:28 +0000 Subject: [PATCH 01/19] CCM-14372: Add a callout message for letter if letter authoring is disabled --- .tool-versions | 4 +- .../NHSNotifyRadioButtonForm.test.tsx.snap | 300 +++++++++++++ .../organisms/PreviewDigitalTemplate.test.tsx | 6 +- .../PreviewDigitalTemplate.test.tsx.snap | 401 ++++++++++++++++++ .../ChooseTemplateType/ChooseTemplateType.tsx | 7 +- .../NHSNotifyRadioButtonForm.tsx | 27 ++ .../PreviewDigitalTemplate.tsx | 1 + frontend/src/content/content.ts | 9 + 8 files changed, 749 insertions(+), 6 deletions(-) diff --git a/.tool-versions b/.tool-versions index 59870d18f..689a5b581 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,17 +1,15 @@ act 0.2.64 gitleaks 8.24.0 jq 1.6 -nodejs 22.22.0 +nodejs 22.16.0 pre-commit 3.6.0 terraform 1.10.1 terraform-docs 0.19.0 trivy 0.61.0 vale 3.6.0 python 3.13.2 - # ============================================================================== # The section below is reserved for Docker image versions. - # TODO: Move this section - consider using a different file for the repository template dependencies. # docker/ghcr.io/anchore/grype v0.104.3@sha256:d340f4f8b3b7e6e72a6c9c0152f25402ed8a2d7375dba1dfce4e53115242feb6 # SEE: https://github.com/anchore/grype/pkgs/container/grype # docker/ghcr.io/anchore/syft v1.39.0@sha256:6f13bb010923c33fb197047c8f88888e77071bd32596b3f605d62a133e493ce4 # SEE: https://github.com/anchore/syft/pkgs/container/syft diff --git a/frontend/src/__tests__/components/molecules/__snapshots__/NHSNotifyRadioButtonForm.test.tsx.snap b/frontend/src/__tests__/components/molecules/__snapshots__/NHSNotifyRadioButtonForm.test.tsx.snap index 282815eb2..095f6e642 100644 --- a/frontend/src/__tests__/components/molecules/__snapshots__/NHSNotifyRadioButtonForm.test.tsx.snap +++ b/frontend/src/__tests__/components/molecules/__snapshots__/NHSNotifyRadioButtonForm.test.tsx.snap @@ -82,6 +82,36 @@ exports[`Renders NHSNotifyRadioButtonForm - handles validation errors for other +
+
+

+ To create a letter template +

+

+ You cannot upload a letter template using this service. +

+

+ Follow our guidance to + + upload a letter template (opens in a new tab) + +

+
+
+ + +`; + +exports[`PreviewDigitalTemplate Routing disabled with letter authoring disabled matches snapshot 1`] = ` + +
+ NHS app message template +
+ Preview +
+ + +
+
+ + Example heading + +
+
+
+ + +
+
+ + +
+
+
+
+
+
+
+

+ To create a letter template +

+

+ You cannot upload a letter template using this service. +

+

+ Follow our guidance to + + upload a letter template (opens in a new tab) + +

+
+
+ +
+
+`; + exports[`PreviewDigitalTemplate Routing enabled matches snapshot 1`] = ` Preview @@ -234,3 +513,125 @@ exports[`PreviewDigitalTemplate Routing enabled matches snapshot 1`] = ` `; + +exports[`PreviewDigitalTemplate Routing enabled with letter authoring disabled matches snapshot 1`] = ` + + Preview +
+ + +
+
+ + Example heading + +
+
+
+ + +
+
+ + +
+
+
+
+
+
+
+

+ To create a letter template +

+

+ You cannot upload a letter template using this service. +

+

+ Follow our guidance to + + upload a letter template (opens in a new tab) + +

+
+
+ +
+
+`; diff --git a/frontend/src/components/forms/ChooseTemplateType/ChooseTemplateType.tsx b/frontend/src/components/forms/ChooseTemplateType/ChooseTemplateType.tsx index 81a30322d..11e3fb1b4 100644 --- a/frontend/src/components/forms/ChooseTemplateType/ChooseTemplateType.tsx +++ b/frontend/src/components/forms/ChooseTemplateType/ChooseTemplateType.tsx @@ -33,6 +33,10 @@ export const ChooseTemplateType = ({ const features = useFeatureFlags(); + const filteredTemplateTypes = features.letterAuthoring + ? templateTypes + : templateTypes.filter((type) => type !== 'LETTER'); + const $ChooseTemplateType = features.letterAuthoring ? $ChooseTemplateTypeWithLetterAuthoring : $ChooseTemplateTypeBase; @@ -61,7 +65,7 @@ export const ChooseTemplateType = ({ ); - const templateTypeOptions = templateTypes.map((templateType) => ({ + const templateTypeOptions = filteredTemplateTypes.map((templateType) => ({ id: templateType, text: content.templateTypes[templateType], conditional: @@ -93,6 +97,7 @@ export const ChooseTemplateType = ({ learnMoreLink={content.learnMoreLink} learnMoreText={content.learnMoreText} formAttributes={{ onSubmit: formValidate }} + isLetterAuthoringEnabled={features.letterAuthoring} /> diff --git a/frontend/src/components/molecules/NHSNotifyRadioButtonForm/NHSNotifyRadioButtonForm.tsx b/frontend/src/components/molecules/NHSNotifyRadioButtonForm/NHSNotifyRadioButtonForm.tsx index c01bc244b..93d10126a 100644 --- a/frontend/src/components/molecules/NHSNotifyRadioButtonForm/NHSNotifyRadioButtonForm.tsx +++ b/frontend/src/components/molecules/NHSNotifyRadioButtonForm/NHSNotifyRadioButtonForm.tsx @@ -2,6 +2,7 @@ import { Radios, Fieldset } from 'nhsuk-react-components'; import { FormState } from 'nhs-notify-web-template-management-utils'; import { NHSNotifyFormWrapper } from '@molecules/NHSNotifyFormWrapper/NHSNotifyFormWrapper'; import { NHSNotifyButton } from '@atoms/NHSNotifyButton/NHSNotifyButton'; +import content from '@content/content'; import { DetailedHTMLProps, FormHTMLAttributes, ReactNode } from 'react'; import Link from 'next/link'; @@ -33,8 +34,11 @@ export type NHSNotifyRadioButtonFormProps = { text: string; url: string; }; + isLetterAuthoringEnabled?: boolean; }; +const { warningCalloutContent } = content.components.chooseTemplateType; + const normaliseId = (id: string) => id.toLowerCase().replaceAll('_', '').replaceAll(',', '-'); @@ -52,6 +56,7 @@ export const NHSNotifyRadioButtonForm = ({ learnMoreLink = '', learnMoreText = '', backLink, + isLetterAuthoringEnabled = false, }: NHSNotifyRadioButtonFormProps) => ( + {isLetterAuthoringEnabled ? null : ( +
+
+

+ {warningCalloutContent.headingLabel} +

+

+ {warningCalloutContent.firstParagraph} +

+

+ {warningCalloutContent.secondParagraph} + + {warningCalloutContent.link.text} + +

+
+
+ )} )} diff --git a/frontend/src/content/content.ts b/frontend/src/content/content.ts index 9208ffafb..d4360204b 100644 --- a/frontend/src/content/content.ts +++ b/frontend/src/content/content.ts @@ -802,6 +802,15 @@ const chooseTemplateType = { x1: 'Large print letter', language: 'Other language letter', }, + warningCalloutContent: { + headingLabel: 'To create a letter template', + firstParagraph: 'You cannot upload a letter template using this service.', + secondParagraph: 'Follow our guidance to ', + link: { + text: 'upload a letter template (opens in a new tab)', + href: 'https://notify.nhs.uk/using-nhs-notify/upload-a-letter', + }, + }, }; const nameYourTemplate = { From cc069bffbe313256d7926d2c8997d396b074ca9d Mon Sep 17 00:00:00 2001 From: "muhammed.salaudeen1" Date: Wed, 11 Feb 2026 08:50:04 +0000 Subject: [PATCH 02/19] CCM-14372: Fix snapshot errors --- .../__snapshots__/page.test.tsx.snap | 163 ------- .../app/choose-a-template-type/page.test.tsx | 3 + .../__snapshots__/page.test.tsx.snap | 30 ++ .../ChooseMessageOrder.test.tsx | 3 + .../PreviewEmailTemplate.test.tsx | 16 +- .../PreviewNHSAppTemplate.test.tsx | 16 +- .../PreviewSMSTemplate.test.tsx | 16 +- .../organisms/PreviewDigitalTemplate.test.tsx | 14 +- .../PreviewDigitalTemplate.test.tsx.snap | 407 +----------------- 9 files changed, 83 insertions(+), 585 deletions(-) delete mode 100644 frontend/src/__tests__/app/choose-a-template-type/__snapshots__/page.test.tsx.snap diff --git a/frontend/src/__tests__/app/choose-a-template-type/__snapshots__/page.test.tsx.snap b/frontend/src/__tests__/app/choose-a-template-type/__snapshots__/page.test.tsx.snap deleted file mode 100644 index 11086d6c4..000000000 --- a/frontend/src/__tests__/app/choose-a-template-type/__snapshots__/page.test.tsx.snap +++ /dev/null @@ -1,163 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ChooseATemplateTypePage 1`] = ` - - - Back to all templates - -
-
- - -
-
- -

- Choose a template type to create -

-
-

- - Learn more about message channels (opens in a new tab) - -

-
-
- Select one option -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
-
- -
-
-
-`; diff --git a/frontend/src/__tests__/app/choose-a-template-type/page.test.tsx b/frontend/src/__tests__/app/choose-a-template-type/page.test.tsx index 3131e04e5..98c862849 100644 --- a/frontend/src/__tests__/app/choose-a-template-type/page.test.tsx +++ b/frontend/src/__tests__/app/choose-a-template-type/page.test.tsx @@ -4,9 +4,12 @@ import ChooseATemplateTypePage, { } from '@app/choose-a-template-type/page'; import { TemplateFormState } from 'nhs-notify-web-template-management-utils'; import content from '@content/content'; +import { useFeatureFlags } from '@providers/client-config-provider'; const { pageTitle } = content.components.chooseTemplateType; +jest.mocked(useFeatureFlags).mockReturnValue({ letterAuthoring: true }); + jest.mock('next/navigation', () => ({ redirect: () => { throw new Error('Simulated redirect'); diff --git a/frontend/src/__tests__/app/message-plans/choose-message-order/__snapshots__/page.test.tsx.snap b/frontend/src/__tests__/app/message-plans/choose-message-order/__snapshots__/page.test.tsx.snap index 26f886e7b..74acf350d 100644 --- a/frontend/src/__tests__/app/message-plans/choose-message-order/__snapshots__/page.test.tsx.snap +++ b/frontend/src/__tests__/app/message-plans/choose-message-order/__snapshots__/page.test.tsx.snap @@ -208,6 +208,36 @@ exports[`ChooseMessageOrderPage 1`] = ` +
+
+

+ To create a letter template +

+

+ You cannot upload a letter template using this service. +

+

+ Follow our guidance to + + upload a letter template (opens in a new tab) + +

+
+
- - -`; - -exports[`PreviewDigitalTemplate Routing disabled with letter authoring disabled matches snapshot 1`] = ` - -
- NHS app message template -
- Preview -
- - -
-
- - Example heading - -
-
-
- - -
-
- - -
-
-
-
-
-
-
-

- To create a letter template -

-

- You cannot upload a letter template using this service. -

-

- Follow our guidance to - - upload a letter template (opens in a new tab) - -

-
-
- -
-
-`; - -exports[`PreviewDigitalTemplate Routing enabled matches snapshot 1`] = ` +exports[`PreviewDigitalTemplate Routing enabled with letter authoring enabled matches snapshot 1`] = ` Preview `; - -exports[`PreviewDigitalTemplate Routing enabled with letter authoring disabled matches snapshot 1`] = ` - - Preview -
- - -
-
- - Example heading - -
-
-
- - -
-
- - -
-
-
-
-
-
- -
- -`; From 9e6a2f9fae883fa70adfcd963b8cc0eab267d308 Mon Sep 17 00:00:00 2001 From: "muhammed.salaudeen1" Date: Wed, 18 Feb 2026 09:30:49 +0000 Subject: [PATCH 03/19] CCM-14372: Fix unit test issues --- .../ChooseTemplateType.test.tsx | 2 +- .../ChooseTemplateType.test.tsx.snap | 196 +++++++++++------- 2 files changed, 121 insertions(+), 77 deletions(-) diff --git a/frontend/src/__tests__/components/forms/ChooseTemplateType/ChooseTemplateType.test.tsx b/frontend/src/__tests__/components/forms/ChooseTemplateType/ChooseTemplateType.test.tsx index 92f60c059..d22005243 100644 --- a/frontend/src/__tests__/components/forms/ChooseTemplateType/ChooseTemplateType.test.tsx +++ b/frontend/src/__tests__/components/forms/ChooseTemplateType/ChooseTemplateType.test.tsx @@ -9,7 +9,7 @@ jest.mock('@utils/amplify-utils'); jest.mock('@providers/client-config-provider', () => ({ useFeatureFlags: jest.fn().mockReturnValue({ - letterAuthoring: false, + letterAuthoring: true, }), })); diff --git a/frontend/src/__tests__/components/forms/ChooseTemplateType/__snapshots__/ChooseTemplateType.test.tsx.snap b/frontend/src/__tests__/components/forms/ChooseTemplateType/__snapshots__/ChooseTemplateType.test.tsx.snap index d9a571b5d..53b86b30e 100644 --- a/frontend/src/__tests__/components/forms/ChooseTemplateType/__snapshots__/ChooseTemplateType.test.tsx.snap +++ b/frontend/src/__tests__/components/forms/ChooseTemplateType/__snapshots__/ChooseTemplateType.test.tsx.snap @@ -166,29 +166,40 @@ exports[`Choose template page Client-side validation triggers - invalid form - e Text message (SMS) -
- - -
+
+
+

+ To create a letter template +

+

+ You cannot upload a letter template using this service. +

+

+ Follow our guidance to + + upload a letter template (opens in a new tab) + +

+
+
+ + + +`; diff --git a/frontend/src/__tests__/app/choose-a-template-type/page.test.tsx b/frontend/src/__tests__/app/choose-a-template-type/page.test.tsx index 98c862849..3131e04e5 100644 --- a/frontend/src/__tests__/app/choose-a-template-type/page.test.tsx +++ b/frontend/src/__tests__/app/choose-a-template-type/page.test.tsx @@ -4,12 +4,9 @@ import ChooseATemplateTypePage, { } from '@app/choose-a-template-type/page'; import { TemplateFormState } from 'nhs-notify-web-template-management-utils'; import content from '@content/content'; -import { useFeatureFlags } from '@providers/client-config-provider'; const { pageTitle } = content.components.chooseTemplateType; -jest.mocked(useFeatureFlags).mockReturnValue({ letterAuthoring: true }); - jest.mock('next/navigation', () => ({ redirect: () => { throw new Error('Simulated redirect'); diff --git a/frontend/src/__tests__/components/forms/ChooseMessageOrder/ChooseMessageOrder.test.tsx b/frontend/src/__tests__/components/forms/ChooseMessageOrder/ChooseMessageOrder.test.tsx index 5f79eaabe..253fb84b9 100644 --- a/frontend/src/__tests__/components/forms/ChooseMessageOrder/ChooseMessageOrder.test.tsx +++ b/frontend/src/__tests__/components/forms/ChooseMessageOrder/ChooseMessageOrder.test.tsx @@ -2,7 +2,6 @@ import { useActionState } from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import { ChooseMessageOrder } from '@forms/ChooseMessageOrder/ChooseMessageOrder'; import { TemplateFormState } from 'nhs-notify-web-template-management-utils'; -import { useFeatureFlags } from '@providers/client-config-provider'; jest.mock('@utils/amplify-utils'); @@ -25,8 +24,6 @@ jest.mock('react', () => { }; }); -jest.mocked(useFeatureFlags).mockReturnValue({ letterAuthoring: true }); - describe('Choose message order page', () => { const errorLogger = console.error; diff --git a/frontend/src/__tests__/components/forms/ChooseMessageOrder/__snapshots__/ChooseMessageOrder.test.tsx.snap b/frontend/src/__tests__/components/forms/ChooseMessageOrder/__snapshots__/ChooseMessageOrder.test.tsx.snap index 1de1ace94..acf61244d 100644 --- a/frontend/src/__tests__/components/forms/ChooseMessageOrder/__snapshots__/ChooseMessageOrder.test.tsx.snap +++ b/frontend/src/__tests__/components/forms/ChooseMessageOrder/__snapshots__/ChooseMessageOrder.test.tsx.snap @@ -244,6 +244,36 @@ exports[`Choose message order page Client-side validation triggers - invalid for +
+
+

+ To create a letter template +

+

+ You cannot upload a letter template using this service. +

+

+ Follow our guidance to + + upload a letter template (opens in a new tab) + +

+
+
+ + +`; + +exports[`Renders ChooseTemplateTypeRadios - renders without validation error field 1`] = ` + +
+ + +
+
+ +

+ Page heading +

+
+
+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+`; + +exports[`Renders ChooseTemplateTypeRadios correctly with errors 1`] = ` + +
+ + +
+
+ +

+ Page heading +

+
+
+ + + Error: + + Field error + +
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+`; + +exports[`Renders ChooseTemplateTypeRadios correctly without errors 1`] = ` + +
+ + +
+
+ +

+ Page heading +

+
+
+
+ Example hint +
+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+`; + +exports[`Renders ChooseTemplateTypeRadios with conditional content for a radio option 1`] = ` + +
+ + +
+
+ +

+ Page heading +

+
+
+
+
+ + +
+
+ + +
+
+
+

+ This is conditional content +

+
+
+
+
+
+
+ +
+
+`; + +exports[`Renders ChooseTemplateTypeRadios with conditional radios and validation error on nested field 1`] = ` + +
+ + +
+
+ +

+ Page heading +

+
+
+
+
+ + +
+
+ + +
+
+
+ + + Error: + + Please select a nested option + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+ +
+
+`; + +exports[`Renders ChooseTemplateTypeRadios with learn more link 1`] = ` + +
+ + +
+
+ +

+ Page heading +

+
+

+ + learn more + +

+
+
+ Example hint +
+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+`; + +exports[`Renders ChooseTemplateTypeRadios with nested conditional radio buttons 1`] = ` + +
+ + +
+
+ +

+ Page heading +

+
+
+
+
+ + +
+
+ + +
+
+
+
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+ +
+
+`; + +exports[`Renders ChooseTemplateTypeRadios without learn more link if learnMoreLink is not provided 1`] = ` + +
+ + +
+
+ +

+ Page heading +

+
+
+
+ Example hint +
+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+`; + +exports[`Renders ChooseTemplateTypeRadios without learn more link if learnMoreText is not provided 1`] = ` + +
+ + +
+
+ +

+ Page heading +

+
+
+
+ Example hint +
+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+`; diff --git a/frontend/src/__tests__/components/molecules/__snapshots__/NHSNotifyRadioButtonForm.test.tsx.snap b/frontend/src/__tests__/components/molecules/__snapshots__/NHSNotifyRadioButtonForm.test.tsx.snap index 709990cd1..282815eb2 100644 --- a/frontend/src/__tests__/components/molecules/__snapshots__/NHSNotifyRadioButtonForm.test.tsx.snap +++ b/frontend/src/__tests__/components/molecules/__snapshots__/NHSNotifyRadioButtonForm.test.tsx.snap @@ -82,36 +82,6 @@ exports[`Renders NHSNotifyRadioButtonForm - handles validation errors for other -
-
-

- To create a letter template -

-

- You cannot upload a letter template using this service. -

-

- Follow our guidance to - - upload a letter template (opens in a new tab) - -

-
-