diff --git a/.github/workflows/stage-1-commit.yaml b/.github/workflows/stage-1-commit.yaml index 7b0e2a4e..b4d7f966 100644 --- a/.github/workflows/stage-1-commit.yaml +++ b/.github/workflows/stage-1-commit.yaml @@ -144,7 +144,7 @@ jobs: npm ci --strict-peer-deps - name: "Check types with tsc" run: | - tsc --noEmit + npx tsc --noEmit - name: "Run linting check" run: | make test-lint diff --git a/.tool-versions b/.tool-versions index afe3f576..f108ae85 100644 --- a/.tool-versions +++ b/.tool-versions @@ -4,6 +4,7 @@ terraform 1.11.2 pre-commit 3.6.0 vale 3.6.0 nodejs 22.13.1 +gitleaks 8.30.1 # ============================================================================== # The section below is reserved for Docker image versions. diff --git a/e2e/elid-copy-helper.ts b/e2e/elid-copy-helper.ts index 83fa6307..e7685370 100644 --- a/e2e/elid-copy-helper.ts +++ b/e2e/elid-copy-helper.ts @@ -20,12 +20,12 @@ export const elidCopyThatDiffersByEnvironment: Record = { }, ["integration"]: { user15: { - bulletPoint2: "did not turn 80 after 1 September 2024", + bulletPoint2: "do not live in a care home for older adults", infoTextHeading: "If you think this is incorrect", infoTextParagraph: "Speak to your healthcare professional if you think you should be offered this vaccine.", }, user01: { - bulletPoint1: "are aged between 75 and 79", + bulletPoint1: "are aged 75 or over", }, user13: { cardParagraphTextv1: "We believe you had the RSV vaccination on 3 April 2025.", diff --git a/e2e/general/eligibility.spec.ts b/e2e/general/eligibility.spec.ts index bb139679..2df58502 100644 --- a/e2e/general/eligibility.spec.ts +++ b/e2e/general/eligibility.spec.ts @@ -28,7 +28,7 @@ test.describe("Eligibility", () => { level: 2, name: "We do not believe you can have it", }); - const bulletPoint1: Locator = eligibility.getByText("are not aged 75 to 79", { exact: true }).first(); + const bulletPoint1: Locator = eligibility.getByText("are not aged 75 or over", { exact: true }).first(); const bulletPoint2: Locator = eligibility .getByText(elidCopyForEnvironment.user15.bulletPoint2, { exact: true }) .first(); diff --git a/scripts/config/pre-commit.yaml b/scripts/config/pre-commit.yaml index 1fd6a7fd..0211b575 100644 --- a/scripts/config/pre-commit.yaml +++ b/scripts/config/pre-commit.yaml @@ -3,7 +3,7 @@ repos: hooks: - id: check-types name: Check types with tsc - entry: tsc --noEmit + entry: npx tsc --noEmit language: system pass_filenames: false - id: run-prettier diff --git a/src/app/_components/eligibility/RSVEligibilityFallback.test.tsx b/src/app/_components/eligibility/RSVEligibilityFallback.test.tsx index 9317a9eb..6a52fc88 100644 --- a/src/app/_components/eligibility/RSVEligibilityFallback.test.tsx +++ b/src/app/_components/eligibility/RSVEligibilityFallback.test.tsx @@ -1,22 +1,13 @@ import { RSVEligibilityFallback } from "@src/app/_components/eligibility/RSVEligibilityFallback"; -import { PharmacyBookingInfo } from "@src/app/_components/nbs/PharmacyBookingInfo"; import { VaccineTypes } from "@src/models/vaccine"; import { render, screen, within } from "@testing-library/react"; -jest.mock("@src/app/_components/nbs/PharmacyBookingInfo", () => ({ - PharmacyBookingInfo: jest - .fn() - .mockImplementation(() =>

