Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/_lambda/content-cache-hydrator/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const checkContentPassesStylingAndWriteToCache = async (
filteredContent: VaccinePageContent,
): Promise<void> => {
try {
await getStyledContentForVaccine(filteredContent);
await getStyledContentForVaccine(filteredContent, vaccineType);
await writeContentForVaccine(vaccineType, content);
log.info({ context: { vaccineType } }, `Content written to cache for vaccine ${vaccineType} `);
} catch (error) {
Expand Down
39 changes: 3 additions & 36 deletions src/app/_components/eligibility/RSVEligibilityFallback.test.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import { HowToGetVaccineFallback } from "@src/app/_components/content/HowToGetVaccineFallback";
import { RSVEligibilityFallback } from "@src/app/_components/eligibility/RSVEligibilityFallback";
import { PharmacyBookingInfo } from "@src/app/_components/nbs/PharmacyBookingInfo";
import { VaccineType } from "@src/models/vaccine";
import { mockStyledContent } from "@test-data/content-api/data";
import { render, screen, within } from "@testing-library/react";

jest.mock("@src/app/_components/nbs/PharmacyBookingInfo", () => ({
PharmacyBookingInfo: jest
.fn()
.mockImplementation(() => <p data-testid={"pharmacy-booking-info"}>Pharmacy booking test</p>),
}));

jest.mock("@src/app/_components/content/HowToGetVaccineFallback", () => ({
HowToGetVaccineFallback: jest
.fn()
Expand All @@ -24,40 +17,20 @@ describe("RSVEligibilityFallback", () => {
render(<RSVEligibilityFallback styledVaccineContent={mockStyledContent} vaccineType={vaccineType} />);

const fallbackHeading: HTMLElement = screen.getByText("The RSV vaccine is recommended if you:");
const fallbackBulletPoint1: HTMLElement = screen.getByText("are aged between 75 and 79");
const fallbackBulletPoint2: HTMLElement = screen.getByText("turned 80 after 1 September 2024");
const fallbackBulletPoint1: HTMLElement = screen.getByText("are aged 75 or over");
const fallbackBulletPoint2: HTMLElement = screen.getByText("live in a care home for older adults");

expect(fallbackHeading).toBeVisible();
expect(fallbackBulletPoint1).toBeVisible();
expect(fallbackBulletPoint2).toBeVisible();
});

it("should include Pharmacy booking info for specified vaccine", () => {
render(<RSVEligibilityFallback styledVaccineContent={mockStyledContent} vaccineType={vaccineType} />);

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 styled how-to-get from content API", async () => {
it("should display styled how-to-get from content API", async () => {
render(<RSVEligibilityFallback styledVaccineContent={mockStyledContent} vaccineType={vaccineType} />);

const fallback = screen.getByTestId("elid-fallback");

const fallbackHeading: HTMLElement = within(fallback).getByRole("heading", {
name: "If this applies to you",
level: 3,
});
const howToGetFromContentAPI: HTMLElement = within(fallback).getByText("How Section styled component");

expect(fallbackHeading).toBeVisible();
expect(howToGetFromContentAPI).toBeVisible();

const howToGetFallback: HTMLElement | null = within(fallback).queryByText("How to get fallback");
Expand All @@ -68,14 +41,8 @@ describe("RSVEligibilityFallback", () => {
render(<RSVEligibilityFallback styledVaccineContent={undefined} vaccineType={vaccineType} />);

const fallback = screen.getByTestId("elid-fallback");

const fallbackHeading: HTMLElement = within(fallback).getByRole("heading", {
name: "If this applies to you",
level: 3,
});
const howToGetFallback: HTMLElement = within(fallback).getByText("How to get fallback");

expect(fallbackHeading).toBeVisible();
expect(howToGetFallback).toBeVisible();

expect(HowToGetVaccineFallback).toHaveBeenCalledWith(
Expand Down
8 changes: 2 additions & 6 deletions src/app/_components/eligibility/RSVEligibilityFallback.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { HowToGetVaccineFallback } from "@src/app/_components/content/HowToGetVaccineFallback";
import { PharmacyBookingInfo } from "@src/app/_components/nbs/PharmacyBookingInfo";
import NonUrgentCareCard from "@src/app/_components/nhs-frontend/NonUrgentCareCard";
import { HEADINGS } from "@src/app/constants";
import { VaccineType } from "@src/models/vaccine";
import { StyledVaccineContent } from "@src/services/content-api/types";
import React, { JSX } from "react";
Expand All @@ -24,15 +22,13 @@ const RSVEligibilityFallback = (props: {
content={
<>
<ul>
<li>{"are aged between 75 and 79"}</li>
<li>{"turned 80 after 1 September 2024"}</li>
<li>{"are aged 75 or over"}</li>
<li>{"live in a care home for older adults"}</li>
</ul>
</>
}
/>
<h3>{HEADINGS.IF_THIS_APPLIES}</h3>
{howToGetVaccineOrFallback}
<PharmacyBookingInfo vaccineType={props.vaccineType} />
</div>
);
};
Expand Down
10 changes: 3 additions & 7 deletions src/app/_components/nbs/PharmacyBookingInfo.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,16 @@ describe("PharmacyBookingInfo", () => {
it("should contain include correct text for older adults", () => {
render(<PharmacyBookingInfo vaccineType={VaccineType.RSV} />);

const pharmacyBookingInfo: HTMLElement = screen.getByText(
/This pharmacy service is only for adults aged 75 to 79./,
);
const pharmacyBookingInfo: HTMLElement = screen.getByText(/In some areas you can /);

expect(pharmacyBookingInfo).toBeInTheDocument();
});

it("should contain include correct text for younger adults", () => {
render(<PharmacyBookingInfo vaccineType={VaccineType.RSV_PREGNANCY} />);

const pharmacyBookingInfo: HTMLElement | null = screen.queryByText(
/This pharmacy service is only for adults aged 75 to 79./,
);
const pharmacyBookingInfo: HTMLElement | null = screen.queryByText(/In some areas you can also /);

expect(pharmacyBookingInfo).not.toBeInTheDocument();
expect(pharmacyBookingInfo).toBeInTheDocument();
});
});
2 changes: 1 addition & 1 deletion src/app/_components/nbs/PharmacyBookingInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const PharmacyBookingInfo = ({ vaccineType }: PharmacyBookingProps): JSX.Element
renderAs={"anchor"}
reduceBottomPadding={false}
/>
{vaccineInfo.forOlderAdults ? ". This pharmacy service is only for adults aged 75 to 79." : "."}
{"."}
</p>
);
};
Expand Down
1 change: 0 additions & 1 deletion src/app/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ export const HEADINGS = {
HOW_TO_GET_VACCINE: "How to get the vaccine",
EXTRA_DOSES_SCHEDULE: "Extra doses of the vaccine",
VACCINE_SIDE_EFFECTS: "Side effects of the vaccine",
IF_THIS_APPLIES: "If this applies to you",
};
7 changes: 6 additions & 1 deletion src/app/vaccines-for-all-ages/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,12 @@ describe("VaccinesForAllAges", () => {
description: "65 to 67 and 70 to 79 years",
path: "/vaccines/shingles-vaccine",
},
{ section: AgeSectionTestId.ADULTS, cardTitle: "RSV", description: "75 years and over", path: "/vaccines/rsv" },
{
section: AgeSectionTestId.ADULTS,
cardTitle: "RSV",
description: "75 years and over, or living in a care home for older adults",
path: "/vaccines/rsv",
},
{
section: AgeSectionTestId.ADULTS,
cardTitle: "COVID-19",
Expand Down
5 changes: 3 additions & 2 deletions src/models/ageBasedHub.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,16 @@ describe("AgeBasedHubInfo", () => {
expect(info.heading).toBe("Adults aged 65 to 74 should get these routine vaccines");
});

it("has 3 vaccines", () => {
expect(info.vaccines).toHaveLength(4);
it("has expected #vaccines", () => {
expect(info.vaccines).toHaveLength(5);
});

it("has correct vaccine names", () => {
expect(info.vaccines.map((v) => v.vaccineName)).toEqual([
VaccineType.PNEUMOCOCCAL,
VaccineType.FLU_FOR_ADULTS,
VaccineType.SHINGLES,
VaccineType.RSV,
VaccineType.COVID_19,
]);
});
Expand Down
1 change: 1 addition & 0 deletions src/models/ageBasedHub.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ const AgeBasedHubInfo: Record<AgeGroup, AgeBasedHubDetails | undefined> = {
{ vaccineName: VaccineType.PNEUMOCOCCAL, cardLinkDescription: "65 years and over" },
{ vaccineName: VaccineType.FLU_FOR_ADULTS, cardLinkDescription: "65 years and over" },
{ vaccineName: VaccineType.SHINGLES, cardLinkDescription: "65 to 67 and 70 to 79 years" },
{ vaccineName: VaccineType.RSV, cardLinkDescription: "If living in a care home for older adults" },
{ vaccineName: VaccineType.COVID_19, cardLinkDescription: "If living in a care home for older adults" },
],
showPregnancyHubContent: false,
Expand Down
2 changes: 1 addition & 1 deletion src/models/vaccine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ const adultVaccines: VaccineCardDetails[] = [
{ vaccineName: VaccineType.PNEUMOCOCCAL, cardLinkDescription: "65 years and over" },
{ vaccineName: VaccineType.FLU_FOR_ADULTS, cardLinkDescription: "65 years and over" },
{ vaccineName: VaccineType.SHINGLES, cardLinkDescription: "65 to 67 and 70 to 79 years" },
{ vaccineName: VaccineType.RSV, cardLinkDescription: "75 years and over" },
{ vaccineName: VaccineType.RSV, cardLinkDescription: "75 years and over, or living in a care home for older adults" },
{
vaccineName: VaccineType.COVID_19,
cardLinkDescription: "75 years and over, or living in a care home for older adults",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe("Content Filter Service Regex", () => {

it("should extract how to get section text for Rsv Older Adults", async () => {
const expectedHowToGetContentRsvOlderAdults =
"<p>If you're aged 75 to 79 (or turned 80 after 1 September 2024) contact your GP surgery to book your RSV vaccination.</p><p>Your GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call or email.</p><p>You do not need to wait to be contacted before booking your vaccination.</p>";
"<h3>If you're aged 75 or over</h3><p>Contact your GP surgery to book your RSV vaccination.</p><p>Your GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call or email.</p><p>You do not need to wait to be contacted before booking your vaccination.</p>";

const defaultConfig = configBuilder().withContentCachePath("wiremock/__files/").build();
Object.assign(mockedConfig, defaultConfig);
Expand Down
2 changes: 1 addition & 1 deletion src/services/content-api/content-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const getContentForVaccine = async (vaccineType: VaccineType): Promise<GetConten

// filter and style content
const filteredContent: VaccinePageContent = await getFilteredContentForVaccine(vaccineType, vaccineContent);
const styledVaccineContent: StyledVaccineContent = await getStyledContentForVaccine(filteredContent);
const styledVaccineContent: StyledVaccineContent = await getStyledContentForVaccine(filteredContent, vaccineType);

profilePerformanceEnd(GetVaccineContentPerformanceMarker);

Expand Down
73 changes: 60 additions & 13 deletions src/services/content-api/parsers/content-styling-service.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ jest.mock("@project/src/app/_components/markdown/MarkdownWithStyling", () => ({
MarkdownWithStyling: jest.fn(),
}));

jest.mock("@src/app/_components/nbs/PharmacyBookingInfo", () => ({
PharmacyBookingInfo: () => <div>Pharmacy Booking Info</div>,
}));

jest.mock("sanitize-data", () => ({ sanitize: jest.fn() }));
jest.mock("cheerio", () => ({
load: jest.fn(() => {
Expand Down Expand Up @@ -70,7 +74,7 @@ describe("ContentStylingService", () => {

const mockHowToGetMarkdownSubsection: VaccinePageSubsection = {
type: "simpleElement",
text: "<p>para</p><h3>If you're aged 75 to 79</h3><p>para1</p><p>para2</p><h3>If you're pregnant</h3><p>para3</p><p>para4</p>",
text: "<p>para</p><h3>If you're aged 75 or over</h3><p>para1</p><p>para2</p><h3>If you live in a care home for older adults</h3><p>para3</p><p>para4</p><h3>If you're pregnant</h3><p>para5</p><p>para6</p>",
name: "markdown",
headline: "How To Get Headline",
};
Expand Down Expand Up @@ -334,40 +338,80 @@ describe("ContentStylingService", () => {
additionalInformation: mockAdditionalInformationSection,
};

it.each(Object.values(VaccineType))("should return styled content for %s", async () => {
const styledVaccineContent: StyledVaccineContent = await getStyledContentForVaccine(mockContent);

const assertCommonStyledSections = (
styledVaccineContent: StyledVaccineContent,
expectedHowToGetHeadline: string,
) => {
expect(styledVaccineContent).not.toBeNull();
expect(styledVaccineContent.overview).toEqual(mockContent.overview);
expect(styledVaccineContent.whatVaccineIsFor?.heading).toEqual(mockWhatSection.headline);
expect(styledVaccineContent.whoVaccineIsFor.heading).toEqual(mockWhoSection.headline);
expect(styledVaccineContent.howToGetVaccine.heading).toEqual(mockHowSection.headline);
expect(styledVaccineContent.howToGetVaccine.heading).toEqual(expectedHowToGetHeadline);
expect(styledVaccineContent.vaccineSideEffects.heading).toEqual(mockSideEffectsSection.headline);
expect(styledVaccineContent.extraDosesSchedule?.heading).toEqual(mockExtraDosesScheduleSection.headline);
expect(styledVaccineContent.callout?.heading).toEqual(mockCallout.heading);
expect(styledVaccineContent.recommendation?.heading).toEqual(mockRecommendation.heading);
expect(styledVaccineContent.additionalInformation?.heading).toEqual(mockAdditionalInformationSection.headline);

const expectedGenericVaccineHowToGetSection =
"<div class=\"zeroMarginBottom\"><h3>How To Get Headline</h3><p>para</p><h3>If you're aged 75 to 79</h3><p>para1</p><p>para2</p><h3>If you're pregnant</h3><p>para3</p><p>para4</p></div>";
const { container } = render(styledVaccineContent.howToGetVaccine.component);
expect(container.innerHTML).toBe(expectedGenericVaccineHowToGetSection);

expect(isValidElement(styledVaccineContent.whatVaccineIsFor?.component)).toBe(true);
expect(isValidElement(styledVaccineContent.whoVaccineIsFor.component)).toBe(true);
expect(isValidElement(styledVaccineContent.howToGetVaccine.component)).toBe(true);
expect(isValidElement(styledVaccineContent.vaccineSideEffects.component)).toBe(true);

expect(isValidElement(styledVaccineContent.additionalInformation?.component)).toBe(true);
expect(styledVaccineContent.webpageLink).toEqual(new URL("https://test.example.com/"));
};

it.each(Object.values(VaccineType).filter((t) => t !== VaccineType.RSV))(
"should return styled content for %s",
async (vaccineType) => {
const styledVaccineContent: StyledVaccineContent = await getStyledContentForVaccine(mockContent, vaccineType);

assertCommonStyledSections(styledVaccineContent, mockHowSection.headline);

const expectedGenericVaccineHowToGetSection =
"<div class=\"zeroMarginBottom\"><h3>How To Get Headline</h3><p>para</p><h3>If you're aged 75 or over</h3><p>para1</p><p>para2</p><h3>If you live in a care home for older adults</h3><p>para3</p><p>para4</p><h3>If you're pregnant</h3><p>para5</p><p>para6</p></div>";
const { container } = render(styledVaccineContent.howToGetVaccine.component);
expect(container.innerHTML).toBe(expectedGenericVaccineHowToGetSection);
},
);

it("should return styled content for RSV with PharmacyBookingInfo between older adults and care home subsections", async () => {
const mockRsvOlderAdultsSubsection: VaccinePageSubsection = {
type: "simpleElement",
headline: "",
name: "markdown",
text: "<h3>If you're aged 75 or over</h3><p>para1</p><p>para2</p>",
};
const mockRsvCareHomeSubsection: VaccinePageSubsection = {
type: "simpleElement",
headline: "",
name: "markdown",
text: "<h3>If you live in a care home for older adults</h3><p>para3</p><p>para4</p>",
};
const mockRsvHowSection: VaccinePageSection = {
headline: "How to get this Vaccine",
subsections: [mockRsvOlderAdultsSubsection, mockRsvCareHomeSubsection],
};
const mockRsvContent: VaccinePageContent = { ...mockContent, howToGetVaccine: mockRsvHowSection };

const styledVaccineContent = await getStyledContentForVaccine(mockRsvContent, VaccineType.RSV);

assertCommonStyledSections(styledVaccineContent, mockRsvHowSection.headline);

const expectedRsvHowToGetSection =
'<div><h3>If you\'re aged 75 or over</h3><p>para1</p><p>para2</p></div><div>Pharmacy Booking Info</div><div class="zeroMarginBottom"><h3>If you live in a care home for older adults</h3><p>para3</p><p>para4</p></div>';
const { container } = render(styledVaccineContent.howToGetVaccine.component);
expect(container.innerHTML).toBe(expectedRsvHowToGetSection);
});

it("should return styled content without what-section when what-section is missing", async () => {
const mockContentWithoutWhatSection = { ...mockContent };
delete mockContentWithoutWhatSection.whatVaccineIsFor;

const styledVaccineContent: StyledVaccineContent =
await getStyledContentForVaccine(mockContentWithoutWhatSection);
const styledVaccineContent: StyledVaccineContent = await getStyledContentForVaccine(
mockContentWithoutWhatSection,
VaccineType.COVID_19,
);

expect(styledVaccineContent).not.toBeNull();
expect(styledVaccineContent.overview).toEqual({ content: "This is an overview", containsHtml: false });
Expand All @@ -384,6 +428,7 @@ describe("ContentStylingService", () => {

const styledVaccineContent: StyledVaccineContent = await getStyledContentForVaccine(
mockContentWithoutRecommendation,
VaccineType.COVID_19,
);

expect(styledVaccineContent.recommendation).toBeUndefined();
Expand All @@ -395,6 +440,7 @@ describe("ContentStylingService", () => {

const styledVaccineContent: StyledVaccineContent = await getStyledContentForVaccine(
mockContentWithoutAdditionalInformation,
VaccineType.COVID_19,
);

expect(styledVaccineContent.additionalInformation).toBeUndefined();
Expand All @@ -406,6 +452,7 @@ describe("ContentStylingService", () => {

const styledVaccineContent: StyledVaccineContent = await getStyledContentForVaccine(
mockContentWithoutExtraDosesSchedule,
VaccineType.COVID_19,
);

expect(styledVaccineContent.extraDosesSchedule).toBeUndefined();
Expand Down
Loading
Loading