diff --git a/.gitleaksignore b/.gitleaksignore
index 76fe6a1c9..196f6cb44 100644
--- a/.gitleaksignore
+++ b/.gitleaksignore
@@ -8,3 +8,5 @@ b19d88d1d92b0530f065feefcf25d8cdd82a876a:tests/test-team/auth/user.json:jwt:25
bc79df4f82052918ae6bf69d36279e5dd391d61e:tests/test-team/auth/user.json:jwt:15
bc79df4f82052918ae6bf69d36279e5dd391d61e:tests/test-team/auth/user.json:jwt:25
306d9ec55d3498b86d5506da9a90ac486fc66563:frontend/src/components/molecules/MessagePlanFallbackConditions/MessagePlanFallbackConditions.tsx:ipv4:92
+a408293ecbc3a95684246fd16b111b6e09d6e194:lambdas/backend-client/src/__tests__/schemas/contact-details/email.test.ts:ipv4:80
+a408293ecbc3a95684246fd16b111b6e09d6e194:lambdas/backend-client/src/__tests__/schemas/contact-details/email.test.ts:ipv4:81
diff --git a/frontend/src/__tests__/app/message-plans/choose-british-sign-language-letter-template/preview-template/page.test.tsx b/frontend/src/__tests__/app/message-plans/choose-british-sign-language-letter-template/preview-template/page.test.tsx
index 47d1a52b4..12c6253b5 100644
--- a/frontend/src/__tests__/app/message-plans/choose-british-sign-language-letter-template/preview-template/page.test.tsx
+++ b/frontend/src/__tests__/app/message-plans/choose-british-sign-language-letter-template/preview-template/page.test.tsx
@@ -1,91 +1,39 @@
+/**
+ * @jest-environment node
+ */
import PreviewBritishSignLanguageLetterTemplateFromMessagePlan, {
generateMetadata,
} from '@app/message-plans/choose-british-sign-language-letter-template/[routingConfigId]/preview-template/[templateId]/page';
-import { BSL_LETTER_TEMPLATE, ROUTING_CONFIG } from '@testhelpers/helpers';
-import { render } from '@testing-library/react';
-import { getTemplate } from '@utils/form-actions';
-import { redirect } from 'next/navigation';
+import { SummaryChooseLetter } from '@molecules/SummaryChooseLetter/SummaryChooseLetter';
+import { validateBritishSignLanguageLetterTemplate } from 'nhs-notify-web-template-management-utils';
-jest.mock('@utils/form-actions');
-jest.mock('next/navigation');
-
-const getTemplateMock = jest.mocked(getTemplate);
-const redirectMock = jest.mocked(redirect);
+jest.mock('@molecules/SummaryChooseLetter/SummaryChooseLetter');
describe('PreviewBritishSignLanguageLetterTemplateFromMessagePlan page', () => {
- it('should redirect to the edit message plan page when lockNumber is invalid', async () => {
- await PreviewBritishSignLanguageLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: 'routing-config-id',
- templateId: 'template-id',
- }),
- searchParams: Promise.resolve({
- lockNumber: 'invalid',
- }),
- });
-
- expect(redirectMock).toHaveBeenCalledWith(
- '/message-plans/edit-message-plan/routing-config-id',
- 'replace'
- );
- });
-
- it('should redirect to the edit message plan page when lockNumber is missing', async () => {
- await PreviewBritishSignLanguageLetterTemplateFromMessagePlan({
+ it('should render SummaryChooseLetter with validateBritishSignLanguageLetterTemplate and redirectUrlOnLockNumberFailure', async () => {
+ const props = {
params: Promise.resolve({
routingConfigId: 'routing-config-id',
templateId: 'template-id',
}),
- searchParams: Promise.resolve({}),
- });
-
- expect(redirectMock).toHaveBeenCalledWith(
- '/message-plans/edit-message-plan/routing-config-id',
- 'replace'
+ searchParams: Promise.resolve({ lockNumber: '5' }),
+ };
+
+ const page =
+ await PreviewBritishSignLanguageLetterTemplateFromMessagePlan(props);
+
+ expect(page).toEqual(
+
);
});
- it('should redirect to invalid page for invalid template id', async () => {
- getTemplateMock.mockResolvedValueOnce(undefined);
-
- await PreviewBritishSignLanguageLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: 'routing-config-id',
- templateId: 'invalid-template-id',
- }),
- searchParams: Promise.resolve({
- lockNumber: '0',
- }),
- });
-
- expect(getTemplateMock).toHaveBeenCalledWith('invalid-template-id');
-
- expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
- });
-
- it('renders British Sign Language letter template preview', async () => {
- getTemplateMock.mockResolvedValueOnce({
- ...BSL_LETTER_TEMPLATE,
- templateStatus: 'SUBMITTED',
- });
-
- const page = await PreviewBritishSignLanguageLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: ROUTING_CONFIG.id,
- templateId: BSL_LETTER_TEMPLATE.id,
- }),
- searchParams: Promise.resolve({
- lockNumber: '5',
- }),
- });
-
- const container = render(page);
-
- expect(getTemplateMock).toHaveBeenCalledWith(BSL_LETTER_TEMPLATE.id);
-
+ it('should have the correct page title', async () => {
expect(await generateMetadata()).toEqual({
title: 'Preview British Sign Language letter template - NHS Notify',
});
- expect(container.asFragment()).toMatchSnapshot();
});
});
diff --git a/frontend/src/__tests__/app/message-plans/choose-large-print-letter-template/preview-template/__snapshots__/page.test.tsx.snap b/frontend/src/__tests__/app/message-plans/choose-large-print-letter-template/preview-template/__snapshots__/page.test.tsx.snap
deleted file mode 100644
index f2746d037..000000000
--- a/frontend/src/__tests__/app/message-plans/choose-large-print-letter-template/preview-template/__snapshots__/page.test.tsx.snap
+++ /dev/null
@@ -1,125 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`PreviewLargePrintLetterTemplateFromMessagePlan page renders large print letter template preview 1`] = `
-
-
-
- Go back
-
-
-
-
-
-
- Template
-
-
- large print letter template name
-
-
-
-
-
-
- Template ID
-
-
- large-print-letter-template-id
-
-
-
-
- Template type
-
-
- Large print letter
-
-
-
-
- Template file
-
-
-
-
-
-
-
- large-print-template.pdf
-
-
-
-
-
-
-
- Go back
-
-
-
-
-
-
-`;
diff --git a/frontend/src/__tests__/app/message-plans/choose-large-print-letter-template/preview-template/page.test.tsx b/frontend/src/__tests__/app/message-plans/choose-large-print-letter-template/preview-template/page.test.tsx
index 8614c9c24..c2cad0e6d 100644
--- a/frontend/src/__tests__/app/message-plans/choose-large-print-letter-template/preview-template/page.test.tsx
+++ b/frontend/src/__tests__/app/message-plans/choose-large-print-letter-template/preview-template/page.test.tsx
@@ -1,96 +1,38 @@
+/**
+ * @jest-environment node
+ */
import PreviewLargePrintLetterTemplateFromMessagePlan, {
generateMetadata,
} from '@app/message-plans/choose-large-print-letter-template/[routingConfigId]/preview-template/[templateId]/page';
-import {
- LARGE_PRINT_LETTER_TEMPLATE,
- ROUTING_CONFIG,
-} from '@testhelpers/helpers';
-import { render } from '@testing-library/react';
-import { getTemplate } from '@utils/form-actions';
-import { redirect } from 'next/navigation';
+import { SummaryChooseLetter } from '@molecules/SummaryChooseLetter/SummaryChooseLetter';
+import { validateLargePrintLetterTemplate } from 'nhs-notify-web-template-management-utils';
-jest.mock('@utils/form-actions');
-jest.mock('next/navigation');
-
-const getTemplateMock = jest.mocked(getTemplate);
-const redirectMock = jest.mocked(redirect);
+jest.mock('@molecules/SummaryChooseLetter/SummaryChooseLetter');
describe('PreviewLargePrintLetterTemplateFromMessagePlan page', () => {
- it('should redirect to the edit message plan page when lockNumber is invalid', async () => {
- await PreviewLargePrintLetterTemplateFromMessagePlan({
+ it('should render SummaryChooseLetter with validateLargePrintLetterTemplate and redirectUrlOnLockNumberFailure', async () => {
+ const props = {
params: Promise.resolve({
routingConfigId: 'routing-config-id',
templateId: 'template-id',
}),
- searchParams: Promise.resolve({
- lockNumber: 'invalid',
- }),
- });
-
- expect(redirectMock).toHaveBeenCalledWith(
- '/message-plans/edit-message-plan/routing-config-id',
- 'replace'
- );
- });
+ searchParams: Promise.resolve({ lockNumber: '5' }),
+ };
- it('should redirect to the edit message plan page when lockNumber is missing', async () => {
- await PreviewLargePrintLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: 'routing-config-id',
- templateId: 'template-id',
- }),
- searchParams: Promise.resolve({}),
- });
+ const page = await PreviewLargePrintLetterTemplateFromMessagePlan(props);
- expect(redirectMock).toHaveBeenCalledWith(
- '/message-plans/edit-message-plan/routing-config-id',
- 'replace'
+ expect(page).toEqual(
+
);
});
- it('should redirect to invalid page for invalid template id', async () => {
- getTemplateMock.mockResolvedValueOnce(undefined);
-
- await PreviewLargePrintLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: 'routing-config-id',
- templateId: 'invalid-template-id',
- }),
- searchParams: Promise.resolve({
- lockNumber: '0',
- }),
- });
-
- expect(getTemplateMock).toHaveBeenCalledWith('invalid-template-id');
-
- expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
- });
-
- it('renders large print letter template preview', async () => {
- getTemplateMock.mockResolvedValueOnce({
- ...LARGE_PRINT_LETTER_TEMPLATE,
- templateStatus: 'SUBMITTED',
- });
-
- const page = await PreviewLargePrintLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: ROUTING_CONFIG.id,
- templateId: LARGE_PRINT_LETTER_TEMPLATE.id,
- }),
- searchParams: Promise.resolve({
- lockNumber: '5',
- }),
- });
-
- const container = render(page);
-
- expect(getTemplateMock).toHaveBeenCalledWith(
- LARGE_PRINT_LETTER_TEMPLATE.id
- );
-
+ it('should have the correct page title', async () => {
expect(await generateMetadata()).toEqual({
title: 'Preview large print letter template - NHS Notify',
});
- expect(container.asFragment()).toMatchSnapshot();
});
});
diff --git a/frontend/src/__tests__/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/__snapshots__/page.test.tsx.snap b/frontend/src/__tests__/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/__snapshots__/page.test.tsx.snap
deleted file mode 100644
index 2ca062b54..000000000
--- a/frontend/src/__tests__/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/__snapshots__/page.test.tsx.snap
+++ /dev/null
@@ -1,125 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`PreviewOtherLanguageLetterTemplateFromMessagePlan page renders foreign language letter template preview 1`] = `
-
-
-
- Go back
-
-
-
-
-
-
- Template
-
-
- French letter template
-
-
-
-
-
-
- Template ID
-
-
- french-letter-id
-
-
-
-
- Template type
-
-
- Standard letter - French
-
-
-
-
- Template file
-
-
-
-
-
-
-
- template.pdf
-
-
-
-
-
-
-
- Go back
-
-
-
-
-
-
-`;
diff --git a/frontend/src/__tests__/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.test.tsx b/frontend/src/__tests__/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.test.tsx
index 37bd77a89..df207660f 100644
--- a/frontend/src/__tests__/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.test.tsx
+++ b/frontend/src/__tests__/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.test.tsx
@@ -1,99 +1,38 @@
+/**
+ * @jest-environment node
+ */
import PreviewOtherLanguageLetterTemplateFromMessagePlan, {
generateMetadata,
} from '@app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/page';
-import { PDF_LETTER_TEMPLATE, ROUTING_CONFIG } from '@testhelpers/helpers';
-import { render } from '@testing-library/react';
-import { getTemplate } from '@utils/form-actions';
-import { redirect } from 'next/navigation';
-import { Language } from 'nhs-notify-web-template-management-types';
+import { SummaryChooseLetter } from '@molecules/SummaryChooseLetter/SummaryChooseLetter';
+import { validateForeignLanguageLetterTemplate } from 'nhs-notify-web-template-management-utils';
-jest.mock('@utils/form-actions');
-jest.mock('next/navigation');
-
-const getTemplateMock = jest.mocked(getTemplate);
-const redirectMock = jest.mocked(redirect);
-
-const FRENCH_LETTER_TEMPLATE = {
- ...PDF_LETTER_TEMPLATE,
- id: 'french-letter-id',
- name: 'French letter template',
- language: 'fr' as Language,
-};
+jest.mock('@molecules/SummaryChooseLetter/SummaryChooseLetter');
describe('PreviewOtherLanguageLetterTemplateFromMessagePlan page', () => {
- it('should redirect to the edit message plan page when lockNumber is invalid', async () => {
- await PreviewOtherLanguageLetterTemplateFromMessagePlan({
+ it('should render SummaryChooseLetter with validateForeignLanguageLetterTemplate and redirectUrlOnLockNumberFailure', async () => {
+ const props = {
params: Promise.resolve({
routingConfigId: 'routing-config-id',
templateId: 'template-id',
}),
- searchParams: Promise.resolve({
- lockNumber: 'invalid',
- }),
- });
+ searchParams: Promise.resolve({ lockNumber: '5' }),
+ };
- expect(redirectMock).toHaveBeenCalledWith(
- '/message-plans/edit-message-plan/routing-config-id',
- 'replace'
- );
- });
-
- it('should redirect to the edit message plan page when lockNumber is missing', async () => {
- await PreviewOtherLanguageLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: 'routing-config-id',
- templateId: 'template-id',
- }),
- searchParams: Promise.resolve({}),
- });
+ const page = await PreviewOtherLanguageLetterTemplateFromMessagePlan(props);
- expect(redirectMock).toHaveBeenCalledWith(
- '/message-plans/edit-message-plan/routing-config-id',
- 'replace'
+ expect(page).toEqual(
+
);
});
- it('should redirect to invalid page with invalid template id', async () => {
- getTemplateMock.mockResolvedValueOnce(undefined);
-
- await PreviewOtherLanguageLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: 'routing-config-id',
- templateId: 'invalid-template-id',
- }),
- searchParams: Promise.resolve({
- lockNumber: '0',
- }),
- });
-
- expect(getTemplateMock).toHaveBeenCalledWith('invalid-template-id');
-
- expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
- });
-
- it('renders foreign language letter template preview', async () => {
- getTemplateMock.mockResolvedValueOnce({
- ...FRENCH_LETTER_TEMPLATE,
- templateStatus: 'SUBMITTED',
- });
-
- const page = await PreviewOtherLanguageLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: ROUTING_CONFIG.id,
- templateId: FRENCH_LETTER_TEMPLATE.id,
- }),
- searchParams: Promise.resolve({
- lockNumber: '5',
- }),
- });
-
- const container = render(page);
-
- expect(getTemplateMock).toHaveBeenCalledWith(FRENCH_LETTER_TEMPLATE.id);
-
+ it('should have the correct page title', async () => {
expect(await generateMetadata()).toEqual({
title: 'Preview other language letter template - NHS Notify',
});
- expect(container.asFragment()).toMatchSnapshot();
});
});
diff --git a/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/__snapshots__/page.test.tsx.snap b/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/__snapshots__/page.test.tsx.snap
index 149ec95f3..a2d4fb717 100644
--- a/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/__snapshots__/page.test.tsx.snap
+++ b/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/__snapshots__/page.test.tsx.snap
@@ -66,7 +66,7 @@ exports[`ChooseStandardEnglishLetterTemplate page renders letter template select
- letter template name
+ authoring letter template name
@@ -156,19 +156,19 @@ exports[`ChooseStandardEnglishLetterTemplate page renders letter template select
class="nhsuk-radios__item"
>
@@ -176,7 +176,7 @@ exports[`ChooseStandardEnglishLetterTemplate page renders letter template select
Name
- letter template name
+ authoring letter template name
Preview
diff --git a/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/page.test.tsx b/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/page.test.tsx
index 83ef9b8cf..cf5c4c03a 100644
--- a/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/page.test.tsx
+++ b/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/page.test.tsx
@@ -1,7 +1,10 @@
import ChooseStandardEnglishLetterTemplate, {
generateMetadata,
} from '@app/message-plans/choose-standard-english-letter-template/[routingConfigId]/page';
-import { PDF_LETTER_TEMPLATE, ROUTING_CONFIG } from '@testhelpers/helpers';
+import {
+ AUTHORING_LETTER_TEMPLATE,
+ ROUTING_CONFIG,
+} from '@testhelpers/helpers';
import { render } from '@testing-library/react';
import { getTemplates } from '@utils/form-actions';
import { getRoutingConfig } from '@utils/message-plans';
@@ -63,7 +66,9 @@ describe('ChooseStandardEnglishLetterTemplate page', () => {
it('renders letter template selection', async () => {
getRoutingConfigMock.mockResolvedValueOnce(ROUTING_CONFIG);
- getTemplatesMock.mockResolvedValueOnce([PDF_LETTER_TEMPLATE]);
+ getTemplatesMock.mockResolvedValueOnce([
+ { ...AUTHORING_LETTER_TEMPLATE, templateStatus: 'PROOF_APPROVED' },
+ ]);
const page = await ChooseStandardEnglishLetterTemplate({
params: Promise.resolve({
diff --git a/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/preview-template/__snapshots__/page.test.tsx.snap b/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/preview-template/__snapshots__/page.test.tsx.snap
deleted file mode 100644
index d5b6d634d..000000000
--- a/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/preview-template/__snapshots__/page.test.tsx.snap
+++ /dev/null
@@ -1,125 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`PreviewStandardEnglishLetterTemplateFromMessagePlan page renders letter template preview 1`] = `
-
-
-
- Go back
-
-
-
-
-
-
- Template
-
-
- letter template name
-
-
-
-
-
-
- Template ID
-
-
- letter-template-id
-
-
-
-
- Template type
-
-
- Standard letter
-
-
-
-
- Template file
-
-
-
-
-
-
-
- template.pdf
-
-
-
-
-
-
-
- Go back
-
-
-
-
-
-
-`;
diff --git a/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/preview-template/page.test.tsx b/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/preview-template/page.test.tsx
index 935298bc7..47616be14 100644
--- a/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/preview-template/page.test.tsx
+++ b/frontend/src/__tests__/app/message-plans/choose-standard-english-letter-template/preview-template/page.test.tsx
@@ -1,91 +1,39 @@
+/**
+ * @jest-environment node
+ */
import PreviewStandardEnglishLetterTemplateFromMessagePlan, {
generateMetadata,
} from '@app/message-plans/choose-standard-english-letter-template/[routingConfigId]/preview-template/[templateId]/page';
-import { PDF_LETTER_TEMPLATE, ROUTING_CONFIG } from '@testhelpers/helpers';
-import { render } from '@testing-library/react';
-import { getTemplate } from '@utils/form-actions';
-import { redirect } from 'next/navigation';
+import { SummaryChooseLetter } from '@molecules/SummaryChooseLetter/SummaryChooseLetter';
+import { validateLetterTemplate } from 'nhs-notify-web-template-management-utils';
-jest.mock('@utils/form-actions');
-jest.mock('next/navigation');
-
-const getTemplateMock = jest.mocked(getTemplate);
-const redirectMock = jest.mocked(redirect);
+jest.mock('@molecules/SummaryChooseLetter/SummaryChooseLetter');
describe('PreviewStandardEnglishLetterTemplateFromMessagePlan page', () => {
- it('should redirect to the edit message plan page when lockNumber is invalid', async () => {
- await PreviewStandardEnglishLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: 'routing-config-id',
- templateId: 'template-id',
- }),
- searchParams: Promise.resolve({
- lockNumber: 'invalid',
- }),
- });
-
- expect(redirectMock).toHaveBeenCalledWith(
- '/message-plans/edit-message-plan/routing-config-id',
- 'replace'
- );
- });
-
- it('should redirect to the edit message plan page when lockNumber is missing', async () => {
- await PreviewStandardEnglishLetterTemplateFromMessagePlan({
+ it('should render SummaryChooseLetter with validateLetterTemplate and redirectUrlOnLockNumberFailure', async () => {
+ const props = {
params: Promise.resolve({
routingConfigId: 'routing-config-id',
templateId: 'template-id',
}),
- searchParams: Promise.resolve({}),
- });
-
- expect(redirectMock).toHaveBeenCalledWith(
- '/message-plans/edit-message-plan/routing-config-id',
- 'replace'
+ searchParams: Promise.resolve({ lockNumber: '5' }),
+ };
+
+ const page =
+ await PreviewStandardEnglishLetterTemplateFromMessagePlan(props);
+
+ expect(page).toEqual(
+
);
});
- it('should redirect to invalid page with invalid template id', async () => {
- getTemplateMock.mockResolvedValueOnce(undefined);
-
- await PreviewStandardEnglishLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: 'routing-config-id',
- templateId: 'invalid-template-id',
- }),
- searchParams: Promise.resolve({
- lockNumber: '0',
- }),
- });
-
- expect(getTemplateMock).toHaveBeenCalledWith('invalid-template-id');
-
- expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
- });
-
- it('renders letter template preview', async () => {
- getTemplateMock.mockResolvedValueOnce({
- ...PDF_LETTER_TEMPLATE,
- templateStatus: 'SUBMITTED',
- });
-
- const page = await PreviewStandardEnglishLetterTemplateFromMessagePlan({
- params: Promise.resolve({
- routingConfigId: ROUTING_CONFIG.id,
- templateId: PDF_LETTER_TEMPLATE.id,
- }),
- searchParams: Promise.resolve({
- lockNumber: '5',
- }),
- });
-
- const container = render(page);
-
- expect(getTemplateMock).toHaveBeenCalledWith(PDF_LETTER_TEMPLATE.id);
-
+ it('should have the correct page title', async () => {
expect(await generateMetadata()).toEqual({
title: 'Preview letter template - NHS Notify',
});
- expect(container.asFragment()).toMatchSnapshot();
});
});
diff --git a/frontend/src/__tests__/app/message-plans/preview-message-plan/__snapshots__/page.test.tsx.snap b/frontend/src/__tests__/app/message-plans/preview-message-plan/__snapshots__/page.test.tsx.snap
index fdf1e126c..6cf6ce8e7 100644
--- a/frontend/src/__tests__/app/message-plans/preview-message-plan/__snapshots__/page.test.tsx.snap
+++ b/frontend/src/__tests__/app/message-plans/preview-message-plan/__snapshots__/page.test.tsx.snap
@@ -101,7 +101,7 @@ exports[`full cascade plan matches snapshot 1`] = `
class="nhsuk-button nhsuk-button--secondary"
type="button"
>
- Open all template previews
+ Open all digital template previews
-
- letter template name
-
+ authoring letter template name
+
+ Preview template (opens in a new tab)
+
-
- large print letter template name
-
+ large print letter template name
+
+ Preview template (opens in a new tab)
+
@@ -747,12 +753,15 @@ exports[`full cascade plan matches snapshot 1`] = `
-
- British Sign Language letter template name
-
+ British Sign Language letter template name
+
+ Preview template (opens in a new tab)
+
@@ -773,25 +782,31 @@ exports[`full cascade plan matches snapshot 1`] = `
Other language letters (optional)
-
- letter template name
-
+ authoring letter template name
-
+ Preview template (opens in a new tab)
+
+
-
- letter template name
-
+ authoring letter template name
+
+ Preview template (opens in a new tab)
+
diff --git a/frontend/src/__tests__/app/message-plans/preview-message-plan/page.test.tsx b/frontend/src/__tests__/app/message-plans/preview-message-plan/page.test.tsx
index ec02b9b40..263c4b0eb 100644
--- a/frontend/src/__tests__/app/message-plans/preview-message-plan/page.test.tsx
+++ b/frontend/src/__tests__/app/message-plans/preview-message-plan/page.test.tsx
@@ -10,11 +10,11 @@ import {
ORDINALS,
} from 'nhs-notify-web-template-management-utils';
import {
+ AUTHORING_LETTER_TEMPLATE,
BSL_LETTER_TEMPLATE,
EMAIL_TEMPLATE,
LARGE_PRINT_LETTER_TEMPLATE,
NHS_APP_TEMPLATE,
- PDF_LETTER_TEMPLATE,
SMS_TEMPLATE,
} from '@testhelpers/helpers';
import { RoutingConfigFactory } from '@testhelpers/routing-config-factory';
@@ -77,17 +77,17 @@ const templates: MessagePlanTemplates = {
templateStatus: 'SUBMITTED',
},
[letterTemplateId]: {
- ...PDF_LETTER_TEMPLATE,
+ ...AUTHORING_LETTER_TEMPLATE,
id: letterTemplateId,
templateStatus: 'SUBMITTED',
},
[kuTemplateId]: {
- ...PDF_LETTER_TEMPLATE,
+ ...AUTHORING_LETTER_TEMPLATE,
id: kuTemplateId,
templateStatus: 'SUBMITTED',
},
[sqTemplateId]: {
- ...PDF_LETTER_TEMPLATE,
+ ...AUTHORING_LETTER_TEMPLATE,
id: sqTemplateId,
templateStatus: 'SUBMITTED',
},
@@ -249,7 +249,7 @@ describe('full cascade plan', () => {
await renderPage(routingConfig);
const button = screen.getByRole('button', {
- name: 'Open all template previews',
+ name: 'Open all digital template previews',
});
const detailsSections = screen
@@ -262,7 +262,7 @@ describe('full cascade plan', () => {
await user.click(button);
- expect(button).toHaveTextContent('Close all template previews');
+ expect(button).toHaveTextContent('Close all digital template previews');
for (const section of detailsSections) {
expect(section.open).toBe(true);
@@ -270,7 +270,7 @@ describe('full cascade plan', () => {
await user.click(button);
- expect(button).toHaveTextContent('Open all template previews');
+ expect(button).toHaveTextContent('Open all digital template previews');
for (const section of detailsSections) {
expect(section.open).toBe(false);
@@ -366,7 +366,7 @@ describe('letter only', () => {
expect(
screen.queryByRole('button', {
- name: 'Open all template previews',
+ name: 'Open all digital template previews',
})
).not.toBeInTheDocument();
@@ -374,15 +374,21 @@ describe('letter only', () => {
const card = within(block).getByTestId('channel-card');
+ const name = within(card).getByTestId('template-name');
+
+ expect(name).toHaveTextContent(template.name);
+
const link = within(card).getByRole('link');
- expect(link).toHaveTextContent(template.name);
+ expect(link).toHaveTextContent('Preview template (opens in a new tab)');
expect(link).toHaveAttribute(
'href',
- `/preview-submitted-letter-template/${template.id}`
+ `/message-plans/preview-message-plan/${routingConfig.id}/preview-template/${template.id}`
);
+ expect(link).toHaveAttribute('target', '_blank');
+
expect(
within(block).queryByTestId('conditional-templates')
).not.toBeInTheDocument();
@@ -423,14 +429,20 @@ describe('letter only', () => {
within(conditionalTemplatesList).getByTestId('conditional-template-x1')
).getByTestId('channel-card');
+ const name = within(largePrintCard).getByTestId('template-name');
+
+ expect(name).toHaveTextContent(template.name);
+
const link = within(largePrintCard).getByRole('link');
- expect(link).toHaveTextContent(template.name);
+ expect(link).toHaveTextContent('Preview template (opens in a new tab)');
expect(link).toHaveAttribute(
'href',
- `/preview-submitted-letter-template/${template.id}`
+ `/message-plans/preview-message-plan/${routingConfig.id}/preview-template/${template.id}`
);
+
+ expect(link).toHaveAttribute('target', '_blank');
});
it('shows the fallback conditions and card for BSL accessible format', async () => {
@@ -468,14 +480,20 @@ describe('letter only', () => {
within(conditionalTemplatesList).getByTestId('conditional-template-q4')
).getByTestId('channel-card');
+ const name = within(bslCard).getByTestId('template-name');
+
+ expect(name).toHaveTextContent(template.name);
+
const link = within(bslCard).getByRole('link');
- expect(link).toHaveTextContent(template.name);
+ expect(link).toHaveTextContent('Preview template (opens in a new tab)');
expect(link).toHaveAttribute(
'href',
- `/preview-submitted-letter-template/${template.id}`
+ `/message-plans/preview-message-plan/${routingConfig.id}/preview-template/${template.id}`
);
+
+ expect(link).toHaveAttribute('target', '_blank');
});
it('shows the card for the other language templates', async () => {
@@ -515,8 +533,10 @@ describe('letter only', () => {
).getByTestId('channel-card');
const links = within(languagesCard).getAllByRole('link');
+ const names = within(languagesCard).getAllByTestId('template-name');
expect(links).toHaveLength(2);
+ expect(names).toHaveLength(2);
for (const [
index,
@@ -524,12 +544,17 @@ describe('letter only', () => {
] of routingConfig.cascade[0].conditionalTemplates!.entries()) {
const template = templates[templateId!];
- expect(links[index]).toHaveTextContent(template.name);
+ expect(names[index]).toHaveTextContent(template.name);
+ expect(links[index]).toHaveTextContent(
+ 'Preview template (opens in a new tab)'
+ );
expect(links[index]).toHaveAttribute(
'href',
- `/preview-submitted-letter-template/${template.id}`
+ `/message-plans/preview-message-plan/${routingConfig.id}/preview-template/${template.id}`
);
+
+ expect(links[index]).toHaveAttribute('target', '_blank');
}
});
});
diff --git a/frontend/src/__tests__/app/message-plans/preview-message-plan/preview-template/page.test.tsx b/frontend/src/__tests__/app/message-plans/preview-message-plan/preview-template/page.test.tsx
new file mode 100644
index 000000000..c07309d1b
--- /dev/null
+++ b/frontend/src/__tests__/app/message-plans/preview-message-plan/preview-template/page.test.tsx
@@ -0,0 +1,32 @@
+/**
+ * @jest-environment node
+ */
+import PreviewLetterTemplateFromPreviewMessagePlan, {
+ generateMetadata,
+} from '@app/message-plans/preview-message-plan/[routingConfigId]/preview-template/[templateId]/page';
+import { SummaryLetterFromMessagePlan } from '@molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan';
+
+jest.mock(
+ '@molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan'
+);
+
+describe('PreviewLetterTemplateFromPreviewMessagePlan page', () => {
+ it('should render SummaryLetterFromMessagePlan with authoring letter validator', async () => {
+ const props = {
+ params: Promise.resolve({
+ routingConfigId: 'routing-config-id',
+ templateId: 'template-id',
+ }),
+ };
+
+ const page = await PreviewLetterTemplateFromPreviewMessagePlan(props);
+
+ expect(page).toEqual( );
+ });
+
+ it('should have the correct page title', async () => {
+ expect(await generateMetadata()).toEqual({
+ title: 'Preview letter template - NHS Notify',
+ });
+ });
+});
diff --git a/frontend/src/__tests__/app/message-plans/review-and-move-to-production/__snapshots__/page.test.tsx.snap b/frontend/src/__tests__/app/message-plans/review-and-move-to-production/__snapshots__/page.test.tsx.snap
index 40a309c19..e9ea3c67c 100644
--- a/frontend/src/__tests__/app/message-plans/review-and-move-to-production/__snapshots__/page.test.tsx.snap
+++ b/frontend/src/__tests__/app/message-plans/review-and-move-to-production/__snapshots__/page.test.tsx.snap
@@ -52,7 +52,7 @@ exports[`Review and move to production page matches snapshot for full cascade 1`
class="nhsuk-button nhsuk-button--secondary"
type="button"
>
- Open all template previews
+ Open all digital template previews
-
- letter template name
-
+ authoring letter template name
+
+ Preview template (opens in a new tab)
+
-
- large print letter template name
-
+ large print letter template name
+
+ Preview template (opens in a new tab)
+
@@ -698,12 +704,15 @@ exports[`Review and move to production page matches snapshot for full cascade 1`
-
- British Sign Language letter template name
-
+ British Sign Language letter template name
+
+ Preview template (opens in a new tab)
+
@@ -724,25 +733,31 @@ exports[`Review and move to production page matches snapshot for full cascade 1`
Other language letters (optional)
-
- letter template name
-
+ authoring letter template name
-
+ Preview template (opens in a new tab)
+
+
-
- letter template name
-
+ authoring letter template name
+
+ Preview template (opens in a new tab)
+
diff --git a/frontend/src/__tests__/app/message-plans/review-and-move-to-production/page.test.tsx b/frontend/src/__tests__/app/message-plans/review-and-move-to-production/page.test.tsx
index 23bfd7275..adf61dbb4 100644
--- a/frontend/src/__tests__/app/message-plans/review-and-move-to-production/page.test.tsx
+++ b/frontend/src/__tests__/app/message-plans/review-and-move-to-production/page.test.tsx
@@ -9,8 +9,8 @@ import {
EMAIL_TEMPLATE,
LARGE_PRINT_LETTER_TEMPLATE,
NHS_APP_TEMPLATE,
- PDF_LETTER_TEMPLATE,
SMS_TEMPLATE,
+ AUTHORING_LETTER_TEMPLATE,
} from '@testhelpers/helpers';
import { RoutingConfigFactory } from '@testhelpers/routing-config-factory';
import {
@@ -67,9 +67,21 @@ const templates: MessagePlanTemplates = {
[appTemplateId]: { ...NHS_APP_TEMPLATE, id: appTemplateId },
[emailTemplateId]: { ...EMAIL_TEMPLATE, id: emailTemplateId },
[smsTemplateId]: { ...SMS_TEMPLATE, id: smsTemplateId },
- [letterTemplateId]: { ...PDF_LETTER_TEMPLATE, id: letterTemplateId },
- [kuTemplateId]: { ...PDF_LETTER_TEMPLATE, id: kuTemplateId },
- [sqTemplateId]: { ...PDF_LETTER_TEMPLATE, id: sqTemplateId },
+ [letterTemplateId]: {
+ ...AUTHORING_LETTER_TEMPLATE,
+ id: letterTemplateId,
+ templateStatus: 'PROOF_APPROVED',
+ },
+ [kuTemplateId]: {
+ ...AUTHORING_LETTER_TEMPLATE,
+ id: kuTemplateId,
+ templateStatus: 'PROOF_APPROVED',
+ },
+ [sqTemplateId]: {
+ ...AUTHORING_LETTER_TEMPLATE,
+ id: sqTemplateId,
+ templateStatus: 'PROOF_APPROVED',
+ },
[largePrintTemplateId]: {
...LARGE_PRINT_LETTER_TEMPLATE,
id: largePrintTemplateId,
@@ -263,7 +275,9 @@ describe('Review and move to production page', () => {
await renderPage(routingConfig);
expect(
- screen.getByRole('button', { name: /open all template previews/i })
+ screen.getByRole('button', {
+ name: /open all digital template previews/i,
+ })
).toBeInTheDocument();
});
@@ -282,7 +296,9 @@ describe('Review and move to production page', () => {
await renderPage(routingConfig);
expect(
- screen.queryByRole('button', { name: /open all template previews/i })
+ screen.queryByRole('button', {
+ name: /open all digital template previews/i,
+ })
).not.toBeInTheDocument();
});
@@ -309,7 +325,7 @@ describe('Review and move to production page', () => {
).toBeInTheDocument();
});
- it('renders letter template as link', async () => {
+ it('renders letter templates with a link', async () => {
const routingConfig = createRoutingConfig({
cascade: [
{
@@ -325,13 +341,16 @@ describe('Review and move to production page', () => {
const block = screen.getByTestId('message-plan-block-LETTER');
const templateName = within(block).getByTestId('template-name');
- const link = within(templateName).getByRole('link');
- expect(link).toHaveTextContent(templates[letterTemplateId].name);
+ expect(templateName).toHaveTextContent(templates[letterTemplateId].name);
+
+ const link = within(block).getByRole('link');
+ expect(link).toHaveTextContent('Preview template (opens in a new tab)');
expect(link).toHaveAttribute(
'href',
- `/preview-letter-template/${letterTemplateId}`
+ `/message-plans/review-and-move-to-production/${routingConfig.id}/preview-template/${letterTemplateId}`
);
+ expect(link).toHaveAttribute('target', '_blank');
});
it('renders fallback conditions between channels', async () => {
diff --git a/frontend/src/__tests__/app/message-plans/review-and-move-to-production/preview-template/page.test.tsx b/frontend/src/__tests__/app/message-plans/review-and-move-to-production/preview-template/page.test.tsx
new file mode 100644
index 000000000..b2efe15e2
--- /dev/null
+++ b/frontend/src/__tests__/app/message-plans/review-and-move-to-production/preview-template/page.test.tsx
@@ -0,0 +1,33 @@
+/**
+ * @jest-environment node
+ */
+import PreviewLetterTemplateFromReviewAndMoveToProduction, {
+ generateMetadata,
+} from '@app/message-plans/review-and-move-to-production/[routingConfigId]/preview-template/[templateId]/page';
+import { SummaryLetterFromMessagePlan } from '@molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan';
+
+jest.mock(
+ '@molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan'
+);
+
+describe('PreviewLetterTemplateFromReviewAndMoveToProduction page', () => {
+ it('should render SummaryLetterFromMessagePlan with authoring letter validator', async () => {
+ const props = {
+ params: Promise.resolve({
+ routingConfigId: 'routing-config-id',
+ templateId: 'template-id',
+ }),
+ };
+
+ const page =
+ await PreviewLetterTemplateFromReviewAndMoveToProduction(props);
+
+ expect(page).toEqual( );
+ });
+
+ it('should have the correct page title', async () => {
+ expect(await generateMetadata()).toEqual({
+ title: 'Preview letter template - NHS Notify',
+ });
+ });
+});
diff --git a/frontend/src/__tests__/app/review-and-approve-letter-template/__snapshots__/page.test.tsx.snap b/frontend/src/__tests__/app/review-and-approve-letter-template/__snapshots__/page.test.tsx.snap
index 8d1b454d9..074365a3a 100644
--- a/frontend/src/__tests__/app/review-and-approve-letter-template/__snapshots__/page.test.tsx.snap
+++ b/frontend/src/__tests__/app/review-and-approve-letter-template/__snapshots__/page.test.tsx.snap
@@ -169,7 +169,7 @@ exports[`valid authoring letter template matches snapshot 1`] = `
@@ -180,7 +180,7 @@ exports[`valid authoring letter template matches snapshot 1`] = `
diff --git a/frontend/src/__tests__/components/forms/ChooseChannelTemplate/ChooseChannelTemplate.test.tsx b/frontend/src/__tests__/components/forms/ChooseChannelTemplate/ChooseChannelTemplate.test.tsx
index c6ceaa8e6..118b4b814 100644
--- a/frontend/src/__tests__/components/forms/ChooseChannelTemplate/ChooseChannelTemplate.test.tsx
+++ b/frontend/src/__tests__/components/forms/ChooseChannelTemplate/ChooseChannelTemplate.test.tsx
@@ -1,9 +1,9 @@
import { ChooseChannelTemplate } from '@forms/ChooseChannelTemplate';
import { fireEvent, render, screen, within } from '@testing-library/react';
import {
+ AUTHORING_LETTER_TEMPLATE,
EMAIL_TEMPLATE,
LARGE_PRINT_LETTER_TEMPLATE,
- PDF_LETTER_TEMPLATE,
NHS_APP_TEMPLATE,
ROUTING_CONFIG,
SMS_TEMPLATE,
@@ -97,12 +97,16 @@ const propsByChannel = {
LETTER: {
pageHeading: 'Choose a letter template',
cascadeIndex: 3,
- templateList: [PDF_LETTER_TEMPLATE],
+ templateList: [
+ { ...AUTHORING_LETTER_TEMPLATE, templateStatus: 'PROOF_APPROVED' },
+ ],
},
LARGE_PRINT_LETTER: {
pageHeading: 'Choose a large print letter template',
cascadeIndex: 3,
- templateList: [LARGE_PRINT_LETTER_TEMPLATE],
+ templateList: [
+ { ...LARGE_PRINT_LETTER_TEMPLATE, templateStatus: 'SUBMITTED' },
+ ],
accessibleFormat: 'x1',
},
};
diff --git a/frontend/src/__tests__/components/forms/ChooseChannelTemplate/__snapshots__/ChooseChannelTemplate.test.tsx.snap b/frontend/src/__tests__/components/forms/ChooseChannelTemplate/__snapshots__/ChooseChannelTemplate.test.tsx.snap
index c627c8974..bfeebca33 100644
--- a/frontend/src/__tests__/components/forms/ChooseChannelTemplate/__snapshots__/ChooseChannelTemplate.test.tsx.snap
+++ b/frontend/src/__tests__/components/forms/ChooseChannelTemplate/__snapshots__/ChooseChannelTemplate.test.tsx.snap
@@ -1808,7 +1808,7 @@ exports[`ChooseChannelTemplate renders letter form 1`] = `
- letter template name
+ authoring letter template name
@@ -1898,19 +1898,19 @@ exports[`ChooseChannelTemplate renders letter form 1`] = `
class="nhsuk-radios__item"
>
@@ -1918,7 +1918,7 @@ exports[`ChooseChannelTemplate renders letter form 1`] = `
Name
- letter template name
+ authoring letter template name
Preview
diff --git a/frontend/src/__tests__/components/molecules/LetterRender/LetterRenderIframe.test.tsx b/frontend/src/__tests__/components/molecules/LetterRender/LetterRenderIframe.test.tsx
index df4c3619f..a9165afb0 100644
--- a/frontend/src/__tests__/components/molecules/LetterRender/LetterRenderIframe.test.tsx
+++ b/frontend/src/__tests__/components/molecules/LetterRender/LetterRenderIframe.test.tsx
@@ -6,7 +6,7 @@ describe('LetterRenderIframe', () => {
it('renders iframe with provided pdfUrl', () => {
render(
);
@@ -22,7 +22,7 @@ describe('LetterRenderIframe', () => {
it('adds additional props', () => {
render(
@@ -34,7 +34,9 @@ describe('LetterRenderIframe', () => {
});
it('renders correct title for short tab', () => {
- render( );
+ render(
+
+ );
expect(
screen.getByTitle('Letter preview - short examples')
@@ -42,17 +44,32 @@ describe('LetterRenderIframe', () => {
});
it('renders correct title for long tab', () => {
- render( );
+ render(
+
+ );
expect(
screen.getByTitle('Letter preview - long examples')
).toBeInTheDocument();
});
+
+ it('renders correct title and aria-label for initialRender', () => {
+ render(
+
+ );
+
+ const iframe = screen.getByTitle('Letter preview');
+ expect(iframe).toBeInTheDocument();
+ expect(iframe).toHaveAttribute(
+ 'aria-label',
+ 'PDF preview of letter template'
+ );
+ });
});
describe('missing file handling', () => {
it('shows message when pdfUrl is null', () => {
- render( );
+ render( );
expect(screen.getByText('No preview available')).toBeInTheDocument();
@@ -66,7 +83,7 @@ describe('LetterRenderIframe', () => {
it('matches snapshot with PDF URL', () => {
const container = render(
);
@@ -76,7 +93,7 @@ describe('LetterRenderIframe', () => {
it('matches snapshot without PDF file', () => {
const container = render(
-
+
);
expect(container.asFragment()).toMatchSnapshot();
diff --git a/frontend/src/__tests__/components/molecules/MessagePlanCascadePreview.test.tsx b/frontend/src/__tests__/components/molecules/MessagePlanCascadePreview.test.tsx
index ac744ac66..6ba782925 100644
--- a/frontend/src/__tests__/components/molecules/MessagePlanCascadePreview.test.tsx
+++ b/frontend/src/__tests__/components/molecules/MessagePlanCascadePreview.test.tsx
@@ -1,19 +1,25 @@
import { render, screen } from '@testing-library/react';
import { MessagePlanCascadePreview } from '@molecules/MessagePlanCascadePreview/MessagePlanCascadePreview';
import {
+ AUTHORING_LETTER_TEMPLATE,
EMAIL_TEMPLATE,
NHS_APP_TEMPLATE,
- PDF_LETTER_TEMPLATE,
ROUTING_CONFIG,
SMS_TEMPLATE,
} from '@testhelpers/helpers';
+import { AuthoringLetterTemplate } from 'nhs-notify-web-template-management-utils';
+
+const APPROVED_LETTER: AuthoringLetterTemplate = {
+ ...AUTHORING_LETTER_TEMPLATE,
+ templateStatus: 'PROOF_APPROVED',
+};
describe('MessagePlanCascadePreview', () => {
const templates = {
[NHS_APP_TEMPLATE.id]: NHS_APP_TEMPLATE,
[EMAIL_TEMPLATE.id]: EMAIL_TEMPLATE,
[SMS_TEMPLATE.id]: SMS_TEMPLATE,
- [PDF_LETTER_TEMPLATE.id]: PDF_LETTER_TEMPLATE,
+ [APPROVED_LETTER.id]: APPROVED_LETTER,
};
it('renders cascade preview with all channels', () => {
@@ -21,6 +27,7 @@ describe('MessagePlanCascadePreview', () => {
);
@@ -36,6 +43,7 @@ describe('MessagePlanCascadePreview', () => {
);
@@ -44,7 +52,7 @@ describe('MessagePlanCascadePreview', () => {
expect(templateNames[0]).toHaveTextContent(NHS_APP_TEMPLATE.name);
expect(templateNames[1]).toHaveTextContent(EMAIL_TEMPLATE.name);
expect(templateNames[2]).toHaveTextContent(SMS_TEMPLATE.name);
- expect(templateNames[3]).toHaveTextContent(PDF_LETTER_TEMPLATE.name);
+ expect(templateNames[3]).toHaveTextContent(APPROVED_LETTER.name);
});
it('renders open/close all previews button when non-letter channels present', () => {
@@ -52,11 +60,14 @@ describe('MessagePlanCascadePreview', () => {
);
expect(
- screen.getByRole('button', { name: 'Open all template previews' })
+ screen.getByRole('button', {
+ name: 'Open all digital template previews',
+ })
).toBeInTheDocument();
});
@@ -68,7 +79,7 @@ describe('MessagePlanCascadePreview', () => {
cascadeGroups: ['standard' as const],
channel: 'LETTER' as const,
channelType: 'primary' as const,
- defaultTemplateId: PDF_LETTER_TEMPLATE.id,
+ defaultTemplateId: APPROVED_LETTER.id,
},
],
};
@@ -77,6 +88,7 @@ describe('MessagePlanCascadePreview', () => {
);
@@ -90,6 +102,7 @@ describe('MessagePlanCascadePreview', () => {
);
@@ -121,6 +134,7 @@ describe('MessagePlanCascadePreview', () => {
);
@@ -129,11 +143,12 @@ describe('MessagePlanCascadePreview', () => {
).not.toBeInTheDocument();
});
- it('renders letter template as link', () => {
+ it('renders letter template with link using letterPreviewHrefBase prop', () => {
render(
);
@@ -141,43 +156,10 @@ describe('MessagePlanCascadePreview', () => {
const link = letterBlock.querySelector('a');
expect(link).toHaveAttribute(
'href',
- `/preview-letter-template/${PDF_LETTER_TEMPLATE.id}`
- );
- expect(link).toHaveTextContent(PDF_LETTER_TEMPLATE.name);
- });
-
- it('renders submitted letter template with submitted link', () => {
- const submittedTemplate = {
- ...PDF_LETTER_TEMPLATE,
- id: 'submitted-letter-id',
- templateStatus: 'SUBMITTED' as const,
- };
- const templatesWithSubmitted = {
- ...templates,
- [submittedTemplate.id]: submittedTemplate,
- };
- const routingConfigWithSubmitted = {
- ...ROUTING_CONFIG,
- cascade: ROUTING_CONFIG.cascade.map((item) =>
- item.channel === 'LETTER'
- ? { ...item, defaultTemplateId: submittedTemplate.id }
- : item
- ),
- };
-
- render(
-
- );
-
- const letterBlock = screen.getByTestId('message-plan-block-LETTER');
- const link = letterBlock.querySelector('a');
- expect(link).toHaveAttribute(
- 'href',
- `/preview-submitted-letter-template/${submittedTemplate.id}`
+ `/base-url/preview-template/${APPROVED_LETTER.id}`
);
+ expect(link).toHaveAttribute('target', '_blank');
+ expect(link).toHaveTextContent('Preview template (opens in a new tab)');
});
it('renders non-letter templates with preview details', () => {
@@ -185,6 +167,7 @@ describe('MessagePlanCascadePreview', () => {
);
@@ -197,13 +180,14 @@ describe('MessagePlanCascadePreview', () => {
[NHS_APP_TEMPLATE.id]: NHS_APP_TEMPLATE,
// EMAIL_TEMPLATE is missing
[SMS_TEMPLATE.id]: SMS_TEMPLATE,
- [PDF_LETTER_TEMPLATE.id]: PDF_LETTER_TEMPLATE,
+ [APPROVED_LETTER.id]: APPROVED_LETTER,
};
render(
);
@@ -220,6 +204,7 @@ describe('MessagePlanCascadePreview', () => {
);
diff --git a/frontend/src/__tests__/components/molecules/PreviewTemplateDetails.test.tsx b/frontend/src/__tests__/components/molecules/PreviewTemplateDetails.test.tsx
index 65f8f02b2..be14fbe21 100644
--- a/frontend/src/__tests__/components/molecules/PreviewTemplateDetails.test.tsx
+++ b/frontend/src/__tests__/components/molecules/PreviewTemplateDetails.test.tsx
@@ -569,4 +569,23 @@ describe('PreviewTemplateDetailsLetter', () => {
expect(screen.queryByTestId('edit-name-link')).not.toBeInTheDocument();
expect(screen.queryByTestId('campaign-action')).not.toBeInTheDocument();
});
+
+ it('renders "No preview available" when initialRender is not RENDERED', () => {
+ render(
+
+ );
+
+ expect(screen.getByText('No preview available')).toBeInTheDocument();
+ });
});
diff --git a/frontend/src/__tests__/components/molecules/SummaryChooseLetter.test.tsx b/frontend/src/__tests__/components/molecules/SummaryChooseLetter.test.tsx
new file mode 100644
index 000000000..2770f7e42
--- /dev/null
+++ b/frontend/src/__tests__/components/molecules/SummaryChooseLetter.test.tsx
@@ -0,0 +1,118 @@
+import { SummaryChooseLetter } from '@molecules/SummaryChooseLetter/SummaryChooseLetter';
+import {
+ AUTHORING_LETTER_TEMPLATE,
+ makeLetterVariant,
+ ROUTING_CONFIG,
+} from '@testhelpers/helpers';
+import { render } from '@testing-library/react';
+import { getLetterVariantById, getTemplate } from '@utils/form-actions';
+import { redirect } from 'next/navigation';
+import { validateLetterTemplate } from 'nhs-notify-web-template-management-utils';
+import type { TemplateDto } from 'nhs-notify-web-template-management-types';
+
+jest.mock('@utils/form-actions');
+jest.mock('next/navigation');
+
+const getTemplateMock = jest.mocked(getTemplate);
+const getLetterVariantByIdMock = jest.mocked(getLetterVariantById);
+const redirectMock = jest.mocked(redirect);
+
+const defaultRedirectUrl = '/message-plans/edit-message-plan/routing-config-id';
+
+const defaultProps = {
+ params: Promise.resolve({
+ routingConfigId: 'routing-config-id',
+ templateId: 'template-id',
+ }),
+ searchParams: Promise.resolve({ lockNumber: '5' }),
+ validateTemplate: validateLetterTemplate,
+ redirectUrlOnLockNumberFailure: defaultRedirectUrl,
+};
+
+describe('SummaryChooseLetter', () => {
+ beforeEach(() => {
+ jest.resetAllMocks();
+ });
+
+ it('should redirect when lockNumber is invalid', async () => {
+ await SummaryChooseLetter({
+ ...defaultProps,
+ searchParams: Promise.resolve({ lockNumber: 'invalid' }),
+ redirectUrlOnLockNumberFailure: '/custom-redirect',
+ });
+
+ expect(redirectMock).toHaveBeenCalledWith('/custom-redirect', 'replace');
+ });
+
+ it('should redirect when lockNumber is missing', async () => {
+ await SummaryChooseLetter({
+ ...defaultProps,
+ searchParams: Promise.resolve({}),
+ });
+
+ expect(redirectMock).toHaveBeenCalledWith(defaultRedirectUrl, 'replace');
+ });
+
+ it('should redirect to invalid-template when template is not found', async () => {
+ getTemplateMock.mockResolvedValueOnce(undefined);
+
+ await SummaryChooseLetter({
+ ...defaultProps,
+ params: Promise.resolve({
+ routingConfigId: 'routing-config-id',
+ templateId: 'invalid-template-id',
+ }),
+ });
+
+ expect(getTemplateMock).toHaveBeenCalledWith('invalid-template-id');
+ expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
+ });
+
+ it('should redirect to invalid-template when template fails validation', async () => {
+ getTemplateMock.mockResolvedValueOnce({
+ ...AUTHORING_LETTER_TEMPLATE,
+ templateType: 'EMAIL',
+ } as unknown as TemplateDto);
+
+ await SummaryChooseLetter(defaultProps);
+
+ expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
+ });
+
+ it('should redirect to invalid-template when authoring letter template has no letterVariantId', async () => {
+ getTemplateMock.mockResolvedValueOnce({
+ ...AUTHORING_LETTER_TEMPLATE,
+ templateStatus: 'PROOF_APPROVED',
+ letterVariantId: undefined,
+ });
+
+ await SummaryChooseLetter(defaultProps);
+
+ expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
+ expect(getLetterVariantByIdMock).not.toHaveBeenCalled();
+ });
+
+ it('renders a letter template preview', async () => {
+ const letterVariant = makeLetterVariant();
+
+ getTemplateMock.mockResolvedValueOnce({
+ ...AUTHORING_LETTER_TEMPLATE,
+ templateStatus: 'SUBMITTED',
+ });
+ getLetterVariantByIdMock.mockResolvedValueOnce(letterVariant);
+
+ const page = await SummaryChooseLetter({
+ ...defaultProps,
+ params: Promise.resolve({
+ routingConfigId: ROUTING_CONFIG.id,
+ templateId: AUTHORING_LETTER_TEMPLATE.id,
+ }),
+ });
+
+ const container = render(page);
+
+ expect(getTemplateMock).toHaveBeenCalledWith(AUTHORING_LETTER_TEMPLATE.id);
+ expect(getLetterVariantByIdMock).toHaveBeenCalledWith('variant-123');
+ expect(container.asFragment()).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/__tests__/components/molecules/SummaryLetterFromMessagePlan.test.tsx b/frontend/src/__tests__/components/molecules/SummaryLetterFromMessagePlan.test.tsx
new file mode 100644
index 000000000..0de7f5ce3
--- /dev/null
+++ b/frontend/src/__tests__/components/molecules/SummaryLetterFromMessagePlan.test.tsx
@@ -0,0 +1,94 @@
+import { SummaryLetterFromMessagePlan } from '@molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan';
+import {
+ AUTHORING_LETTER_TEMPLATE,
+ makeLetterVariant,
+ ROUTING_CONFIG,
+} from '@testhelpers/helpers';
+import { render } from '@testing-library/react';
+import { getLetterVariantById, getTemplate } from '@utils/form-actions';
+import { redirect } from 'next/navigation';
+import type { TemplateDto } from 'nhs-notify-web-template-management-types';
+
+jest.mock('@utils/form-actions');
+jest.mock('next/navigation');
+
+const getTemplateMock = jest.mocked(getTemplate);
+const getLetterVariantByIdMock = jest.mocked(getLetterVariantById);
+const redirectMock = jest.mocked(redirect);
+
+const defaultProps = {
+ params: Promise.resolve({
+ routingConfigId: 'routing-config-id',
+ templateId: 'template-id',
+ }),
+ searchParams: Promise.resolve({}),
+};
+
+describe('SummaryLetterFromMessagePlan', () => {
+ beforeEach(() => {
+ jest.resetAllMocks();
+ });
+
+ it('should redirect to invalid-template when template is not found', async () => {
+ getTemplateMock.mockResolvedValueOnce(undefined);
+
+ await SummaryLetterFromMessagePlan({
+ ...defaultProps,
+ params: Promise.resolve({
+ routingConfigId: 'routing-config-id',
+ templateId: 'invalid-template-id',
+ }),
+ });
+
+ expect(getTemplateMock).toHaveBeenCalledWith('invalid-template-id');
+ expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
+ });
+
+ it('should redirect to invalid-template when template fails validation', async () => {
+ getTemplateMock.mockResolvedValueOnce({
+ ...AUTHORING_LETTER_TEMPLATE,
+ templateType: 'EMAIL',
+ } as unknown as TemplateDto);
+
+ await SummaryLetterFromMessagePlan(defaultProps);
+
+ expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
+ });
+
+ it('should redirect to invalid-template when authoring letter template has no letterVariantId', async () => {
+ getTemplateMock.mockResolvedValueOnce({
+ ...AUTHORING_LETTER_TEMPLATE,
+ templateStatus: 'SUBMITTED',
+ letterVariantId: undefined,
+ });
+
+ await SummaryLetterFromMessagePlan(defaultProps);
+
+ expect(redirectMock).toHaveBeenCalledWith('/invalid-template', 'replace');
+ expect(getLetterVariantByIdMock).not.toHaveBeenCalled();
+ });
+
+ it('renders an authoring letter template preview', async () => {
+ const letterVariant = makeLetterVariant();
+
+ getTemplateMock.mockResolvedValueOnce({
+ ...AUTHORING_LETTER_TEMPLATE,
+ templateStatus: 'SUBMITTED',
+ });
+ getLetterVariantByIdMock.mockResolvedValueOnce(letterVariant);
+
+ const page = await SummaryLetterFromMessagePlan({
+ ...defaultProps,
+ params: Promise.resolve({
+ routingConfigId: ROUTING_CONFIG.id,
+ templateId: AUTHORING_LETTER_TEMPLATE.id,
+ }),
+ });
+
+ const container = render(page);
+
+ expect(getTemplateMock).toHaveBeenCalledWith(AUTHORING_LETTER_TEMPLATE.id);
+ expect(getLetterVariantByIdMock).toHaveBeenCalledWith('variant-123');
+ expect(container.asFragment()).toMatchSnapshot();
+ });
+});
diff --git a/frontend/src/__tests__/components/molecules/__snapshots__/MessagePlanCascadePreview.test.tsx.snap b/frontend/src/__tests__/components/molecules/__snapshots__/MessagePlanCascadePreview.test.tsx.snap
index e994f40fa..546575a07 100644
--- a/frontend/src/__tests__/components/molecules/__snapshots__/MessagePlanCascadePreview.test.tsx.snap
+++ b/frontend/src/__tests__/components/molecules/__snapshots__/MessagePlanCascadePreview.test.tsx.snap
@@ -8,7 +8,7 @@ exports[`MessagePlanCascadePreview matches snapshot 1`] = `
class="nhsuk-button nhsuk-button--secondary"
type="button"
>
- Open all template previews
+ Open all digital template previews
-
- letter template name
-
+ authoring letter template name
+
+ Preview template (opens in a new tab)
+
diff --git a/frontend/src/__tests__/components/molecules/__snapshots__/PreviewTemplateFromMessagePlan.test.tsx.snap b/frontend/src/__tests__/components/molecules/__snapshots__/PreviewTemplateFromMessagePlan.test.tsx.snap
index ee69f8628..7a17f7f79 100644
--- a/frontend/src/__tests__/components/molecules/__snapshots__/PreviewTemplateFromMessagePlan.test.tsx.snap
+++ b/frontend/src/__tests__/components/molecules/__snapshots__/PreviewTemplateFromMessagePlan.test.tsx.snap
@@ -123,22 +123,9 @@ exports[`PreviewTemplateFromMessagePlan renders Authoring Letter template previe
1
-
- Learn more
-
- about sheets
-
-
-
+ aria-hidden="true"
+ class="nhsuk-summary-list__actions"
+ />
Go back
@@ -34,7 +34,7 @@ exports[`PreviewBritishSignLanguageLetterTemplateFromMessagePlan page renders Br
- British Sign Language letter template name
+ authoring letter template name
- bsl-letter-template-id
+ authoring-letter-template-id
- British Sign Language letter
+ Standard letter
-
- Learn more
-
- about sheets
-
-
-
+ aria-hidden="true"
+ class="nhsuk-summary-list__actions"
+ />
+ >
+ Standard C5
+
+
+ Example preview
+
+
Go back
diff --git a/frontend/src/__tests__/components/molecules/__snapshots__/SummaryLetterFromMessagePlan.test.tsx.snap b/frontend/src/__tests__/components/molecules/__snapshots__/SummaryLetterFromMessagePlan.test.tsx.snap
new file mode 100644
index 000000000..b5285b2a4
--- /dev/null
+++ b/frontend/src/__tests__/components/molecules/__snapshots__/SummaryLetterFromMessagePlan.test.tsx.snap
@@ -0,0 +1,163 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`SummaryLetterFromMessagePlan renders an authoring letter template preview 1`] = `
+
+
+
+
+
+
+
+ Template
+
+
+ authoring letter template name
+
+
+
+
+
+
+ Template ID
+
+
+ authoring-letter-template-id
+
+
+
+
+
+ Template type
+
+
+ Standard letter
+
+
+
+
+
+ Campaign
+
+
+
+
+
+
+ Total pages
+
+
+ 2
+
+
+
+
+
+ Sheets
+
+
+ 1
+
+
+
+
+
+ Printing and postage
+
+
+ Standard C5
+
+
+
+
+
+
+ Example preview
+
+
+
+
+
+
+
+`;
diff --git a/frontend/src/__tests__/helpers/helpers.ts b/frontend/src/__tests__/helpers/helpers.ts
index 68d336b3c..4cd8e7fb7 100644
--- a/frontend/src/__tests__/helpers/helpers.ts
+++ b/frontend/src/__tests__/helpers/helpers.ts
@@ -176,7 +176,7 @@ export const ROUTING_CONFIG: RoutingConfig = {
cascadeGroups: ['standard'],
channel: 'LETTER',
channelType: 'primary',
- defaultTemplateId: PDF_LETTER_TEMPLATE.id,
+ defaultTemplateId: AUTHORING_LETTER_TEMPLATE.id,
},
],
lockNumber: 0,
diff --git a/frontend/src/app/message-plans/choose-british-sign-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx b/frontend/src/app/message-plans/choose-british-sign-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
index 8b08a8ae1..92868ef3e 100644
--- a/frontend/src/app/message-plans/choose-british-sign-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
+++ b/frontend/src/app/message-plans/choose-british-sign-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
@@ -4,14 +4,9 @@ import {
MessagePlanAndTemplatePageProps,
validateBritishSignLanguageLetterTemplate,
} from 'nhs-notify-web-template-management-utils';
-import { getTemplate } from '@utils/form-actions';
-import { redirect, RedirectType } from 'next/navigation';
import { Metadata } from 'next';
import content from '@content/content';
-import { PreviewTemplateFromMessagePlan } from '@molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan';
-import PreviewTemplateDetailsLetter from '@molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter';
-import { $LockNumber } from 'nhs-notify-backend-client/schemas';
-import { NHSNotifyContainer } from '@layouts/container/container';
+import { SummaryChooseLetter } from '@molecules/SummaryChooseLetter/SummaryChooseLetter';
const { pageTitle } = content.pages.previewBritishSignLanguageLetterTemplate;
@@ -24,35 +19,13 @@ export async function generateMetadata(): Promise
{
const PreviewBritishSignLanguageLetterTemplateFromMessagePlan = async (
props: MessagePlanAndTemplatePageProps
) => {
- const { templateId, routingConfigId } = await props.params;
- const searchParams = await props.searchParams;
-
- const lockNumberResult = $LockNumber.safeParse(searchParams?.lockNumber);
-
- if (!lockNumberResult.success) {
- return redirect(
- `/message-plans/edit-message-plan/${routingConfigId}`,
- RedirectType.replace
- );
- }
-
- const template = await getTemplate(templateId);
-
- const validatedTemplate = validateBritishSignLanguageLetterTemplate(template);
-
- if (!validatedTemplate) {
- return redirect('/invalid-template', RedirectType.replace);
- }
-
+ const { routingConfigId } = await props.params;
return (
-
-
-
+
);
};
diff --git a/frontend/src/app/message-plans/choose-large-print-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx b/frontend/src/app/message-plans/choose-large-print-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
index 584e9dad3..09a133f00 100644
--- a/frontend/src/app/message-plans/choose-large-print-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
+++ b/frontend/src/app/message-plans/choose-large-print-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
@@ -1,17 +1,10 @@
-'use server';
-
import {
MessagePlanAndTemplatePageProps,
validateLargePrintLetterTemplate,
} from 'nhs-notify-web-template-management-utils';
-import { getTemplate } from '@utils/form-actions';
-import { redirect, RedirectType } from 'next/navigation';
import { Metadata } from 'next';
import content from '@content/content';
-import { PreviewTemplateFromMessagePlan } from '@molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan';
-import PreviewTemplateDetailsLetter from '@molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter';
-import { $LockNumber } from 'nhs-notify-backend-client/schemas';
-import { NHSNotifyContainer } from '@layouts/container/container';
+import { SummaryChooseLetter } from '@molecules/SummaryChooseLetter/SummaryChooseLetter';
const { pageTitle } = content.pages.previewLargePrintLetterTemplate;
@@ -24,35 +17,13 @@ export async function generateMetadata(): Promise {
const PreviewLargePrintLetterTemplateFromMessagePlan = async (
props: MessagePlanAndTemplatePageProps
) => {
- const { templateId, routingConfigId } = await props.params;
- const searchParams = await props.searchParams;
-
- const lockNumberResult = $LockNumber.safeParse(searchParams?.lockNumber);
-
- if (!lockNumberResult.success) {
- return redirect(
- `/message-plans/edit-message-plan/${routingConfigId}`,
- RedirectType.replace
- );
- }
-
- const template = await getTemplate(templateId);
-
- const validatedTemplate = validateLargePrintLetterTemplate(template);
-
- if (!validatedTemplate) {
- return redirect('/invalid-template', RedirectType.replace);
- }
-
+ const { routingConfigId } = await props.params;
return (
-
-
-
+
);
};
diff --git a/frontend/src/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx b/frontend/src/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
index 1b8df4d17..22911b99d 100644
--- a/frontend/src/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
+++ b/frontend/src/app/message-plans/choose-other-language-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
@@ -1,17 +1,10 @@
-'use server';
-
import {
MessagePlanAndTemplatePageProps,
validateForeignLanguageLetterTemplate,
} from 'nhs-notify-web-template-management-utils';
-import { getTemplate } from '@utils/form-actions';
-import { redirect, RedirectType } from 'next/navigation';
import { Metadata } from 'next';
import content from '@content/content';
-import { PreviewTemplateFromMessagePlan } from '@molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan';
-import PreviewTemplateDetailsLetter from '@molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter';
-import { $LockNumber } from 'nhs-notify-backend-client/schemas';
-import { NHSNotifyContainer } from '@layouts/container/container';
+import { SummaryChooseLetter } from '@molecules/SummaryChooseLetter/SummaryChooseLetter';
const { pageTitle } = content.pages.previewOtherLanguageLetterTemplate;
@@ -24,35 +17,13 @@ export async function generateMetadata(): Promise {
const PreviewOtherLanguageLetterTemplateFromMessagePlan = async (
props: MessagePlanAndTemplatePageProps
) => {
- const { templateId, routingConfigId } = await props.params;
- const searchParams = await props.searchParams;
-
- const lockNumberResult = $LockNumber.safeParse(searchParams?.lockNumber);
-
- if (!lockNumberResult.success) {
- return redirect(
- `/message-plans/edit-message-plan/${routingConfigId}`,
- RedirectType.replace
- );
- }
-
- const template = await getTemplate(templateId);
-
- const validatedTemplate = validateForeignLanguageLetterTemplate(template);
-
- if (!validatedTemplate) {
- return redirect('/invalid-template', RedirectType.replace);
- }
-
+ const { routingConfigId } = await props.params;
return (
-
-
-
+
);
};
diff --git a/frontend/src/app/message-plans/choose-standard-english-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx b/frontend/src/app/message-plans/choose-standard-english-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
index 39ecdcdec..5821e8756 100644
--- a/frontend/src/app/message-plans/choose-standard-english-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
+++ b/frontend/src/app/message-plans/choose-standard-english-letter-template/[routingConfigId]/preview-template/[templateId]/page.tsx
@@ -1,17 +1,10 @@
-'use server';
-
import {
MessagePlanAndTemplatePageProps,
validateLetterTemplate,
} from 'nhs-notify-web-template-management-utils';
-import { getTemplate } from '@utils/form-actions';
-import { redirect, RedirectType } from 'next/navigation';
import { Metadata } from 'next';
import content from '@content/content';
-import { PreviewTemplateFromMessagePlan } from '@molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan';
-import PreviewTemplateDetailsLetter from '@molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter';
-import { $LockNumber } from 'nhs-notify-backend-client/schemas';
-import { NHSNotifyContainer } from '@layouts/container/container';
+import { SummaryChooseLetter } from '@molecules/SummaryChooseLetter/SummaryChooseLetter';
const { pageTitle } = content.pages.previewStandardEnglishLetterTemplate;
@@ -24,35 +17,13 @@ export async function generateMetadata(): Promise {
const PreviewStandardEnglishLetterTemplateFromMessagePlan = async (
props: MessagePlanAndTemplatePageProps
) => {
- const { templateId, routingConfigId } = await props.params;
- const searchParams = await props.searchParams;
-
- const lockNumberResult = $LockNumber.safeParse(searchParams?.lockNumber);
-
- if (!lockNumberResult.success) {
- return redirect(
- `/message-plans/edit-message-plan/${routingConfigId}`,
- RedirectType.replace
- );
- }
-
- const template = await getTemplate(templateId);
-
- const validatedTemplate = validateLetterTemplate(template);
-
- if (!validatedTemplate) {
- return redirect('/invalid-template', RedirectType.replace);
- }
-
+ const { routingConfigId } = await props.params;
return (
-
-
-
+
);
};
diff --git a/frontend/src/app/message-plans/preview-message-plan/[routingConfigId]/page.tsx b/frontend/src/app/message-plans/preview-message-plan/[routingConfigId]/page.tsx
index 57b2c100b..f3673b38c 100644
--- a/frontend/src/app/message-plans/preview-message-plan/[routingConfigId]/page.tsx
+++ b/frontend/src/app/message-plans/preview-message-plan/[routingConfigId]/page.tsx
@@ -111,6 +111,7 @@ export default async function PreviewMessagePlanPage({
diff --git a/frontend/src/app/message-plans/preview-message-plan/[routingConfigId]/preview-template/[templateId]/page.tsx b/frontend/src/app/message-plans/preview-message-plan/[routingConfigId]/preview-template/[templateId]/page.tsx
new file mode 100644
index 000000000..7c25b09f6
--- /dev/null
+++ b/frontend/src/app/message-plans/preview-message-plan/[routingConfigId]/preview-template/[templateId]/page.tsx
@@ -0,0 +1,18 @@
+import { MessagePlanAndTemplatePageProps } from 'nhs-notify-web-template-management-utils';
+import { Metadata } from 'next';
+import content from '@content/content';
+import { SummaryLetterFromMessagePlan } from '@molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan';
+
+const { pageTitle } = content.pages.previewMessagePlanPreviewLetter;
+
+export async function generateMetadata(): Promise
{
+ return {
+ title: pageTitle,
+ };
+}
+
+const PreviewLetterTemplateFromPreviewMessagePlan = async (
+ props: MessagePlanAndTemplatePageProps
+) => ;
+
+export default PreviewLetterTemplateFromPreviewMessagePlan;
diff --git a/frontend/src/app/message-plans/review-and-move-to-production/[routingConfigId]/page.tsx b/frontend/src/app/message-plans/review-and-move-to-production/[routingConfigId]/page.tsx
index c24d7821a..8127efaba 100644
--- a/frontend/src/app/message-plans/review-and-move-to-production/[routingConfigId]/page.tsx
+++ b/frontend/src/app/message-plans/review-and-move-to-production/[routingConfigId]/page.tsx
@@ -75,6 +75,7 @@ export default async function ReviewAndMoveMessagePlanPage({
diff --git a/frontend/src/app/message-plans/review-and-move-to-production/[routingConfigId]/preview-template/[templateId]/page.tsx b/frontend/src/app/message-plans/review-and-move-to-production/[routingConfigId]/preview-template/[templateId]/page.tsx
new file mode 100644
index 000000000..934bdb8b0
--- /dev/null
+++ b/frontend/src/app/message-plans/review-and-move-to-production/[routingConfigId]/preview-template/[templateId]/page.tsx
@@ -0,0 +1,18 @@
+import { MessagePlanAndTemplatePageProps } from 'nhs-notify-web-template-management-utils';
+import { Metadata } from 'next';
+import content from '@content/content';
+import { SummaryLetterFromMessagePlan } from '@molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan';
+
+const { pageTitle } = content.pages.reviewAndMoveToProductionPreviewLetter;
+
+export async function generateMetadata(): Promise {
+ return {
+ title: pageTitle,
+ };
+}
+
+const PreviewLetterTemplateFromReviewAndMoveToProduction = async (
+ props: MessagePlanAndTemplatePageProps
+) => ;
+
+export default PreviewLetterTemplateFromReviewAndMoveToProduction;
diff --git a/frontend/src/app/review-and-approve-letter-template/[templateId]/ReviewAndApproveLetterTemplatePage.module.scss b/frontend/src/app/review-and-approve-letter-template/[templateId]/ReviewAndApproveLetterTemplatePage.module.scss
deleted file mode 100644
index 40769cbf3..000000000
--- a/frontend/src/app/review-and-approve-letter-template/[templateId]/ReviewAndApproveLetterTemplatePage.module.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-.iframe {
- width: 100%;
- height: 1200px
-}
diff --git a/frontend/src/app/review-and-approve-letter-template/[templateId]/page.tsx b/frontend/src/app/review-and-approve-letter-template/[templateId]/page.tsx
index 254cff331..59a0721db 100644
--- a/frontend/src/app/review-and-approve-letter-template/[templateId]/page.tsx
+++ b/frontend/src/app/review-and-approve-letter-template/[templateId]/page.tsx
@@ -17,10 +17,8 @@ import { PreviewTemplateDetailsAuthoringLetterTable } from '@molecules/PreviewTe
import { LetterRenderIframe } from '@molecules/LetterRender/LetterRenderIframe';
import { getBasePath } from '@utils/get-base-path';
import { NHSNotifyButton } from '@atoms/NHSNotifyButton/NHSNotifyButton';
-import styles from './ReviewAndApproveLetterTemplatePage.module.scss';
import { interpolate } from '@utils/interpolate';
import { $LockNumber } from 'nhs-notify-backend-client/schemas';
-import concatClassNames from '@utils/concat-class-names';
import { buildLetterRenderUrl } from '@utils/letter-render-url';
const {
@@ -97,11 +95,8 @@ const ReviewAndApproveLetterTemplatePage = async (props: TemplatePageProps) => {
/>
{shortExampleHeading}
{
/>
{longExampleHeading}
;
export function LetterRenderIframe({
- tab,
+ renderType,
pdfUrl,
...rest
}: LetterRenderIframeProps) {
- if (!pdfUrl) return No preview available
;
- const tabDescription = tab === 'shortFormRender' ? 'short' : 'long';
+ if (!pdfUrl)
+ return (
+
+ {content.components.letterRender.iframe.noPreview}
+
+ );
+
+ const { title, ariaLabel } = content.components.letterRender.iframe;
return (
);
diff --git a/frontend/src/components/molecules/LetterRender/LetterRenderTab.tsx b/frontend/src/components/molecules/LetterRender/LetterRenderTab.tsx
index cb00e21e1..649f74c8a 100644
--- a/frontend/src/components/molecules/LetterRender/LetterRenderTab.tsx
+++ b/frontend/src/components/molecules/LetterRender/LetterRenderTab.tsx
@@ -92,7 +92,7 @@ function LetterRenderTabContent({
{hideEditActions ? (
-
+
) : (
{loadingText}}
forcePolling={isPending}
>
-
+
)}
diff --git a/frontend/src/components/molecules/MessagePlanCascadePreview/MessagePlanCascadePreview.tsx b/frontend/src/components/molecules/MessagePlanCascadePreview/MessagePlanCascadePreview.tsx
index 635984945..c620324f1 100644
--- a/frontend/src/components/molecules/MessagePlanCascadePreview/MessagePlanCascadePreview.tsx
+++ b/frontend/src/components/molecules/MessagePlanCascadePreview/MessagePlanCascadePreview.tsx
@@ -39,22 +39,23 @@ import {
const pageContent = content.components.messagePlanCascadePreview;
-function getLetterTemplatePreviewHref(template: TemplateDto): string {
- const linkTemplate =
- template.templateStatus === 'SUBMITTED'
- ? pageContent.letterTemplateLinks.previewSubmitted
- : pageContent.letterTemplateLinks.preview;
- return interpolate(linkTemplate, { id: template.id });
+function getLetterTemplatePreviewHref(
+ template: TemplateDto,
+ letterPreviewHrefBase?: string
+): string {
+ return `${letterPreviewHrefBase}/preview-template/${template.id}`;
}
export type MessagePlanCascadePreviewProps = {
messagePlan: RoutingConfig;
templates: MessagePlanTemplates;
+ letterPreviewHrefBase: string;
};
export function MessagePlanCascadePreview({
messagePlan,
templates,
+ letterPreviewHrefBase,
}: MessagePlanCascadePreviewProps) {
return (
@@ -107,13 +108,19 @@ export function MessagePlanCascadePreview({
data-testid='channel-card'
>
{cascadeItem.channel === 'LETTER' ? (
-
+ <>
+
{defaultTemplate.name}
- {defaultTemplate.name}
+ {pageContent.letterTemplateLinkText}
-
+ >
) : (
<>
{defaultTemplate.name}
@@ -163,11 +170,19 @@ export function MessagePlanCascadePreview({
)}
data-testid='channel-card'
>
-
-
- {template.name}
+ <>
+
{template.name}
+
+ {pageContent.letterTemplateLinkText}
-
+ >
))}
@@ -179,17 +194,20 @@ export function MessagePlanCascadePreview({
data-testid='channel-card'
>
{languageTemplates.map((template) => (
-
+ <>
+
{template.name}
- {template.name}
+ {pageContent.letterTemplateLinkText}
-
+ >
))}
diff --git a/frontend/src/components/molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter.tsx b/frontend/src/components/molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter.tsx
index 89882438f..3f43b5172 100644
--- a/frontend/src/components/molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter.tsx
+++ b/frontend/src/components/molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter.tsx
@@ -3,27 +3,54 @@
import { LetterTemplate } from 'nhs-notify-web-template-management-utils';
import PreviewTemplateDetailsPdfLetter from './PreviewTemplateDetailsPdfLetter';
import PreviewTemplateDetailsAuthoringLetter from './PreviewTemplateDetailsAuthoringLetter';
+import { LetterRenderIframe } from '@molecules/LetterRender/LetterRenderIframe';
+import { buildLetterRenderUrl } from '@utils/letter-render-url';
+import type { LetterVariant } from 'nhs-notify-web-template-management-types';
export default function PreviewTemplateDetailsLetter({
template,
+ letterVariant,
hideStatus,
hideEditActions,
+ hideLearnMore,
}: {
template: LetterTemplate;
+ letterVariant?: LetterVariant;
hideStatus?: boolean;
hideEditActions?: boolean;
+ hideLearnMore?: boolean;
}) {
- // TODO: CCM-14768 - PreviewTemplateDetailsAuthoringLetter requires the Letter Variant.
- return template.letterVersion === 'PDF' ? (
-
- ) : (
-
+ if (template.letterVersion === 'PDF') {
+ return (
+
+ );
+ }
+
+ const { initialRender } = template.files;
+
+ const pdfUrl =
+ initialRender.status === 'RENDERED'
+ ? buildLetterRenderUrl(template, initialRender.fileName)
+ : null;
+
+ return (
+ <>
+
+ Example preview
+
+ >
);
}
diff --git a/frontend/src/components/molecules/PreviewTemplateDetails/common.tsx b/frontend/src/components/molecules/PreviewTemplateDetails/common.tsx
index 53dec7cf7..a68ae7cb2 100644
--- a/frontend/src/components/molecules/PreviewTemplateDetails/common.tsx
+++ b/frontend/src/components/molecules/PreviewTemplateDetails/common.tsx
@@ -7,7 +7,10 @@ import {
import styles from './PreviewTemplateDetails.module.scss';
import { JSX } from 'react';
import content from '@content/content';
-import type { TemplateDto } from 'nhs-notify-web-template-management-types';
+import type {
+ LetterVariant,
+ TemplateDto,
+} from 'nhs-notify-web-template-management-types';
import classNames from 'classnames';
import { toKebabCase } from '@utils/kebab-case';
import { useFeatureFlags } from '@providers/client-config-provider';
@@ -19,10 +22,14 @@ export type PreviewTemplateComponent = ({
template,
hideStatus,
hideEditActions,
+ hideLearnMore,
+ letterVariant,
}: {
template: T;
hideStatus?: boolean;
hideEditActions?: boolean;
+ hideLearnMore?: boolean;
+ letterVariant?: LetterVariant;
}) => JSX.Element;
type ContentPreviewField = {
diff --git a/frontend/src/components/molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan.tsx b/frontend/src/components/molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan.tsx
index c5134c030..20934cf6b 100644
--- a/frontend/src/components/molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan.tsx
+++ b/frontend/src/components/molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan.tsx
@@ -3,8 +3,11 @@
import baseContent from '@content/content';
import Link from 'next/link';
import { NHSNotifyMain } from '@atoms/NHSNotifyMain/NHSNotifyMain';
-import NotifyBackLink from '@atoms/NHSNotifyBackLink/NHSNotifyBackLink';
-import type { TemplateDto } from 'nhs-notify-web-template-management-types';
+import { NHSNotifyBackLink } from '@atoms/NHSNotifyBackLink/NHSNotifyBackLink';
+import type {
+ LetterVariant,
+ TemplateDto,
+} from 'nhs-notify-web-template-management-types';
import {
templateTypeToUrlTextMappings,
PageComponentProps,
@@ -18,7 +21,9 @@ export type MessagePlanPreviewTemplateProps =
PageComponentProps & {
previewComponent: PreviewTemplateComponent;
routingConfigId: string;
- lockNumber: number;
+ lockNumber?: number;
+ letterVariant?: LetterVariant;
+ hideBackLinks?: boolean;
};
export function PreviewTemplateFromMessagePlan({
@@ -26,6 +31,8 @@ export function PreviewTemplateFromMessagePlan({
previewComponent,
routingConfigId,
lockNumber,
+ letterVariant,
+ hideBackLinks,
}: Readonly>) {
const content = baseContent.components.previewTemplateFromMessagePlan;
@@ -39,36 +46,45 @@ export function PreviewTemplateFromMessagePlan({
}
}
- const backLinkHref = interpolate(content.backLink.href, {
- templateType: templateTypeToUrlTextMappings(
- template.templateType,
- letterType
- ),
- routingConfigId,
- lockNumber,
- });
+ const backLinkHref =
+ hideBackLinks || lockNumber === undefined
+ ? undefined
+ : interpolate(content.backLink.href, {
+ templateType: templateTypeToUrlTextMappings(
+ template.templateType,
+ letterType
+ ),
+ routingConfigId,
+ lockNumber,
+ });
return (
<>
-
- {content.backLink.text}
-
+ {backLinkHref && (
+
+ {content.backLink.text}
+
+ )}
{previewComponent({
template,
+ letterVariant,
hideStatus: true,
hideEditActions: true,
+ hideLearnMore: true,
})}
-
- {content.backLink.text}
-
+ {backLinkHref && (
+
+ {content.backLink.text}
+
+ )}
diff --git a/frontend/src/components/molecules/SummaryChooseLetter/SummaryChooseLetter.tsx b/frontend/src/components/molecules/SummaryChooseLetter/SummaryChooseLetter.tsx
new file mode 100644
index 000000000..de07b0666
--- /dev/null
+++ b/frontend/src/components/molecules/SummaryChooseLetter/SummaryChooseLetter.tsx
@@ -0,0 +1,58 @@
+import {
+ LetterTemplate,
+ MessagePlanAndTemplatePageProps,
+} from 'nhs-notify-web-template-management-utils';
+import type { TemplateDto } from 'nhs-notify-web-template-management-types';
+import { getLetterVariantById, getTemplate } from '@utils/form-actions';
+import { redirect, RedirectType } from 'next/navigation';
+import { PreviewTemplateFromMessagePlan } from '@molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan';
+import PreviewTemplateDetailsLetter from '@molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter';
+import { $LockNumber } from 'nhs-notify-backend-client/schemas';
+import { NHSNotifyContainer } from '@layouts/container/container';
+
+type SummaryChooseLetterProps = MessagePlanAndTemplatePageProps & {
+ validateTemplate: (template?: TemplateDto) => LetterTemplate | undefined;
+ redirectUrlOnLockNumberFailure: string;
+};
+
+export const SummaryChooseLetter = async (props: SummaryChooseLetterProps) => {
+ const { templateId, routingConfigId } = await props.params;
+ const { redirectUrlOnLockNumberFailure } = props;
+
+ const searchParams = await props.searchParams;
+ const lockNumberResult = $LockNumber.safeParse(searchParams?.lockNumber);
+
+ if (!lockNumberResult.success) {
+ return redirect(redirectUrlOnLockNumberFailure, RedirectType.replace);
+ }
+
+ const lockNumber = lockNumberResult.data;
+
+ const template = await getTemplate(templateId);
+
+ const validatedTemplate = props.validateTemplate(template);
+
+ if (
+ !validatedTemplate ||
+ !('letterVariantId' in validatedTemplate) ||
+ !validatedTemplate.letterVariantId
+ ) {
+ return redirect('/invalid-template', RedirectType.replace);
+ }
+
+ const letterVariant = await getLetterVariantById(
+ validatedTemplate.letterVariantId
+ );
+
+ return (
+
+
+
+ );
+};
diff --git a/frontend/src/components/molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan.tsx b/frontend/src/components/molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan.tsx
new file mode 100644
index 000000000..ddd0c8c97
--- /dev/null
+++ b/frontend/src/components/molecules/SummaryLetterFromMessagePlan/SummaryLetterFromMessagePlan.tsx
@@ -0,0 +1,39 @@
+import {
+ MessagePlanAndTemplatePageProps,
+ validateAuthoringLetterTemplate,
+} from 'nhs-notify-web-template-management-utils';
+import { getLetterVariantById, getTemplate } from '@utils/form-actions';
+import { redirect, RedirectType } from 'next/navigation';
+import { PreviewTemplateFromMessagePlan } from '@molecules/PreviewTemplateFromMessagePlan/PreviewTemplateFromMessagePlan';
+import PreviewTemplateDetailsLetter from '@molecules/PreviewTemplateDetails/PreviewTemplateDetailsLetter';
+import { NHSNotifyContainer } from '@layouts/container/container';
+
+export const SummaryLetterFromMessagePlan = async (
+ props: MessagePlanAndTemplatePageProps
+) => {
+ const { templateId, routingConfigId } = await props.params;
+
+ const template = await getTemplate(templateId);
+
+ const validatedTemplate = validateAuthoringLetterTemplate(template);
+
+ if (!validatedTemplate || !validatedTemplate.letterVariantId) {
+ return redirect('/invalid-template', RedirectType.replace);
+ }
+
+ const letterVariant = await getLetterVariantById(
+ validatedTemplate.letterVariantId
+ );
+
+ return (
+
+
+
+ );
+};
diff --git a/frontend/src/content/content.ts b/frontend/src/content/content.ts
index e036d90a3..1adce327e 100644
--- a/frontend/src/content/content.ts
+++ b/frontend/src/content/content.ts
@@ -3,6 +3,7 @@ import type {
TemplateStatus,
TemplateType,
} from 'nhs-notify-web-template-management-types';
+import type { RenderKey } from '@utils/types';
import type {
DigitalTemplateType,
FrontendSupportedLetterType,
@@ -573,6 +574,14 @@ const previewSubmittedLetterTemplate = {
pageTitle: previewLetterTitle,
};
+const previewMessagePlanPreviewLetter = {
+ pageTitle: previewLetterTitle,
+};
+
+const reviewAndMoveToProductionPreviewLetter = {
+ pageTitle: previewLetterTitle,
+};
+
const letterRender = {
heading: 'Letter preview',
guidance: 'Check how your personalisation fields will appear in your letter.',
@@ -586,6 +595,21 @@ const letterRender = {
long: 'Long examples',
},
loadingText: 'Loading letter preview',
+ iframe: {
+ noPreview: 'No preview available',
+ title: {
+ initialRender: 'Letter preview',
+ shortFormRender: 'Letter preview - short examples',
+ longFormRender: 'Letter preview - long examples',
+ } satisfies Record,
+ ariaLabel: {
+ initialRender: 'PDF preview of letter template',
+ shortFormRender:
+ 'PDF preview of letter template with short example personalisation data',
+ longFormRender:
+ 'PDF preview of letter template with long example personalisation data',
+ } satisfies Record,
+ },
pdsSection: {
heading: 'PDS personalisation fields',
hint: 'The PDS fields will be pre-filled with example data when you choose a test recipient.',
@@ -1402,8 +1426,8 @@ const messagePlanConditionalLetterTemplates = {
const messagePlanCascadePreview = {
detailsOpenButton: {
- openText: 'Close all template previews',
- closedText: 'Open all template previews',
+ openText: 'Close all digital template previews',
+ closedText: 'Open all digital template previews',
},
languageFormatsCardHeading: 'Other language letters (optional)',
accessibleFormatCardHeading: '{{format}} (optional)',
@@ -1415,6 +1439,7 @@ const messagePlanCascadePreview = {
previewSubmitted: '/preview-submitted-letter-template/{{id}}',
preview: '/preview-letter-template/{{id}}',
},
+ letterTemplateLinkText: 'Preview template (opens in a new tab)',
};
const editMessagePlan = {
@@ -2103,11 +2128,13 @@ const content = {
previewLargePrintLetterTemplate,
previewLetterTemplate,
previewMessagePlan,
+ previewMessagePlanPreviewLetter,
previewOtherLanguageLetterTemplate,
previewStandardEnglishLetterTemplate,
previewSubmittedLetterTemplate,
reviewAndApproveLetterTemplate,
reviewAndMoveToProduction,
+ reviewAndMoveToProductionPreviewLetter,
submitLetterTemplate: submitLetterTemplatePage,
uploadDocxLetterTemplatePage,
},
diff --git a/frontend/src/middleware.ts b/frontend/src/middleware.ts
index e4e383046..76f241e4d 100644
--- a/frontend/src/middleware.ts
+++ b/frontend/src/middleware.ts
@@ -45,7 +45,9 @@ const protectedPaths = [
/^\/message-plans\/get-ready-to-move\/[^/]+$/,
/^\/message-plans\/invalid$/,
/^\/message-plans\/preview-message-plan\/[^/]+$/,
+ /^\/message-plans\/preview-message-plan\/[^/]+\/preview-template\/[^/]+$/,
/^\/message-plans\/review-and-move-to-production\/[^/]+$/,
+ /^\/message-plans\/review-and-move-to-production\/[^/]+\/preview-template\/[^/]+$/,
/^\/message-plans$/,
/^\/message-templates$/,
/^\/nhs-app-template-submitted\/[^/]+$/,
diff --git a/frontend/src/styles/app.scss b/frontend/src/styles/app.scss
index 57c31e281..7cea77c31 100644
--- a/frontend/src/styles/app.scss
+++ b/frontend/src/styles/app.scss
@@ -146,3 +146,8 @@ a.nhsuk-link--no-visited-state {
background-color: var(--nhsuk-pale-yellow-colour);
box-shadow: inset 0 0 0 3px var(--nhsuk-yellow-colour);
}
+
+.letter-render-iframe {
+ width: 100%;
+ height: 1200px;
+}
diff --git a/scripts/config/pre-commit.yaml b/scripts/config/pre-commit.yaml
index 4e757008d..79d121c0b 100644
--- a/scripts/config/pre-commit.yaml
+++ b/scripts/config/pre-commit.yaml
@@ -19,8 +19,8 @@ repos:
- id: pretty-format-json
exclude: |
(?x)^(
- .*/?package-lock.json |
- packages/event-schemas/schemas/[^/]+/[^/]+\.json
+ (^|/)package-lock\.json$ |
+ ^packages/event-schemas/schemas/[^/]+/[^/]+\.json$
)$
args: ['--autofix']
diff --git a/tests/test-team/pages/routing/index.ts b/tests/test-team/pages/routing/index.ts
index f7420eacd..07c52426b 100644
--- a/tests/test-team/pages/routing/index.ts
+++ b/tests/test-team/pages/routing/index.ts
@@ -6,7 +6,9 @@ export * from './edit-message-plan-settings-page';
export * from './get-ready-to-move-page';
export * from './invalid-message-plan-page';
export * from './message-plans-page';
+export * from './preview-message-plan-letter-template-page';
export * from './preview-message-plan-page';
+export * from './review-and-move-to-production-letter-template-page';
export * from './review-and-move-to-production-page';
export * from './email';
export * from './letter';
diff --git a/tests/test-team/pages/routing/letter/preview-british-sign-language-letter-template-page.ts b/tests/test-team/pages/routing/letter/preview-british-sign-language-letter-template-page.ts
index 09737b0a9..4ed016468 100644
--- a/tests/test-team/pages/routing/letter/preview-british-sign-language-letter-template-page.ts
+++ b/tests/test-team/pages/routing/letter/preview-british-sign-language-letter-template-page.ts
@@ -1,6 +1,18 @@
+import { Locator, Page } from '@playwright/test';
import { TemplateMgmtPreviewBasePage } from 'pages/template-mgmt-preview-base-page';
export class RoutingPreviewBritishSignLanguageLetterTemplatePage extends TemplateMgmtPreviewBasePage {
static readonly pathTemplate =
'/message-plans/choose-british-sign-language-letter-template/:messagePlanId/preview-template/:templateId';
+
+ public readonly letterPreviewHeading: Locator;
+ public readonly letterPreviewIframe: Locator;
+
+ constructor(page: Page) {
+ super(page);
+ this.letterPreviewHeading = page.getByRole('heading', {
+ name: 'Example preview',
+ });
+ this.letterPreviewIframe = page.locator('iframe[title="Letter preview"]');
+ }
}
diff --git a/tests/test-team/pages/routing/letter/preview-large-print-letter-template-page.ts b/tests/test-team/pages/routing/letter/preview-large-print-letter-template-page.ts
index 5b025da39..8bcea6ed5 100644
--- a/tests/test-team/pages/routing/letter/preview-large-print-letter-template-page.ts
+++ b/tests/test-team/pages/routing/letter/preview-large-print-letter-template-page.ts
@@ -1,6 +1,18 @@
+import { Locator, Page } from '@playwright/test';
import { TemplateMgmtPreviewBasePage } from 'pages/template-mgmt-preview-base-page';
export class RoutingPreviewLargePrintLetterTemplatePage extends TemplateMgmtPreviewBasePage {
static readonly pathTemplate =
'/message-plans/choose-large-print-letter-template/:messagePlanId/preview-template/:templateId';
+
+ public readonly letterPreviewHeading: Locator;
+ public readonly letterPreviewIframe: Locator;
+
+ constructor(page: Page) {
+ super(page);
+ this.letterPreviewHeading = page.getByRole('heading', {
+ name: 'Example preview',
+ });
+ this.letterPreviewIframe = page.locator('iframe[title="Letter preview"]');
+ }
}
diff --git a/tests/test-team/pages/routing/letter/preview-other-language-letter-template-page.ts b/tests/test-team/pages/routing/letter/preview-other-language-letter-template-page.ts
index 08028315f..66d67a2e7 100644
--- a/tests/test-team/pages/routing/letter/preview-other-language-letter-template-page.ts
+++ b/tests/test-team/pages/routing/letter/preview-other-language-letter-template-page.ts
@@ -1,6 +1,18 @@
+import { Locator, Page } from '@playwright/test';
import { TemplateMgmtPreviewBasePage } from 'pages/template-mgmt-preview-base-page';
export class RoutingPreviewOtherLanguageLetterTemplatePage extends TemplateMgmtPreviewBasePage {
static readonly pathTemplate =
'/message-plans/choose-other-language-letter-template/:messagePlanId/preview-template/:templateId';
+
+ public readonly letterPreviewHeading: Locator;
+ public readonly letterPreviewIframe: Locator;
+
+ constructor(page: Page) {
+ super(page);
+ this.letterPreviewHeading = page.getByRole('heading', {
+ name: 'Example preview',
+ });
+ this.letterPreviewIframe = page.locator('iframe[title="Letter preview"]');
+ }
}
diff --git a/tests/test-team/pages/routing/letter/preview-standard-letter-page.ts b/tests/test-team/pages/routing/letter/preview-standard-letter-page.ts
index 597930cb8..d820a9677 100644
--- a/tests/test-team/pages/routing/letter/preview-standard-letter-page.ts
+++ b/tests/test-team/pages/routing/letter/preview-standard-letter-page.ts
@@ -1,6 +1,18 @@
+import { Locator, Page } from '@playwright/test';
import { TemplateMgmtPreviewBasePage } from 'pages/template-mgmt-preview-base-page';
export class RoutingPreviewStandardLetterTemplatePage extends TemplateMgmtPreviewBasePage {
static readonly pathTemplate =
'/message-plans/choose-standard-english-letter-template/:messagePlanId/preview-template/:templateId';
+
+ public readonly letterPreviewHeading: Locator;
+ public readonly letterPreviewIframe: Locator;
+
+ constructor(page: Page) {
+ super(page);
+ this.letterPreviewHeading = page.getByRole('heading', {
+ name: 'Example preview',
+ });
+ this.letterPreviewIframe = page.locator('iframe[title="Letter preview"]');
+ }
}
diff --git a/tests/test-team/pages/routing/preview-message-plan-letter-template-page.ts b/tests/test-team/pages/routing/preview-message-plan-letter-template-page.ts
new file mode 100644
index 000000000..eb1f74c39
--- /dev/null
+++ b/tests/test-team/pages/routing/preview-message-plan-letter-template-page.ts
@@ -0,0 +1,18 @@
+import { Locator, Page } from '@playwright/test';
+import { TemplateMgmtPreviewBasePage } from 'pages/template-mgmt-preview-base-page';
+
+export class RoutingPreviewMessagePlanPreviewLetterTemplatePage extends TemplateMgmtPreviewBasePage {
+ static readonly pathTemplate =
+ '/message-plans/preview-message-plan/:messagePlanId/preview-template/:templateId';
+
+ public readonly letterPreviewHeading: Locator;
+ public readonly letterPreviewIframe: Locator;
+
+ constructor(page: Page) {
+ super(page);
+ this.letterPreviewHeading = page.getByRole('heading', {
+ name: 'Example preview',
+ });
+ this.letterPreviewIframe = page.locator('iframe[title="Letter preview"]');
+ }
+}
diff --git a/tests/test-team/pages/routing/preview-message-plan-page.ts b/tests/test-team/pages/routing/preview-message-plan-page.ts
index 7946d53bb..d6a7f34f7 100644
--- a/tests/test-team/pages/routing/preview-message-plan-page.ts
+++ b/tests/test-team/pages/routing/preview-message-plan-page.ts
@@ -26,7 +26,7 @@ export class RoutingPreviewMessagePlanPage extends TemplateMgmtBasePage {
this.campaignId = page.getByTestId('campaign-id');
this.status = page.getByTestId('status');
this.previewToggleButton = page.getByRole('button', {
- name: /^(Open|Close) all template previews$/,
+ name: /^(Open|Close) all digital template previews$/,
});
this.detailsSections = page.locator('details');
}
diff --git a/tests/test-team/pages/routing/review-and-move-to-production-letter-template-page.ts b/tests/test-team/pages/routing/review-and-move-to-production-letter-template-page.ts
new file mode 100644
index 000000000..5af076ee2
--- /dev/null
+++ b/tests/test-team/pages/routing/review-and-move-to-production-letter-template-page.ts
@@ -0,0 +1,18 @@
+import { Locator, Page } from '@playwright/test';
+import { TemplateMgmtPreviewBasePage } from 'pages/template-mgmt-preview-base-page';
+
+export class RoutingReviewAndMoveToProductionPreviewLetterTemplatePage extends TemplateMgmtPreviewBasePage {
+ static readonly pathTemplate =
+ '/message-plans/review-and-move-to-production/:messagePlanId/preview-template/:templateId';
+
+ public readonly letterPreviewHeading: Locator;
+ public readonly letterPreviewIframe: Locator;
+
+ constructor(page: Page) {
+ super(page);
+ this.letterPreviewHeading = page.getByRole('heading', {
+ name: 'Example preview',
+ });
+ this.letterPreviewIframe = page.locator('iframe[title="Letter preview"]');
+ }
+}
diff --git a/tests/test-team/pages/routing/review-and-move-to-production-page.ts b/tests/test-team/pages/routing/review-and-move-to-production-page.ts
index 7eeafe880..42a5047bc 100644
--- a/tests/test-team/pages/routing/review-and-move-to-production-page.ts
+++ b/tests/test-team/pages/routing/review-and-move-to-production-page.ts
@@ -24,7 +24,7 @@ export class RoutingReviewAndMoveToProductionPage extends TemplateMgmtBasePage {
this.messagePlanName = page.getByTestId('plan-name');
this.previewToggleButton = page.getByRole('button', {
- name: /^(Open|Close) all template previews$/,
+ name: /^(Open|Close) all digital template previews$/,
});
this.detailsSections = page.locator('details');
this.moveToProductionButton = page.getByTestId('move-to-production-button');
diff --git a/tests/test-team/template-mgmt-accessibility/route-coverage.accessibility.spec.ts b/tests/test-team/template-mgmt-accessibility/route-coverage.accessibility.spec.ts
index 28812a0e7..ca0e40dca 100644
--- a/tests/test-team/template-mgmt-accessibility/route-coverage.accessibility.spec.ts
+++ b/tests/test-team/template-mgmt-accessibility/route-coverage.accessibility.spec.ts
@@ -85,12 +85,14 @@ import {
RoutingPreviewBritishSignLanguageLetterTemplatePage,
RoutingPreviewEmailTemplatePage,
RoutingPreviewLargePrintLetterTemplatePage,
+ RoutingPreviewMessagePlanPreviewLetterTemplatePage,
RoutingPreviewMessagePlanPage,
RoutingPreviewNhsAppTemplatePage,
RoutingPreviewOtherLanguageLetterTemplatePage,
RoutingPreviewSmsTemplatePage,
RoutingPreviewStandardLetterTemplatePage,
RoutingReviewAndMoveToProductionPage,
+ RoutingReviewAndMoveToProductionPreviewLetterTemplatePage,
} from 'pages/routing';
/**
@@ -173,12 +175,14 @@ const allPages: (typeof TemplateMgmtBasePage)[] = [
RoutingPreviewBritishSignLanguageLetterTemplatePage,
RoutingPreviewEmailTemplatePage,
RoutingPreviewLargePrintLetterTemplatePage,
+ RoutingPreviewMessagePlanPreviewLetterTemplatePage,
RoutingPreviewMessagePlanPage,
RoutingPreviewNhsAppTemplatePage,
RoutingPreviewOtherLanguageLetterTemplatePage,
RoutingPreviewSmsTemplatePage,
RoutingPreviewStandardLetterTemplatePage,
RoutingReviewAndMoveToProductionPage,
+ RoutingReviewAndMoveToProductionPreviewLetterTemplatePage,
];
test('all app routes have accessibility test coverage', async () => {
diff --git a/tests/test-team/template-mgmt-accessibility/routing.accessibility.spec.ts b/tests/test-team/template-mgmt-accessibility/routing.accessibility.spec.ts
index 4d8685b2d..6d2cc5c4d 100644
--- a/tests/test-team/template-mgmt-accessibility/routing.accessibility.spec.ts
+++ b/tests/test-team/template-mgmt-accessibility/routing.accessibility.spec.ts
@@ -26,12 +26,14 @@ import {
RoutingPreviewBritishSignLanguageLetterTemplatePage,
RoutingPreviewEmailTemplatePage,
RoutingPreviewLargePrintLetterTemplatePage,
+ RoutingPreviewMessagePlanPreviewLetterTemplatePage,
RoutingPreviewMessagePlanPage,
RoutingPreviewNhsAppTemplatePage,
RoutingPreviewOtherLanguageLetterTemplatePage,
RoutingPreviewSmsTemplatePage,
RoutingPreviewStandardLetterTemplatePage,
RoutingReviewAndMoveToProductionPage,
+ RoutingReviewAndMoveToProductionPreviewLetterTemplatePage,
} from 'pages/routing';
import { getTestContext } from 'helpers/context/context';
@@ -62,6 +64,9 @@ test.describe('Routing', () => {
testUsers.UserWithMultipleCampaigns.userId
);
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
const createRoutingConfig = (id: string, status: RoutingConfigStatus) =>
RoutingConfigFactory.createForMessageOrder(user, messageOrder, {
id,
@@ -124,6 +129,7 @@ test.describe('Routing', () => {
{
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: globalLetterVariant.id,
}
),
TemplateFactory.createAuthoringLetterTemplate(
@@ -135,6 +141,7 @@ test.describe('Routing', () => {
letterType: 'x1',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: globalLetterVariant.id,
}
),
TemplateFactory.createAuthoringLetterTemplate(
@@ -146,6 +153,7 @@ test.describe('Routing', () => {
letterType: 'q4',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: globalLetterVariant.id,
}
),
TemplateFactory.createAuthoringLetterTemplate(
@@ -157,6 +165,7 @@ test.describe('Routing', () => {
language: 'fr',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: globalLetterVariant.id,
}
),
]);
@@ -280,6 +289,26 @@ test.describe('Routing', () => {
.setPathParam('templateId', templateIds.SMS)
.setSearchParam('lockNumber', '0')
));
+
+ test('Preview message plan / preview letter template', async ({
+ page,
+ analyze,
+ }) =>
+ analyze(
+ new RoutingPreviewMessagePlanPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', productionRoutingConfigId)
+ .setPathParam('templateId', templateIds.LETTER)
+ ));
+
+ test('Review and move to production / preview letter template', async ({
+ page,
+ analyze,
+ }) =>
+ analyze(
+ new RoutingReviewAndMoveToProductionPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', draftRoutingConfigId)
+ .setPathParam('templateId', templateIds.LETTER)
+ ));
});
test('Message plans', async ({ page, analyze }) =>
diff --git a/tests/test-team/template-mgmt-component-tests/template-protected-routes.component.spec.ts b/tests/test-team/template-mgmt-component-tests/template-protected-routes.component.spec.ts
index a7ef734e5..b0ea2418f 100644
--- a/tests/test-team/template-mgmt-component-tests/template-protected-routes.component.spec.ts
+++ b/tests/test-team/template-mgmt-component-tests/template-protected-routes.component.spec.ts
@@ -17,11 +17,13 @@ import { RoutingMessagePlanCampaignIdRequiredPage } from '../pages/routing/campa
import { RoutingMessagePlansPage } from '../pages/routing/message-plans-page';
import { RoutingPreviewEmailTemplatePage } from 'pages/routing/email/preview-email-page';
import { RoutingPreviewLargePrintLetterTemplatePage } from 'pages/routing/letter/preview-large-print-letter-template-page';
+import { RoutingPreviewMessagePlanPreviewLetterTemplatePage } from 'pages/routing/preview-message-plan-letter-template-page';
import { RoutingPreviewMessagePlanPage } from 'pages/routing/preview-message-plan-page';
import { RoutingPreviewNhsAppTemplatePage } from 'pages/routing/nhs-app/preview-nhs-app-page';
import { RoutingPreviewOtherLanguageLetterTemplatePage } from 'pages/routing/letter/preview-other-language-letter-template-page';
import { RoutingPreviewSmsTemplatePage } from 'pages/routing/sms/preview-sms-template-page';
import { RoutingPreviewStandardLetterTemplatePage } from 'pages/routing/letter/preview-standard-letter-page';
+import { RoutingReviewAndMoveToProductionPreviewLetterTemplatePage } from 'pages/routing/review-and-move-to-production-letter-template-page';
import {
RoutingChooseBritishSignLanguageLetterTemplatePage,
RoutingPreviewBritishSignLanguageLetterTemplatePage,
@@ -93,12 +95,14 @@ const protectedPages = [
RoutingPreviewBritishSignLanguageLetterTemplatePage,
RoutingPreviewEmailTemplatePage,
RoutingPreviewLargePrintLetterTemplatePage,
+ RoutingPreviewMessagePlanPreviewLetterTemplatePage,
RoutingPreviewMessagePlanPage,
RoutingPreviewNhsAppTemplatePage,
RoutingPreviewOtherLanguageLetterTemplatePage,
RoutingPreviewSmsTemplatePage,
RoutingPreviewStandardLetterTemplatePage,
RoutingReviewAndMoveToProductionPage,
+ RoutingReviewAndMoveToProductionPreviewLetterTemplatePage,
TemplateMgmtChoosePage,
TemplateMgmtChoosePrintingAndPostagePage,
TemplateMgmtCopyPage,
diff --git a/tests/test-team/template-mgmt-e2e-tests/routing.e2e.spec.ts b/tests/test-team/template-mgmt-e2e-tests/routing.e2e.spec.ts
index 9ea2baca4..ad94767fd 100644
--- a/tests/test-team/template-mgmt-e2e-tests/routing.e2e.spec.ts
+++ b/tests/test-team/template-mgmt-e2e-tests/routing.e2e.spec.ts
@@ -18,17 +18,23 @@ import {
RoutingChooseLargePrintLetterTemplatePage,
RoutingGetReadyToMovePage,
RoutingReviewAndMoveToProductionPage,
+ RoutingReviewAndMoveToProductionPreviewLetterTemplatePage,
RoutingChooseBritishSignLanguageLetterTemplatePage,
+ RoutingPreviewMessagePlanPage,
+ RoutingPreviewMessagePlanPreviewLetterTemplatePage,
} from '../pages/routing';
import { TemplateMgmtMessageTemplatesPage } from '../pages/template-mgmt-message-templates-page';
import { RoutingChooseTemplateForMessagePlanBasePage } from '../pages/routing/choose-template-base-page';
import type { Template } from '../helpers/types';
import { loginAsUser } from 'helpers/auth/login-as-user';
-import type { Channel } from 'nhs-notify-web-template-management-types';
+import type {
+ Channel,
+ LetterVariant,
+} from 'nhs-notify-web-template-management-types';
const templateStorageHelper = new TemplateStorageHelper();
-function createTemplates(user: TestUser) {
+function createTemplates(user: TestUser, letterVariant: LetterVariant) {
const templateIds = {
NHSAPP: randomUUID(),
EMAIL: randomUUID(),
@@ -67,6 +73,7 @@ function createTemplates(user: TestUser) {
{
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
LARGE_PRINT_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -78,6 +85,7 @@ function createTemplates(user: TestUser) {
letterType: 'x1',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
BSL_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -89,6 +97,7 @@ function createTemplates(user: TestUser) {
letterType: 'q4',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
ARABIC_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -100,6 +109,7 @@ function createTemplates(user: TestUser) {
language: 'ar',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
POLISH_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -111,6 +121,7 @@ function createTemplates(user: TestUser) {
language: 'pl',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
};
@@ -175,7 +186,10 @@ test.describe('Routing', () => {
user = await context.auth.getTestUser(
testUsers.UserLetterAuthoringEnabled.userId
);
- templates = createTemplates(user);
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
+ templates = createTemplates(user, globalLetterVariant);
await templateStorageHelper.seedTemplateData(Object.values(templates));
});
@@ -198,6 +212,7 @@ test.describe('Routing', () => {
const messageTemplatesPage = new TemplateMgmtMessageTemplatesPage(page);
const messagePlansPage = new RoutingMessagePlansPage(page);
const editMessagePlanPage = new RoutingEditMessagePlanPage(page);
+ const previewMessagePlanPage = new RoutingPreviewMessagePlanPage(page);
await test.step('check initial template statuses', async () => {
await messageTemplatesPage.loadPage();
@@ -445,6 +460,36 @@ test.describe('Routing', () => {
expect(languageTemplateNames).toHaveLength(2);
expect(languageTemplateNames).toContain(templates.ARABIC_LETTER.name);
expect(languageTemplateNames).toContain(templates.POLISH_LETTER.name);
+ });
+
+ await test.step('preview letter template from review page', async () => {
+ const reviewPage = new RoutingReviewAndMoveToProductionPage(page);
+
+ const letterBlock = reviewPage.getTemplateBlock('LETTER');
+
+ const newPagePromise = page.context().waitForEvent('page');
+ await letterBlock.defaultTemplateCard.templateLink.click();
+ const newPage = await newPagePromise;
+ await newPage.waitForLoadState();
+
+ const previewLetterPage =
+ new RoutingReviewAndMoveToProductionPreviewLetterTemplatePage(newPage);
+
+ await expect(previewLetterPage.pageHeading).toContainText(
+ templates.LETTER.name
+ );
+
+ await expect(previewLetterPage.templateId).toContainText(
+ templates.LETTER.id
+ );
+
+ await newPage.close();
+
+ await expect(reviewPage.pageHeading).toBeVisible();
+ });
+
+ await test.step('move to production', async () => {
+ const reviewPage = new RoutingReviewAndMoveToProductionPage(page);
await reviewPage.moveToProductionButton.click();
});
@@ -463,8 +508,34 @@ test.describe('Routing', () => {
);
});
+ await test.step('preview letter template from preview message plan page', async () => {
+ await expect(previewMessagePlanPage.pageHeading).toBeVisible();
+
+ const letterBlock = previewMessagePlanPage.getTemplateBlock('LETTER');
+
+ const newPagePromise = page.context().waitForEvent('page');
+ await letterBlock.defaultTemplateCard.templateLink.click();
+ const newPage = await newPagePromise;
+ await newPage.waitForLoadState();
+
+ const previewLetterPage =
+ new RoutingPreviewMessagePlanPreviewLetterTemplatePage(newPage);
+
+ await expect(previewLetterPage.pageHeading).toContainText(
+ templates.LETTER.name
+ );
+
+ await expect(previewLetterPage.templateId).toContainText(
+ templates.LETTER.id
+ );
+
+ await newPage.close();
+
+ await expect(previewMessagePlanPage.pageHeading).toBeVisible();
+ });
+
await test.step('verify all templates are locked (except removed large print letter)', async () => {
- await messagePlansPage.clickTemplatesHeaderLink();
+ await previewMessagePlanPage.clickTemplatesHeaderLink();
await expect(messageTemplatesPage.pageHeading).toBeVisible();
diff --git a/tests/test-team/template-mgmt-routing-component-tests/letter/preview-british-sign-language-letter-template.routing-component.spec.ts b/tests/test-team/template-mgmt-routing-component-tests/letter/preview-british-sign-language-letter-template.routing-component.spec.ts
index 26776a43c..ec8ea410d 100644
--- a/tests/test-team/template-mgmt-routing-component-tests/letter/preview-british-sign-language-letter-template.routing-component.spec.ts
+++ b/tests/test-team/template-mgmt-routing-component-tests/letter/preview-british-sign-language-letter-template.routing-component.spec.ts
@@ -15,12 +15,20 @@ import { RoutingPreviewBritishSignLanguageLetterTemplatePage } from 'pages/routi
import { RoutingConfigFactory } from 'helpers/factories/routing-config-factory';
import { RoutingConfigStorageHelper } from 'helpers/db/routing-config-storage-helper';
import { getTestContext } from 'helpers/context/context';
+import { LetterVariant } from 'nhs-notify-web-template-management-types';
const routingConfigStorageHelper = new RoutingConfigStorageHelper();
const templateStorageHelper = new TemplateStorageHelper();
const invalidTemplateId = 'invalid-id';
-const notFoundTemplateId = 'dc67b576-af7d-47b3-97d7-48fa204e7525';
+const notFoundTemplateId = randomUUID();
+
+const templateIds = {
+ EMAIL: randomUUID(),
+ STANDARD_LETTER: randomUUID(),
+ BSL_LETTER: randomUUID(),
+ BSL_LETTER_WITHOUT_VARIANT: randomUUID(),
+};
function createMessagePlans(user: TestUser) {
return {
@@ -31,23 +39,41 @@ function createMessagePlans(user: TestUser) {
};
}
-function createTemplates(user: TestUser) {
+function createTemplates(user: TestUser, letterVariant: LetterVariant) {
return {
EMAIL: TemplateFactory.createEmailTemplate(
- randomUUID(),
+ templateIds.EMAIL,
user,
- 'Email template name'
+ `Email template name - ${templateIds.EMAIL}`
),
STANDARD_LETTER: TemplateFactory.createAuthoringLetterTemplate(
- randomUUID(),
+ templateIds.STANDARD_LETTER,
user,
- 'Standard letter template name'
+ `Standard letter template name - ${templateIds.STANDARD_LETTER}`,
+ 'SUBMITTED',
+ {
+ shortFormRender: { status: 'RENDERED' },
+ longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
+ }
),
BSL_LETTER: TemplateFactory.createAuthoringLetterTemplate(
- randomUUID(),
+ templateIds.BSL_LETTER,
user,
- 'BSL letter template name',
+ `BSL letter template name - ${templateIds.BSL_LETTER}`,
'SUBMITTED',
+ {
+ letterType: 'q4',
+ shortFormRender: { status: 'RENDERED' },
+ longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
+ }
+ ),
+ BSL_LETTER_WITHOUT_VARIANT: TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.BSL_LETTER_WITHOUT_VARIANT,
+ user,
+ `BSL letter template no variant - ${templateIds.BSL_LETTER_WITHOUT_VARIANT}`,
+ 'PROOF_APPROVED',
{
letterType: 'q4',
shortFormRender: { status: 'RENDERED' },
@@ -65,8 +91,11 @@ test.describe('Routing - Preview British Sign Language letter template page', ()
const context = getTestContext();
const user = await context.auth.getTestUser(testUsers.User1.userId);
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
messagePlans = createMessagePlans(user);
- templates = createTemplates(user);
+ templates = createTemplates(user, globalLetterVariant);
await routingConfigStorageHelper.seed(Object.values(messagePlans));
await templateStorageHelper.seedTemplateData(Object.values(templates));
@@ -153,10 +182,18 @@ test.describe('Routing - Preview British Sign Language letter template page', ()
await expect(previewBSLLetterTemplatePage.summaryList).toBeVisible();
- expect(templates.BSL_LETTER.campaignId).toBeTruthy();
-
- await expect(previewBSLLetterTemplatePage.campaignId).toContainText(
- templates.BSL_LETTER.campaignId!
+ await expect(
+ previewBSLLetterTemplatePage.letterPreviewHeading
+ ).toBeVisible();
+ await expect(
+ previewBSLLetterTemplatePage.letterPreviewIframe
+ ).toBeVisible();
+
+ await expect(
+ previewBSLLetterTemplatePage.letterPreviewIframe
+ ).toHaveAttribute(
+ 'src',
+ `/templates/files/${templates.BSL_LETTER.clientId}/renders/${templates.BSL_LETTER.id}/initial-render.pdf`
);
});
@@ -215,6 +252,22 @@ test.describe('Routing - Preview British Sign Language letter template page', ()
await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
});
+
+ test('when template does not have a letterVariantId', async ({
+ page,
+ baseURL,
+ }) => {
+ const previewBSLLetterTemplatePage =
+ new RoutingPreviewBritishSignLanguageLetterTemplatePage(page);
+
+ await previewBSLLetterTemplatePage
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.BSL_LETTER_WITHOUT_VARIANT.id)
+ .setSearchParam('lockNumber', '0')
+ .loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
});
test('redirects to the edit message plan page when lockNumber is missing', async ({
diff --git a/tests/test-team/template-mgmt-routing-component-tests/letter/preview-large-print-letter-template.routing-component.spec.ts b/tests/test-team/template-mgmt-routing-component-tests/letter/preview-large-print-letter-template.routing-component.spec.ts
index e964316bc..dc8dd60a6 100644
--- a/tests/test-team/template-mgmt-routing-component-tests/letter/preview-large-print-letter-template.routing-component.spec.ts
+++ b/tests/test-team/template-mgmt-routing-component-tests/letter/preview-large-print-letter-template.routing-component.spec.ts
@@ -15,12 +15,20 @@ import { RoutingPreviewLargePrintLetterTemplatePage } from 'pages/routing/letter
import { RoutingConfigFactory } from 'helpers/factories/routing-config-factory';
import { RoutingConfigStorageHelper } from 'helpers/db/routing-config-storage-helper';
import { getTestContext } from 'helpers/context/context';
+import { LetterVariant } from 'nhs-notify-web-template-management-types';
const routingConfigStorageHelper = new RoutingConfigStorageHelper();
const templateStorageHelper = new TemplateStorageHelper();
const invalidTemplateId = 'invalid-id';
-const notFoundTemplateId = 'dc67b576-af7d-47b3-97d7-48fa204e7525';
+const notFoundTemplateId = randomUUID();
+
+const templateIds = {
+ EMAIL: randomUUID(),
+ STANDARD_LETTER: randomUUID(),
+ LARGE_PRINT_LETTER: randomUUID(),
+ LARGE_PRINT_LETTER_WITHOUT_VARIANT: randomUUID(),
+};
function createMessagePlans(user: TestUser) {
return {
@@ -31,37 +39,48 @@ function createMessagePlans(user: TestUser) {
};
}
-function createTemplates(user: TestUser) {
+function createTemplates(user: TestUser, letterVariant: LetterVariant) {
return {
EMAIL: TemplateFactory.createEmailTemplate(
- randomUUID(),
- user,
- 'Email template name'
- ),
- STANDARD_LETTER: TemplateFactory.uploadPdfLetterTemplate(
- randomUUID(),
+ templateIds.EMAIL,
user,
- 'Standard letter template name'
+ `Email template name - ${templateIds.EMAIL}`
),
- LARGE_PRINT_LETTER: TemplateFactory.uploadPdfLetterTemplate(
- randomUUID(),
+ STANDARD_LETTER: TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.STANDARD_LETTER,
user,
- 'Large print letter template name',
+ `Standard letter template name - ${templateIds.STANDARD_LETTER}`,
'SUBMITTED',
- 'PASSED',
- { letterType: 'x1' }
+ {
+ shortFormRender: { status: 'RENDERED' },
+ longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
+ }
),
- AUTHORING_LARGE_PRINT_LETTER: TemplateFactory.createAuthoringLetterTemplate(
- randomUUID(),
+ LARGE_PRINT_LETTER: TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.LARGE_PRINT_LETTER,
user,
- 'Authoring large print letter template name',
+ `Large print letter template name - ${templateIds.LARGE_PRINT_LETTER}`,
'SUBMITTED',
{
letterType: 'x1',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
+ LARGE_PRINT_LETTER_WITHOUT_VARIANT:
+ TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.LARGE_PRINT_LETTER_WITHOUT_VARIANT,
+ user,
+ `Large print letter template no variant - ${templateIds.LARGE_PRINT_LETTER_WITHOUT_VARIANT}`,
+ 'PROOF_APPROVED',
+ {
+ letterType: 'x1',
+ shortFormRender: { status: 'RENDERED' },
+ longFormRender: { status: 'RENDERED' },
+ }
+ ),
};
}
@@ -73,8 +92,11 @@ test.describe('Routing - Preview large print letter template page', () => {
const context = getTestContext();
const user = await context.auth.getTestUser(testUsers.User1.userId);
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
messagePlans = createMessagePlans(user);
- templates = createTemplates(user);
+ templates = createTemplates(user, globalLetterVariant);
await routingConfigStorageHelper.seed(Object.values(messagePlans));
await templateStorageHelper.seedTemplateData(Object.values(templates));
@@ -159,56 +181,18 @@ test.describe('Routing - Preview large print letter template page', () => {
await expect(previewLargePrintLetterTemplatePage.summaryList).toBeVisible();
- expect(templates.LARGE_PRINT_LETTER.campaignId).toBeTruthy();
-
- await expect(previewLargePrintLetterTemplatePage.campaignId).toContainText(
- templates.LARGE_PRINT_LETTER.campaignId!
- );
-
await expect(
- page.getByText(templates.LARGE_PRINT_LETTER.files!.pdfTemplate!.fileName)
+ previewLargePrintLetterTemplatePage.letterPreviewHeading
).toBeVisible();
-
await expect(
- page.getByText(templates.LARGE_PRINT_LETTER.files!.testDataCsv!.fileName)
+ previewLargePrintLetterTemplatePage.letterPreviewIframe
).toBeVisible();
- });
-
- test('loads the AUTHORING large print letter template', async ({
- page,
- baseURL,
- }) => {
- const previewLargePrintLetterTemplatePage =
- new RoutingPreviewLargePrintLetterTemplatePage(page);
- await previewLargePrintLetterTemplatePage
- .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
- .setPathParam('templateId', templates.AUTHORING_LARGE_PRINT_LETTER.id)
- .setSearchParam('lockNumber', '0')
- .loadPage();
-
- await expect(page).toHaveURL(
- `${baseURL}/templates/message-plans/choose-large-print-letter-template/${messagePlans.LETTER_ROUTING_CONFIG.id}/preview-template/${templates.AUTHORING_LARGE_PRINT_LETTER.id}?lockNumber=0`
- );
await expect(
- previewLargePrintLetterTemplatePage.templateCaption
- ).toContainText('Template');
-
- await expect(previewLargePrintLetterTemplatePage.pageHeading).toContainText(
- templates.AUTHORING_LARGE_PRINT_LETTER.name
- );
-
- await expect(previewLargePrintLetterTemplatePage.templateId).toBeVisible();
- await expect(previewLargePrintLetterTemplatePage.templateId).toContainText(
- templates.AUTHORING_LARGE_PRINT_LETTER.id
- );
-
- await expect(previewLargePrintLetterTemplatePage.summaryList).toBeVisible();
-
- expect(templates.AUTHORING_LARGE_PRINT_LETTER.campaignId).toBeTruthy();
-
- await expect(previewLargePrintLetterTemplatePage.campaignId).toContainText(
- templates.AUTHORING_LARGE_PRINT_LETTER.campaignId!
+ previewLargePrintLetterTemplatePage.letterPreviewIframe
+ ).toHaveAttribute(
+ 'src',
+ `/templates/files/${templates.LARGE_PRINT_LETTER.clientId}/renders/${templates.LARGE_PRINT_LETTER.id}/initial-render.pdf`
);
});
@@ -267,6 +251,25 @@ test.describe('Routing - Preview large print letter template page', () => {
await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
});
+
+ test('when template does not have a letterVariantId', async ({
+ page,
+ baseURL,
+ }) => {
+ const previewLargePrintLetterTemplatePage =
+ new RoutingPreviewLargePrintLetterTemplatePage(page);
+
+ await previewLargePrintLetterTemplatePage
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam(
+ 'templateId',
+ templates.LARGE_PRINT_LETTER_WITHOUT_VARIANT.id
+ )
+ .setSearchParam('lockNumber', '0')
+ .loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
});
test('redirects to the edit message plan page when lockNumber is missing', async ({
diff --git a/tests/test-team/template-mgmt-routing-component-tests/letter/preview-other-language-letter-template.routing-component.spec.ts b/tests/test-team/template-mgmt-routing-component-tests/letter/preview-other-language-letter-template.routing-component.spec.ts
index 6dea884bc..e172c91ff 100644
--- a/tests/test-team/template-mgmt-routing-component-tests/letter/preview-other-language-letter-template.routing-component.spec.ts
+++ b/tests/test-team/template-mgmt-routing-component-tests/letter/preview-other-language-letter-template.routing-component.spec.ts
@@ -15,6 +15,7 @@ import { RoutingPreviewOtherLanguageLetterTemplatePage } from 'pages/routing/let
import { RoutingConfigFactory } from 'helpers/factories/routing-config-factory';
import { RoutingConfigStorageHelper } from 'helpers/db/routing-config-storage-helper';
import { getTestContext } from 'helpers/context/context';
+import { LetterVariant } from 'nhs-notify-web-template-management-types';
const routingConfigStorageHelper = new RoutingConfigStorageHelper();
const templateStorageHelper = new TemplateStorageHelper();
@@ -25,8 +26,8 @@ const notFoundTemplateId = randomUUID();
const templateIds = {
EMAIL: randomUUID(),
STANDARD_LETTER: randomUUID(),
- FRENCH_LETTER: randomUUID(),
AUTHORING_FRENCH_LETTER: randomUUID(),
+ FRENCH_LETTER_WITHOUT_VARIANT: randomUUID(),
};
function createMessagePlans(user: TestUser) {
@@ -38,37 +39,48 @@ function createMessagePlans(user: TestUser) {
};
}
-function createTemplates(user: TestUser) {
+function createTemplates(user: TestUser, letterVariant: LetterVariant) {
return {
EMAIL: TemplateFactory.createEmailTemplate(
templateIds.EMAIL,
user,
- 'Email template name'
+ `Email template name - ${templateIds.EMAIL}`
),
- STANDARD_LETTER: TemplateFactory.uploadPdfLetterTemplate(
+ STANDARD_LETTER: TemplateFactory.createAuthoringLetterTemplate(
templateIds.STANDARD_LETTER,
user,
- 'Standard letter template name'
- ),
- FRENCH_LETTER: TemplateFactory.uploadPdfLetterTemplate(
- templateIds.FRENCH_LETTER,
- user,
- 'French letter template name',
- 'SUBMITTED',
- 'PASSED',
- { language: 'fr' }
+ `Standard letter template name - ${templateIds.STANDARD_LETTER}`,
+ 'PROOF_APPROVED',
+ {
+ shortFormRender: { status: 'RENDERED' },
+ longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
+ }
),
- AUTHORING_FRENCH_LETTER: TemplateFactory.createAuthoringLetterTemplate(
+ FRENCH_LETTER: TemplateFactory.createAuthoringLetterTemplate(
templateIds.AUTHORING_FRENCH_LETTER,
user,
- 'Authoring French letter template name',
+ `French letter template name - ${templateIds.AUTHORING_FRENCH_LETTER}`,
'SUBMITTED',
{
language: 'fr',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
+ FRENCH_LETTER_WITHOUT_VARIANT:
+ TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.FRENCH_LETTER_WITHOUT_VARIANT,
+ user,
+ `French letter template no variant - ${templateIds.FRENCH_LETTER_WITHOUT_VARIANT}`,
+ 'PROOF_APPROVED',
+ {
+ language: 'fr',
+ shortFormRender: { status: 'RENDERED' },
+ longFormRender: { status: 'RENDERED' },
+ }
+ ),
};
}
@@ -80,8 +92,11 @@ test.describe('Routing - Preview foreign language letter template page', () => {
const context = getTestContext();
const user = await context.auth.getTestUser(testUsers.User1.userId);
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
messagePlans = createMessagePlans(user);
- templates = createTemplates(user);
+ templates = createTemplates(user, globalLetterVariant);
await routingConfigStorageHelper.seed(Object.values(messagePlans));
await templateStorageHelper.seedTemplateData(Object.values(templates));
@@ -178,62 +193,19 @@ test.describe('Routing - Preview foreign language letter template page', () => {
previewForeignLanguageLetterTemplatePage.summaryList
).toBeVisible();
- expect(templates.FRENCH_LETTER.campaignId).toBeTruthy();
-
- await expect(
- previewForeignLanguageLetterTemplatePage.campaignId
- ).toContainText(templates.FRENCH_LETTER.campaignId!);
-
await expect(
- page.getByText(templates.FRENCH_LETTER.files!.pdfTemplate!.fileName)
+ previewForeignLanguageLetterTemplatePage.letterPreviewHeading
).toBeVisible();
-
await expect(
- page.getByText(templates.FRENCH_LETTER.files!.testDataCsv!.fileName)
+ previewForeignLanguageLetterTemplatePage.letterPreviewIframe
).toBeVisible();
- });
-
- test('loads the AUTHORING foreign language letter template', async ({
- page,
- baseURL,
- }) => {
- const previewForeignLanguageLetterTemplatePage =
- new RoutingPreviewOtherLanguageLetterTemplatePage(page)
- .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
- .setPathParam('templateId', templates.AUTHORING_FRENCH_LETTER.id)
- .setSearchParam('lockNumber', '0');
- await previewForeignLanguageLetterTemplatePage.loadPage();
- await expect(page).toHaveURL(
- `${baseURL}/templates/message-plans/choose-other-language-letter-template/${messagePlans.LETTER_ROUTING_CONFIG.id}/preview-template/${templates.AUTHORING_FRENCH_LETTER.id}?lockNumber=0`
- );
await expect(
- previewForeignLanguageLetterTemplatePage.templateCaption
- ).toBeVisible();
- await expect(
- previewForeignLanguageLetterTemplatePage.templateCaption
- ).toContainText('Template');
-
- await expect(
- previewForeignLanguageLetterTemplatePage.pageHeading
- ).toContainText(templates.AUTHORING_FRENCH_LETTER.name);
-
- await expect(
- previewForeignLanguageLetterTemplatePage.templateId
- ).toBeVisible();
- await expect(
- previewForeignLanguageLetterTemplatePage.templateId
- ).toContainText(templates.AUTHORING_FRENCH_LETTER.id);
-
- await expect(
- previewForeignLanguageLetterTemplatePage.summaryList
- ).toBeVisible();
-
- expect(templates.AUTHORING_FRENCH_LETTER.campaignId).toBeTruthy();
-
- await expect(
- previewForeignLanguageLetterTemplatePage.campaignId
- ).toContainText(templates.AUTHORING_FRENCH_LETTER.campaignId!);
+ previewForeignLanguageLetterTemplatePage.letterPreviewIframe
+ ).toHaveAttribute(
+ 'src',
+ `/templates/files/${templates.FRENCH_LETTER.clientId}/renders/${templates.FRENCH_LETTER.id}/initial-render.pdf`
+ );
});
test.describe('redirects to invalid template page', () => {
@@ -287,6 +259,24 @@ test.describe('Routing - Preview foreign language letter template page', () => {
await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
});
+
+ test('when template does not have a letterVariantId', async ({
+ page,
+ baseURL,
+ }) => {
+ const previewForeignLanguageLetterTemplatePage =
+ new RoutingPreviewOtherLanguageLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam(
+ 'templateId',
+ templates.FRENCH_LETTER_WITHOUT_VARIANT.id
+ )
+ .setSearchParam('lockNumber', '0');
+
+ await previewForeignLanguageLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
});
test('redirects to the edit message plan page when lockNumber is missing', async ({
diff --git a/tests/test-team/template-mgmt-routing-component-tests/letter/preview-standard-letter-template.routing-component.spec.ts b/tests/test-team/template-mgmt-routing-component-tests/letter/preview-standard-letter-template.routing-component.spec.ts
index 70706e4a2..34c5eb345 100644
--- a/tests/test-team/template-mgmt-routing-component-tests/letter/preview-standard-letter-template.routing-component.spec.ts
+++ b/tests/test-team/template-mgmt-routing-component-tests/letter/preview-standard-letter-template.routing-component.spec.ts
@@ -15,12 +15,19 @@ import { RoutingPreviewStandardLetterTemplatePage } from 'pages/routing/letter/p
import { RoutingConfigFactory } from 'helpers/factories/routing-config-factory';
import { RoutingConfigStorageHelper } from 'helpers/db/routing-config-storage-helper';
import { getTestContext } from 'helpers/context/context';
+import { LetterVariant } from 'nhs-notify-web-template-management-types';
const routingConfigStorageHelper = new RoutingConfigStorageHelper();
const templateStorageHelper = new TemplateStorageHelper();
const invalidTemplateId = 'invalid-id';
-const notFoundTemplateId = 'dc67b576-af7d-47b3-97d7-48fa204e7525';
+const notFoundTemplateId = randomUUID();
+
+const templateIds = {
+ EMAIL: randomUUID(),
+ LETTER: randomUUID(),
+ LETTER_WITHOUT_VARIANT: randomUUID(),
+};
function createMessagePlans(user: TestUser) {
return {
@@ -31,22 +38,33 @@ function createMessagePlans(user: TestUser) {
};
}
-function createTemplates(user: TestUser) {
+function createTemplates(user: TestUser, letterVariant: LetterVariant) {
return {
EMAIL: TemplateFactory.createEmailTemplate(
- randomUUID(),
+ templateIds.EMAIL,
user,
- 'Email template name'
+ `Email template name - ${templateIds.EMAIL}`
),
- LETTER: TemplateFactory.uploadPdfLetterTemplate(
- randomUUID(),
+ LETTER: TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.LETTER,
user,
- 'Letter template name'
+ `Letter template name - ${templateIds.LETTER}`,
+ 'PROOF_APPROVED',
+ {
+ shortFormRender: { status: 'RENDERED' },
+ longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
+ }
),
- AUTHORING_LETTER: TemplateFactory.createAuthoringLetterTemplate(
- randomUUID(),
+ LETTER_WITHOUT_VARIANT: TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.LETTER_WITHOUT_VARIANT,
user,
- 'Authoring letter template name'
+ `Letter template no variant - ${templateIds.LETTER_WITHOUT_VARIANT}`,
+ 'PROOF_APPROVED',
+ {
+ shortFormRender: { status: 'RENDERED' },
+ longFormRender: { status: 'RENDERED' },
+ }
),
};
}
@@ -59,8 +77,11 @@ test.describe('Routing - Preview Letter template page', () => {
const context = getTestContext();
const user = await context.auth.getTestUser(testUsers.User1.userId);
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
messagePlans = createMessagePlans(user);
- templates = createTemplates(user);
+ templates = createTemplates(user, globalLetterVariant);
await routingConfigStorageHelper.seed(Object.values(messagePlans));
await templateStorageHelper.seedTemplateData(Object.values(templates));
@@ -88,7 +109,7 @@ test.describe('Routing - Preview Letter template page', () => {
await assertAndClickBackLinkTop(props);
});
- test('loads the Letter template', async ({ page, baseURL }) => {
+ test('loads the letter template', async ({ page, baseURL }) => {
const previewLetterTemplatePage =
new RoutingPreviewStandardLetterTemplatePage(page)
.setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
@@ -111,44 +132,20 @@ test.describe('Routing - Preview Letter template page', () => {
templates.LETTER.campaignId!
);
- await expect(
- page.getByText(templates.LETTER.files!.pdfTemplate!.fileName)
- ).toBeVisible();
-
- await expect(
- page.getByText(templates.LETTER.files!.testDataCsv!.fileName)
- ).toBeVisible();
- });
-
- test('loads the AUTHORING letter template', async ({ page, baseURL }) => {
- const previewLetterTemplatePage =
- new RoutingPreviewStandardLetterTemplatePage(page)
- .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
- .setPathParam('templateId', templates.AUTHORING_LETTER.id)
- .setSearchParam('lockNumber', '0');
-
- await previewLetterTemplatePage.loadPage();
-
- await expect(page).toHaveURL(
- `${baseURL}/templates/message-plans/choose-standard-english-letter-template/${messagePlans.LETTER_ROUTING_CONFIG.id}/preview-template/${templates.AUTHORING_LETTER.id}?lockNumber=0`
- );
-
- await expect(previewLetterTemplatePage.pageHeading).toContainText(
- templates.AUTHORING_LETTER.name
- );
-
- expect(templates.AUTHORING_LETTER.campaignId).toBeTruthy();
-
- await expect(previewLetterTemplatePage.campaignId).toContainText(
- templates.AUTHORING_LETTER.campaignId!
- );
-
await expect(previewLetterTemplatePage.templateId).toBeVisible();
await expect(previewLetterTemplatePage.templateId).toContainText(
- templates.AUTHORING_LETTER.id
+ templates.LETTER.id
);
await expect(previewLetterTemplatePage.summaryList).toBeVisible();
+
+ await expect(previewLetterTemplatePage.letterPreviewHeading).toBeVisible();
+ await expect(previewLetterTemplatePage.letterPreviewIframe).toBeVisible();
+
+ await expect(previewLetterTemplatePage.letterPreviewIframe).toHaveAttribute(
+ 'src',
+ `/templates/files/${templates.LETTER.clientId}/renders/${templates.LETTER.id}/initial-render.pdf`
+ );
});
test.describe('redirects to invalid template page', () => {
@@ -187,6 +184,21 @@ test.describe('Routing - Preview Letter template page', () => {
await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
});
+
+ test('when template does not have a letterVariantId', async ({
+ page,
+ baseURL,
+ }) => {
+ const previewLetterTemplatePage =
+ new RoutingPreviewStandardLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.LETTER_WITHOUT_VARIANT.id)
+ .setSearchParam('lockNumber', '0');
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
});
test('redirects to the edit message plan page when lockNumber is missing', async ({
diff --git a/tests/test-team/template-mgmt-routing-component-tests/preview-message-plan-preview-letter-template.routing-component.spec.ts b/tests/test-team/template-mgmt-routing-component-tests/preview-message-plan-preview-letter-template.routing-component.spec.ts
new file mode 100644
index 000000000..4f69ab45a
--- /dev/null
+++ b/tests/test-team/template-mgmt-routing-component-tests/preview-message-plan-preview-letter-template.routing-component.spec.ts
@@ -0,0 +1,192 @@
+import { test, expect } from '@playwright/test';
+import {
+ assertFooterLinks,
+ assertSignOutLink,
+ assertHeaderLogoLink,
+ assertSkipToMainContent,
+} from 'helpers/template-mgmt-common.steps';
+import { TestUser, testUsers } from 'helpers/auth/cognito-auth-helper';
+import { TemplateStorageHelper } from 'helpers/db/template-storage-helper';
+import { randomUUID } from 'node:crypto';
+import { TemplateFactory } from 'helpers/factories/template-factory';
+import { RoutingPreviewMessagePlanPreviewLetterTemplatePage } from 'pages/routing/preview-message-plan-letter-template-page';
+import { RoutingConfigFactory } from 'helpers/factories/routing-config-factory';
+import { RoutingConfigStorageHelper } from 'helpers/db/routing-config-storage-helper';
+import { getTestContext } from 'helpers/context/context';
+import { LetterVariant } from 'nhs-notify-web-template-management-types';
+
+const routingConfigStorageHelper = new RoutingConfigStorageHelper();
+const templateStorageHelper = new TemplateStorageHelper();
+
+const invalidTemplateId = 'invalid-id';
+const notFoundTemplateId = randomUUID();
+
+const templateIds = {
+ EMAIL: randomUUID(),
+ LETTER: randomUUID(),
+ LETTER_WITHOUT_VARIANT: randomUUID(),
+};
+
+function createMessagePlans(user: TestUser) {
+ return {
+ LETTER_ROUTING_CONFIG: RoutingConfigFactory.createForMessageOrder(
+ user,
+ 'LETTER'
+ ).dbEntry,
+ };
+}
+
+function createTemplates(user: TestUser, letterVariant: LetterVariant) {
+ return {
+ EMAIL: TemplateFactory.createEmailTemplate(
+ templateIds.EMAIL,
+ user,
+ `Test Email template - ${templateIds.EMAIL}`
+ ),
+ LETTER: TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.LETTER,
+ user,
+ `Test Letter template - ${templateIds.LETTER}`,
+ 'PROOF_APPROVED',
+ {
+ letterVariantId: letterVariant.id,
+ longFormRender: { status: 'RENDERED' },
+ shortFormRender: { status: 'RENDERED' },
+ }
+ ),
+ LETTER_WITHOUT_VARIANT: TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.LETTER_WITHOUT_VARIANT,
+ user,
+ `Test Letter template no variant - ${templateIds.LETTER_WITHOUT_VARIANT}`,
+ 'PROOF_APPROVED',
+ {
+ longFormRender: { status: 'RENDERED' },
+ shortFormRender: { status: 'RENDERED' },
+ }
+ ),
+ };
+}
+
+test.describe('Routing - Preview Message Plan / Preview Letter template page', () => {
+ let messagePlans: ReturnType;
+ let templates: ReturnType;
+
+ test.beforeAll(async () => {
+ const context = getTestContext();
+ const user = await context.auth.getTestUser(testUsers.User1.userId);
+
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
+ messagePlans = createMessagePlans(user);
+ templates = createTemplates(user, globalLetterVariant);
+
+ await routingConfigStorageHelper.seed(Object.values(messagePlans));
+ await templateStorageHelper.seedTemplateData(Object.values(templates));
+ });
+
+ test.afterAll(async () => {
+ await routingConfigStorageHelper.deleteSeeded();
+ await templateStorageHelper.deleteSeededTemplates();
+ });
+
+ test('common page tests', async ({ page, baseURL }) => {
+ const props = {
+ page: new RoutingPreviewMessagePlanPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.LETTER.id),
+ baseURL,
+ };
+ await assertSkipToMainContent(props);
+ await assertHeaderLogoLink(props);
+ await assertFooterLinks(props);
+ await assertSignOutLink(props);
+ });
+
+ test('loads the letter template', async ({ page, baseURL }) => {
+ const previewLetterTemplatePage =
+ new RoutingPreviewMessagePlanPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.LETTER.id);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(
+ `${baseURL}/templates/message-plans/preview-message-plan/${messagePlans.LETTER_ROUTING_CONFIG.id}/preview-template/${templates.LETTER.id}`
+ );
+
+ await expect(previewLetterTemplatePage.pageHeading).toContainText(
+ templates.LETTER.name
+ );
+
+ expect(templates.LETTER.campaignId).toBeTruthy();
+
+ await expect(previewLetterTemplatePage.campaignId).toContainText(
+ templates.LETTER.campaignId!
+ );
+
+ await expect(previewLetterTemplatePage.templateId).toBeVisible();
+ await expect(previewLetterTemplatePage.templateId).toContainText(
+ templates.LETTER.id
+ );
+
+ await expect(previewLetterTemplatePage.summaryList).toBeVisible();
+
+ await expect(previewLetterTemplatePage.letterPreviewHeading).toBeVisible();
+ await expect(previewLetterTemplatePage.letterPreviewIframe).toBeVisible();
+
+ await expect(previewLetterTemplatePage.letterPreviewIframe).toHaveAttribute(
+ 'src',
+ `/templates/files/${templates.LETTER.clientId}/renders/${templates.LETTER.id}/initial-render.pdf`
+ );
+ });
+
+ test.describe('redirects to invalid template page', () => {
+ test('when template cannot be found', async ({ page, baseURL }) => {
+ const previewLetterTemplatePage =
+ new RoutingPreviewMessagePlanPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', notFoundTemplateId);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
+
+ test('when template ID is invalid', async ({ page, baseURL }) => {
+ const previewLetterTemplatePage =
+ new RoutingPreviewMessagePlanPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', invalidTemplateId);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
+
+ test('when template is not a letter', async ({ page, baseURL }) => {
+ const previewLetterTemplatePage =
+ new RoutingPreviewMessagePlanPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.EMAIL.id);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
+
+ test('when template does not have a letterVariantId', async ({
+ page,
+ baseURL,
+ }) => {
+ const previewLetterTemplatePage =
+ new RoutingPreviewMessagePlanPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.LETTER_WITHOUT_VARIANT.id);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
+ });
+});
diff --git a/tests/test-team/template-mgmt-routing-component-tests/preview-message-plan.routing-component.spec.ts b/tests/test-team/template-mgmt-routing-component-tests/preview-message-plan.routing-component.spec.ts
index 7d1d953bc..0606b8373 100644
--- a/tests/test-team/template-mgmt-routing-component-tests/preview-message-plan.routing-component.spec.ts
+++ b/tests/test-team/template-mgmt-routing-component-tests/preview-message-plan.routing-component.spec.ts
@@ -1,5 +1,8 @@
import { randomUUID } from 'node:crypto';
-import type { Channel } from 'nhs-notify-web-template-management-types';
+import type {
+ Channel,
+ LetterVariant,
+} from 'nhs-notify-web-template-management-types';
import { test, expect } from '@playwright/test';
import { TestUser, testUsers } from 'helpers/auth/cognito-auth-helper';
import { RoutingConfigStorageHelper } from 'helpers/db/routing-config-storage-helper';
@@ -21,7 +24,7 @@ import { getTestContext } from 'helpers/context/context';
const routingConfigStorageHelper = new RoutingConfigStorageHelper();
const templateStorageHelper = new TemplateStorageHelper();
-function createTemplates(user: TestUser) {
+function createTemplates(user: TestUser, letterVariant: LetterVariant) {
const templateIds = {
NHSAPP: randomUUID(),
EMAIL: randomUUID(),
@@ -52,11 +55,16 @@ function createTemplates(user: TestUser) {
`Test SMS template - ${templateIds.SMS}`,
'SUBMITTED'
),
- LETTER: TemplateFactory.uploadPdfLetterTemplate(
+ LETTER: TemplateFactory.createAuthoringLetterTemplate(
templateIds.LETTER,
user,
`Test Letter template - ${templateIds.LETTER}`,
- 'SUBMITTED'
+ 'SUBMITTED',
+ {
+ letterVariantId: letterVariant.id,
+ shortFormRender: { status: 'RENDERED' },
+ longFormRender: { status: 'RENDERED' },
+ }
),
LARGE_PRINT_LETTER: TemplateFactory.createAuthoringLetterTemplate(
templateIds.LARGE_PRINT_LETTER,
@@ -67,6 +75,7 @@ function createTemplates(user: TestUser) {
letterType: 'x1',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
BSL_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -78,6 +87,7 @@ function createTemplates(user: TestUser) {
letterType: 'q4',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
FRENCH_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -89,6 +99,7 @@ function createTemplates(user: TestUser) {
language: 'fr',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
SPANISH_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -100,6 +111,7 @@ function createTemplates(user: TestUser) {
language: 'es',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
};
@@ -113,7 +125,11 @@ test.describe('Routing - Preview Message Plan page', () => {
test.beforeAll(async () => {
const context = getTestContext();
user = await context.auth.getTestUser(testUsers.User1.userId);
- templates = createTemplates(user);
+
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
+ templates = createTemplates(user, globalLetterVariant);
await templateStorageHelper.seedTemplateData(Object.values(templates));
});
@@ -226,7 +242,7 @@ test.describe('Routing - Preview Message Plan page', () => {
}
await expect(previewMessagePlanPage.previewToggleButton).toHaveText(
- 'Open all template previews'
+ 'Open all digital template previews'
);
await previewMessagePlanPage.previewToggleButton.click();
@@ -236,7 +252,7 @@ test.describe('Routing - Preview Message Plan page', () => {
}
await expect(previewMessagePlanPage.previewToggleButton).toHaveText(
- 'Close all template previews'
+ 'Close all digital template previews'
);
await previewMessagePlanPage.previewToggleButton.click();
@@ -246,7 +262,7 @@ test.describe('Routing - Preview Message Plan page', () => {
}
await expect(previewMessagePlanPage.previewToggleButton).toHaveText(
- 'Open all template previews'
+ 'Open all digital template previews'
);
});
@@ -292,36 +308,43 @@ test.describe('Routing - Preview Message Plan page', () => {
templateBlock.defaultTemplateCard.previewTemplateSummary
).toBeHidden();
- await expect(templateBlock.defaultTemplateCard.templateLink).toHaveText(
+ await expect(templateBlock.defaultTemplateCard.templateName).toHaveText(
templates.LETTER.name
);
+ await expect(templateBlock.defaultTemplateCard.templateLink).toHaveText(
+ 'Preview template (opens in a new tab)'
+ );
await expect(
templateBlock.defaultTemplateCard.templateLink
).toHaveAttribute(
'href',
- `/templates/preview-submitted-letter-template/${templates.LETTER.id}`
+ `/templates/message-plans/preview-message-plan/${dbEntry.id}/preview-template/${templates.LETTER.id}`
);
+ await expect(
+ templateBlock.defaultTemplateCard.templateLink
+ ).toHaveAttribute('target', '_blank');
+
await expect(
templateBlock.getAccessibilityFormatCard('x1').templateLink
- ).toHaveText(templates.LARGE_PRINT_LETTER.name);
+ ).toHaveText('Preview template (opens in a new tab)');
await expect(
templateBlock.getAccessibilityFormatCard('x1').templateLink
).toHaveAttribute(
'href',
- `/templates/preview-submitted-letter-template/${templates.LARGE_PRINT_LETTER.id}`
+ `/templates/message-plans/preview-message-plan/${dbEntry.id}/preview-template/${templates.LARGE_PRINT_LETTER.id}`
);
await expect(
templateBlock.getAccessibilityFormatCard('q4').templateLink
- ).toHaveText(templates.BSL_LETTER.name);
+ ).toHaveText('Preview template (opens in a new tab)');
await expect(
templateBlock.getAccessibilityFormatCard('q4').templateLink
).toHaveAttribute(
'href',
- `/templates/preview-submitted-letter-template/${templates.BSL_LETTER.id}`
+ `/templates/message-plans/preview-message-plan/${dbEntry.id}/preview-template/${templates.BSL_LETTER.id}`
);
for (const [index, language] of (
@@ -330,19 +353,27 @@ test.describe('Routing - Preview Message Plan page', () => {
>)[]
).entries()) {
const links = await templateBlock.getLanguagesCard().templateLink.all();
- await expect(links[index]).toHaveText(templates[language].name);
+ await expect(links[index]).toHaveText(
+ 'Preview template (opens in a new tab)'
+ );
await expect(links[index]).toHaveAttribute(
'href',
- `/templates/preview-submitted-letter-template/${templates[language].id}`
+ `/templates/message-plans/preview-message-plan/${dbEntry.id}/preview-template/${templates[language].id}`
);
+ await expect(links[index]).toHaveAttribute('target', '_blank');
}
- await templateBlock.defaultTemplateCard.templateLink.click();
+ const [newTab] = await Promise.all([
+ page.context().waitForEvent('page'),
+ templateBlock.defaultTemplateCard.templateLink.click(),
+ ]);
- await expect(page).toHaveURL(
- `/templates/preview-submitted-letter-template/${templates.LETTER.id}`
+ await expect(newTab).toHaveURL(
+ `/templates/message-plans/preview-message-plan/${dbEntry.id}/preview-template/${templates.LETTER.id}`
);
+
+ await newTab.close();
});
});
diff --git a/tests/test-team/template-mgmt-routing-component-tests/review-and-move-to-production-preview-letter-template.routing-component.spec.ts b/tests/test-team/template-mgmt-routing-component-tests/review-and-move-to-production-preview-letter-template.routing-component.spec.ts
new file mode 100644
index 000000000..e3587f3a5
--- /dev/null
+++ b/tests/test-team/template-mgmt-routing-component-tests/review-and-move-to-production-preview-letter-template.routing-component.spec.ts
@@ -0,0 +1,192 @@
+import { test, expect } from '@playwright/test';
+import {
+ assertFooterLinks,
+ assertSignOutLink,
+ assertHeaderLogoLink,
+ assertSkipToMainContent,
+} from 'helpers/template-mgmt-common.steps';
+import { TestUser, testUsers } from 'helpers/auth/cognito-auth-helper';
+import { TemplateStorageHelper } from 'helpers/db/template-storage-helper';
+import { randomUUID } from 'node:crypto';
+import { TemplateFactory } from 'helpers/factories/template-factory';
+import { RoutingReviewAndMoveToProductionPreviewLetterTemplatePage } from 'pages/routing/review-and-move-to-production-letter-template-page';
+import { RoutingConfigFactory } from 'helpers/factories/routing-config-factory';
+import { RoutingConfigStorageHelper } from 'helpers/db/routing-config-storage-helper';
+import { getTestContext } from 'helpers/context/context';
+import { LetterVariant } from 'nhs-notify-web-template-management-types';
+
+const routingConfigStorageHelper = new RoutingConfigStorageHelper();
+const templateStorageHelper = new TemplateStorageHelper();
+
+const invalidTemplateId = 'invalid-id';
+const notFoundTemplateId = randomUUID();
+
+const templateIds = {
+ EMAIL: randomUUID(),
+ LETTER: randomUUID(),
+ LETTER_WITHOUT_VARIANT: randomUUID(),
+};
+
+function createMessagePlans(user: TestUser) {
+ return {
+ LETTER_ROUTING_CONFIG: RoutingConfigFactory.createForMessageOrder(
+ user,
+ 'LETTER'
+ ).dbEntry,
+ };
+}
+
+function createTemplates(user: TestUser, letterVariant: LetterVariant) {
+ return {
+ EMAIL: TemplateFactory.createEmailTemplate(
+ templateIds.EMAIL,
+ user,
+ `Test Email template - ${templateIds.EMAIL}`
+ ),
+ LETTER: TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.LETTER,
+ user,
+ `Test Letter template - ${templateIds.LETTER}`,
+ 'PROOF_APPROVED',
+ {
+ letterVariantId: letterVariant.id,
+ longFormRender: { status: 'RENDERED' },
+ shortFormRender: { status: 'RENDERED' },
+ }
+ ),
+ LETTER_WITHOUT_VARIANT: TemplateFactory.createAuthoringLetterTemplate(
+ templateIds.LETTER_WITHOUT_VARIANT,
+ user,
+ `Test Letter template no variant - ${templateIds.LETTER_WITHOUT_VARIANT}`,
+ 'PROOF_APPROVED',
+ {
+ longFormRender: { status: 'RENDERED' },
+ shortFormRender: { status: 'RENDERED' },
+ }
+ ),
+ };
+}
+
+test.describe('Routing - Review and Move to Production / Preview Letter template page', () => {
+ let messagePlans: ReturnType;
+ let templates: ReturnType;
+
+ test.beforeAll(async () => {
+ const context = getTestContext();
+ const user = await context.auth.getTestUser(testUsers.User1.userId);
+
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
+ messagePlans = createMessagePlans(user);
+ templates = createTemplates(user, globalLetterVariant);
+
+ await routingConfigStorageHelper.seed(Object.values(messagePlans));
+ await templateStorageHelper.seedTemplateData(Object.values(templates));
+ });
+
+ test.afterAll(async () => {
+ await routingConfigStorageHelper.deleteSeeded();
+ await templateStorageHelper.deleteSeededTemplates();
+ });
+
+ test('common page tests', async ({ page, baseURL }) => {
+ const props = {
+ page: new RoutingReviewAndMoveToProductionPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.LETTER.id),
+ baseURL,
+ };
+ await assertSkipToMainContent(props);
+ await assertHeaderLogoLink(props);
+ await assertFooterLinks(props);
+ await assertSignOutLink(props);
+ });
+
+ test('loads the AUTHORING letter template', async ({ page, baseURL }) => {
+ const previewLetterTemplatePage =
+ new RoutingReviewAndMoveToProductionPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.LETTER.id);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(
+ `${baseURL}/templates/message-plans/review-and-move-to-production/${messagePlans.LETTER_ROUTING_CONFIG.id}/preview-template/${templates.LETTER.id}`
+ );
+
+ await expect(previewLetterTemplatePage.pageHeading).toContainText(
+ templates.LETTER.name
+ );
+
+ expect(templates.LETTER.campaignId).toBeTruthy();
+
+ await expect(previewLetterTemplatePage.campaignId).toContainText(
+ templates.LETTER.campaignId!
+ );
+
+ await expect(previewLetterTemplatePage.templateId).toBeVisible();
+ await expect(previewLetterTemplatePage.templateId).toContainText(
+ templates.LETTER.id
+ );
+
+ await expect(previewLetterTemplatePage.summaryList).toBeVisible();
+
+ await expect(previewLetterTemplatePage.letterPreviewHeading).toBeVisible();
+ await expect(previewLetterTemplatePage.letterPreviewIframe).toBeVisible();
+
+ await expect(previewLetterTemplatePage.letterPreviewIframe).toHaveAttribute(
+ 'src',
+ `/templates/files/${templates.LETTER.clientId}/renders/${templates.LETTER.id}/initial-render.pdf`
+ );
+ });
+
+ test.describe('redirects to invalid template page', () => {
+ test('when template cannot be found', async ({ page, baseURL }) => {
+ const previewLetterTemplatePage =
+ new RoutingReviewAndMoveToProductionPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', notFoundTemplateId);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
+
+ test('when template ID is invalid', async ({ page, baseURL }) => {
+ const previewLetterTemplatePage =
+ new RoutingReviewAndMoveToProductionPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', invalidTemplateId);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
+
+ test('when template is not letter', async ({ page, baseURL }) => {
+ const previewLetterTemplatePage =
+ new RoutingReviewAndMoveToProductionPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.EMAIL.id);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
+
+ test('when template does not have a letterVariantId', async ({
+ page,
+ baseURL,
+ }) => {
+ const previewLetterTemplatePage =
+ new RoutingReviewAndMoveToProductionPreviewLetterTemplatePage(page)
+ .setPathParam('messagePlanId', messagePlans.LETTER_ROUTING_CONFIG.id)
+ .setPathParam('templateId', templates.LETTER_WITHOUT_VARIANT.id);
+
+ await previewLetterTemplatePage.loadPage();
+
+ await expect(page).toHaveURL(`${baseURL}/templates/invalid-template`);
+ });
+ });
+});
diff --git a/tests/test-team/template-mgmt-routing-component-tests/review-and-move-to-production.routing-component.spec.ts b/tests/test-team/template-mgmt-routing-component-tests/review-and-move-to-production.routing-component.spec.ts
index dd2bafe55..6be7e7346 100644
--- a/tests/test-team/template-mgmt-routing-component-tests/review-and-move-to-production.routing-component.spec.ts
+++ b/tests/test-team/template-mgmt-routing-component-tests/review-and-move-to-production.routing-component.spec.ts
@@ -1,5 +1,8 @@
import { randomUUID } from 'node:crypto';
-import type { Channel } from 'nhs-notify-web-template-management-types';
+import type {
+ Channel,
+ LetterVariant,
+} from 'nhs-notify-web-template-management-types';
import { test, expect } from '@playwright/test';
import { TestUser, testUsers } from 'helpers/auth/cognito-auth-helper';
import { RoutingConfigStorageHelper } from 'helpers/db/routing-config-storage-helper';
@@ -20,7 +23,7 @@ import { getTestContext } from 'helpers/context/context';
const routingConfigStorageHelper = new RoutingConfigStorageHelper();
const templateStorageHelper = new TemplateStorageHelper();
-function createTemplates(user: TestUser) {
+function createTemplates(user: TestUser, letterVariant: LetterVariant) {
const templateIds = {
NHSAPP: randomUUID(),
EMAIL: randomUUID(),
@@ -55,6 +58,7 @@ function createTemplates(user: TestUser) {
`Test Letter template - ${templateIds.LETTER}`,
'SUBMITTED',
{
+ letterVariantId: letterVariant.id,
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
}
@@ -68,6 +72,7 @@ function createTemplates(user: TestUser) {
letterType: 'x1',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
BSL_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -79,6 +84,7 @@ function createTemplates(user: TestUser) {
letterType: 'q4',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
FRENCH_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -90,6 +96,7 @@ function createTemplates(user: TestUser) {
language: 'fr',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
SPANISH_LETTER: TemplateFactory.createAuthoringLetterTemplate(
@@ -101,6 +108,7 @@ function createTemplates(user: TestUser) {
language: 'es',
shortFormRender: { status: 'RENDERED' },
longFormRender: { status: 'RENDERED' },
+ letterVariantId: letterVariant.id,
}
),
};
@@ -114,7 +122,11 @@ test.describe('Routing - Review and Move to Production page', () => {
test.beforeAll(async () => {
const context = getTestContext();
user = await context.auth.getTestUser(testUsers.User1.userId);
- templates = createTemplates(user);
+
+ const [globalLetterVariant] =
+ await context.letterVariants.getGlobalLetterVariants();
+
+ templates = createTemplates(user, globalLetterVariant);
await templateStorageHelper.seedTemplateData(Object.values(templates));
});
@@ -230,7 +242,7 @@ test.describe('Routing - Review and Move to Production page', () => {
}
await expect(reviewPage.previewToggleButton).toHaveText(
- 'Open all template previews'
+ 'Open all digital template previews'
);
await reviewPage.previewToggleButton.click();
@@ -240,7 +252,7 @@ test.describe('Routing - Review and Move to Production page', () => {
}
await expect(reviewPage.previewToggleButton).toHaveText(
- 'Close all template previews'
+ 'Close all digital template previews'
);
await reviewPage.previewToggleButton.click();
@@ -250,7 +262,7 @@ test.describe('Routing - Review and Move to Production page', () => {
}
await expect(reviewPage.previewToggleButton).toHaveText(
- 'Open all template previews'
+ 'Open all digital template previews'
);
});
@@ -292,51 +304,76 @@ test.describe('Routing - Review and Move to Production page', () => {
templateBlock.defaultTemplateCard.previewTemplateSummary
).toBeHidden();
- await expect(templateBlock.defaultTemplateCard.templateLink).toHaveText(
+ await expect(templateBlock.defaultTemplateCard.templateName).toHaveText(
templates.LETTER.name
);
+ await expect(templateBlock.defaultTemplateCard.templateLink).toHaveText(
+ 'Preview template (opens in a new tab)'
+ );
await expect(
templateBlock.defaultTemplateCard.templateLink
).toHaveAttribute(
'href',
- `/templates/preview-submitted-letter-template/${templates.LETTER.id}`
+ `/templates/message-plans/review-and-move-to-production/${dbEntry.id}/preview-template/${templates.LETTER.id}`
);
+ await expect(
+ templateBlock.defaultTemplateCard.templateLink
+ ).toHaveAttribute('target', '_blank');
+
await expect(
templateBlock.getAccessibilityFormatCard('x1').templateLink
- ).toHaveText(templates.LARGE_PRINT_LETTER.name);
+ ).toHaveText('Preview template (opens in a new tab)');
await expect(
templateBlock.getAccessibilityFormatCard('x1').templateLink
).toHaveAttribute(
'href',
- `/templates/preview-letter-template/${templates.LARGE_PRINT_LETTER.id}`
+ `/templates/message-plans/review-and-move-to-production/${dbEntry.id}/preview-template/${templates.LARGE_PRINT_LETTER.id}`
);
await expect(
templateBlock.getAccessibilityFormatCard('q4').templateLink
- ).toHaveText(templates.BSL_LETTER.name);
+ ).toHaveText('Preview template (opens in a new tab)');
await expect(
templateBlock.getAccessibilityFormatCard('q4').templateLink
).toHaveAttribute(
'href',
- `/templates/preview-letter-template/${templates.BSL_LETTER.id}`
+ `/templates/message-plans/review-and-move-to-production/${dbEntry.id}/preview-template/${templates.BSL_LETTER.id}`
);
+ await expect(
+ templateBlock.getAccessibilityFormatCard('q4').templateLink
+ ).toHaveAttribute('target', '_blank');
+
for (const [index, language] of (
['FRENCH_LETTER', 'SPANISH_LETTER'] satisfies (keyof ReturnType<
typeof createTemplates
>)[]
).entries()) {
const links = await templateBlock.getLanguagesCard().templateLink.all();
- await expect(links[index]).toHaveText(templates[language].name);
+ await expect(links[index]).toHaveText(
+ 'Preview template (opens in a new tab)'
+ );
await expect(links[index]).toHaveAttribute(
'href',
- `/templates/preview-letter-template/${templates[language].id}`
+ `/templates/message-plans/review-and-move-to-production/${dbEntry.id}/preview-template/${templates[language].id}`
);
+ await expect(links[index]).toHaveAttribute('target', '_blank');
}
+
+ const [newTab] = await Promise.all([
+ page.context().waitForEvent('page'),
+ templateBlock.defaultTemplateCard.templateLink.click(),
+ ]);
+
+ await expect(newTab).toHaveURL(
+ `/templates/message-plans/review-and-move-to-production/${dbEntry.id}/preview-template/${templates.LETTER.id}`
+ );
+
+ await newTab.close();
});
});
diff --git a/utils/utils/src/zod-validators.ts b/utils/utils/src/zod-validators.ts
index 130c96e27..dab668804 100644
--- a/utils/utils/src/zod-validators.ts
+++ b/utils/utils/src/zod-validators.ts
@@ -150,6 +150,9 @@ export const validateEmailTemplate = (template?: TemplateDto) =>
export const validateLetterTemplate = (template?: TemplateDto) =>
zodValidate($LetterTemplate, template);
+export const validateAuthoringLetterTemplate = (template?: TemplateDto) =>
+ zodValidate($AuthoringLetterTemplate, template);
+
export const validateLargePrintLetterTemplate = (template?: TemplateDto) =>
zodValidate($LargePrintLetterTemplate, template);