Pharmacy booking test

), -})); - describe("RSVEligibilityFallback", () => { const vaccineType = VaccineTypes.RSV; const howToGetVaccineFallback =
How Section styled component
; it("should display fallback care card", async () => { - await render( - , - ); + render(); const fallbackHeading: HTMLElement = screen.getByText("The RSV vaccine is recommended if you:"); const fallbackBulletPoint1: HTMLElement = screen.getByText("are aged 75 or over"); @@ -27,27 +18,13 @@ describe("RSVEligibilityFallback", () => { expect(fallbackBulletPoint2).toBeVisible(); }); - it("should include Pharmacy booking info for specified vaccine", () => { - render(); - - const pharmacyBookingInfo: HTMLElement = screen.getByTestId("pharmacy-booking-info"); - expect(pharmacyBookingInfo).toBeVisible(); - - expect(PharmacyBookingInfo).toHaveBeenCalledWith( - { - vaccineType: vaccineType, - }, - undefined, - ); - }); - - it("should display 'If this applies' paragraph with provided how-to-get content", async () => { + it("should display provided how-to-get content", async () => { render(); const fallback = screen.getByTestId("elid-fallback"); const fallbackHeading: HTMLElement = within(fallback).getByRole("heading", { - name: "If this applies to you", + name: "", level: 3, }); const howToGetContent: HTMLElement = within(fallback).getByText("How Section styled component"); diff --git a/src/app/_components/eligibility/RSVEligibilityFallback.tsx b/src/app/_components/eligibility/RSVEligibilityFallback.tsx index f437434a..c23bdf97 100644 --- a/src/app/_components/eligibility/RSVEligibilityFallback.tsx +++ b/src/app/_components/eligibility/RSVEligibilityFallback.tsx @@ -1,8 +1,6 @@ -import { PharmacyBookingInfo } from "@src/app/_components/nbs/PharmacyBookingInfo"; import Expander from "@src/app/_components/nhs-frontend/Expander"; import NonUrgentCareCard from "@src/app/_components/nhs-frontend/NonUrgentCareCard"; import styles from "@src/app/_components/vaccine/styles.module.css"; -import { HEADINGS } from "@src/app/constants"; import { VaccineTypes } from "@src/models/vaccine"; import React, { JSX } from "react"; @@ -23,8 +21,7 @@ const RSVEligibilityFallback = (props: { } /> - - +
); diff --git a/src/app/constants.ts b/src/app/constants.ts index a400d7ee..e43b3d47 100644 --- a/src/app/constants.ts +++ b/src/app/constants.ts @@ -7,5 +7,4 @@ export const HEADINGS = { WHAT_VACCINE_IS_FOR: "What this vaccine is for", WHO_SHOULD_HAVE_VACCINE: "Who should have this vaccine", HOW_TO_GET_VACCINE: "How to get the vaccine", - IF_THIS_APPLIES: "If this applies to you", }; diff --git a/src/services/content-api/parsers/content-styling-service.test.tsx b/src/services/content-api/parsers/content-styling-service.test.tsx index aad8b25f..9c6ab5f6 100644 --- a/src/services/content-api/parsers/content-styling-service.test.tsx +++ b/src/services/content-api/parsers/content-styling-service.test.tsx @@ -20,6 +20,9 @@ const mockNBSBookingActionHTML = "NBS Booking Link Test"; jest.mock("@src/app/_components/nbs/NBSBookingAction", () => ({ NBSBookingAction: () => mockNBSBookingActionHTML, })); +jest.mock("@src/app/_components/nbs/PharmacyBookingInfo", () => ({ + PharmacyBookingInfo: () =>
Pharmacy Booking Info
, +})); jest.mock("sanitize-data", () => ({ sanitize: jest.fn() })); describe("ContentStylingService", () => { @@ -32,7 +35,7 @@ describe("ContentStylingService", () => { const mockRsvMarkdownSubsection: VaccinePageSubsection = { type: "simpleElement", - text: "

para

If you're aged 75 to 79

para1

para2

If you're pregnant

para3

para4

", + text: "

para

If you're aged 75 or over

para1

para2

If you live in a care home for older adults

para3

para4

If you're pregnant

para5

para6

", name: "markdown", headline: "Headline", }; @@ -209,8 +212,9 @@ describe("ContentStylingService", () => { expect(styledVaccineContent.whoVaccineIsFor.heading).toEqual("Who is this Vaccine For"); expect(styledVaccineContent.howToGetVaccine.heading).toEqual("How to get this Vaccine"); - const expectedRsvSection = "

para1

para2

"; - const expectedRsvPregnancySection = `

para3

para4

`; + const expectedRsvSection = + "

If you're aged 75 or over

para1

para2

Pharmacy Booking Info

If you live in a care home for older adults

para3

para4

"; + const expectedRsvPregnancySection = `

para5

para6

`; const { container } = render(styledVaccineContent.howToGetVaccine.component); if (vaccine === VaccineTypes.RSV) { expect(container).toContainHTML(expectedRsvSection); diff --git a/src/services/content-api/parsers/custom/both.test.tsx b/src/services/content-api/parsers/custom/both.test.tsx index c721604b..a94df050 100644 --- a/src/services/content-api/parsers/custom/both.test.tsx +++ b/src/services/content-api/parsers/custom/both.test.tsx @@ -6,6 +6,9 @@ import { render } from "@testing-library/react"; import React from "react"; const mockNBSBookingActionHTML = "NBS Booking Link Test"; +jest.mock("@src/app/_components/nbs/PharmacyBookingInfo", () => ({ + PharmacyBookingInfo: () =>

test

, +})); jest.mock("@src/app/_components/nbs/NBSBookingAction", () => ({ NBSBookingAction: () => mockNBSBookingActionHTML, })); @@ -26,14 +29,7 @@ const mockRsvInPregnancySubsection: VaccinePageSubsection = { const mockRsvForOlderAdultsSubsection: VaccinePageSubsection = { type: "simpleElement", - text: "

If you're aged 75 to 79

Paragraph 1

Paragraph 2

", - headline: "", - name: "", -}; - -const mockRsvForOlderAdultsNewerSubsection: VaccinePageSubsection = { - type: "simpleElement", - text: "

If you're aged 75 to 79 (or turned 80 after 1 September 2024)

Paragraph 1

Paragraph 2

", + text: "

If you're aged 75 or over

Paragraph 1

Paragraph 2

If you live in a care home for older adults

Paragraph 3

Paragraph 4

", headline: "", name: "", }; @@ -63,12 +59,9 @@ describe("styleHowToGetSubsection for rsv in older adults", () => { it("renders HTML if subsection contains rsv for older adults", () => { const { container } = render(<>{styleHowToGetSubsectionForRsv(mockRsvForOlderAdultsSubsection, 0, false)}); - expect(container.innerHTML).toBe("

Paragraph 1

Paragraph 2

"); - }); - - it("renders HTML if newer subsection contains rsv for older adults", () => { - const { container } = render(<>{styleHowToGetSubsectionForRsv(mockRsvForOlderAdultsNewerSubsection, 0, false)}); - expect(container.innerHTML).toBe("

Paragraph 1

Paragraph 2

"); + expect(container.innerHTML).toBe( + '

If you\'re aged 75 or over

Paragraph 1

Paragraph 2

test

If you live in a care home for older adults

Paragraph 3

Paragraph 4

', + ); }); }); diff --git a/src/services/content-api/parsers/custom/rsv.tsx b/src/services/content-api/parsers/custom/rsv.tsx index 4bf6a291..613ce621 100644 --- a/src/services/content-api/parsers/custom/rsv.tsx +++ b/src/services/content-api/parsers/custom/rsv.tsx @@ -1,3 +1,5 @@ +import { PharmacyBookingInfo } from "@src/app/_components/nbs/PharmacyBookingInfo"; +import { VaccineTypes } from "@src/models/vaccine"; import { ContentParsingError } from "@src/services/content-api/parsers/custom/exceptions"; import type { StyledPageSection, VaccinePageSection, VaccinePageSubsection } from "@src/services/content-api/types"; import { logger } from "@src/utils/logger"; @@ -7,9 +9,9 @@ import React from "react"; const log: Logger = logger.child({ module: "services-content-api-parsers-custom-rsv" }); -const olderAdultsRegExp: RegExp = - /

If you're aged \d+ to \d+(?: \(or turned \d+ after .*\))?<\/h3>((?:\s*

.*?<\/p>)+)/i; -const paragraphsRegExp: RegExp = /

.*?<\/p>/g; +const olderAdultsRegExp: RegExp = /

If you're aged \d+ or over<\/h3>((?:\s*

.*?<\/p>)+)/i; +const olderAdultsInCareHomeRegExp: RegExp = + /

If you live in a care home for older adults<\/h3>((?:\s*

.*?<\/p>)+)/i; export const styleHowToGetSubsection = (subsection: VaccinePageSubsection, index: number, fragile: boolean) => { if (subsection.type !== "simpleElement") { @@ -31,26 +33,33 @@ export const styleHowToGetSubsection = (subsection: VaccinePageSubsection, index } } - const paragraphsMatches = olderAdultsMatches[1].match(paragraphsRegExp); - if (!paragraphsMatches) { + const olderAdultsInCareHomeMatches = olderAdultsInCareHomeRegExp.exec(subsection.text); + if (!olderAdultsInCareHomeMatches) { log.warn( - { context: { text: olderAdultsMatches[1] } }, - "HowToGetSubsection paragraph not found - has the content changed?", + { context: { text: subsection.text } }, + "HowToGetSubsection care home header not found - has the content changed?", ); if (fragile) { - throw new ContentParsingError("HowToGetSubsection paragraph not found - has the content changed?"); + throw new ContentParsingError("HowToGetSubsection care home header not found - has the content changed?"); } else { return <>; } } return ( -

+
+
+ +
+
); }; diff --git a/wiremock/__files/rsv-vaccine.json b/wiremock/__files/rsv-vaccine.json index 46f14043..78eae5be 100644 --- a/wiremock/__files/rsv-vaccine.json +++ b/wiremock/__files/rsv-vaccine.json @@ -304,7 +304,7 @@ { "position": 0, "identifier": "1", - "text": "

There are different ways to get the RSV vaccine.

If you're pregnant

You should be offered the RSV vaccine around the time of your 28-week antenatal appointment.

Getting vaccinated as soon as possible from 28 weeks will provide the best protection for your baby. But the vaccine can be given later if needed, including up until you go into labour.

Speak to your maternity service or GP surgery if you're 28 weeks pregnant or more and have not been offered the vaccine.

If you're aged 75 to 79 (or turned 80 after 1 September 2024)

If you're aged 75 to 79 (or turned 80 after 1 September 2024) contact your GP surgery to book your RSV vaccination.

Your GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call or email.

You do not need to wait to be contacted before booking your vaccination.

", + "text": "

There are different ways to get the RSV vaccine.

If you're pregnant

You should be offered the RSV vaccine around the time of your 28-week antenatal appointment.

Getting vaccinated as soon as possible from 28 weeks will provide the best protection for your baby. But the vaccine can be given later if needed, including up until you go into labour.

Speak to your maternity service or GP surgery if you're 28 weeks pregnant or more and have not been offered the vaccine.

If you're aged 75 or over

Contact your GP surgery to book your RSV vaccination.

Your GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call or email.

You do not need to wait to be contacted before booking your vaccination.

If you live in a care home for older adults

Speak to a member of staff at your care home or your GP surgery about how to get the RSV vaccine.

Your GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call or email.

", "@type": "WebPageElement", "name": "markdown", "headline": ""