Skip to content

Commit d978f0a

Browse files
VIA-299 SB extract data for warning callout component fro content API response.
1 parent fa37da0 commit d978f0a

File tree

5 files changed

+107
-2
lines changed

5 files changed

+107
-2
lines changed

src/services/content-api/parsers/content-filter-service.test.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ import {
1111
} from "@src/services/content-api/parsers/content-filter-service";
1212
import {
1313
ContentApiVaccineResponse,
14+
HeadingWithContent,
1415
MainEntityOfPage,
1516
VaccinePageContent,
1617
VaccinePageSection,
1718
VaccinePageSubsection,
1819
} from "@src/services/content-api/types";
1920
import { genericVaccineContentAPIResponse } from "@test-data/content-api/data";
20-
import { contentWithoutBenefitsHealthAspect } from "@test-data/content-api/helpers";
21+
import { contentWithoutBenefitsHealthAspect, contentWithoutCallout } from "@test-data/content-api/helpers";
2122

2223
describe("Content Filter", () => {
2324
describe("_extractDescriptionForVaccine", () => {
@@ -693,5 +694,30 @@ describe("Content Filter", () => {
693694

694695
expect(pageCopyForFlu.whatVaccineIsFor).toBeUndefined();
695696
});
697+
698+
it("should return all parts for callout section", () => {
699+
const expectedCallout: HeadingWithContent = {
700+
heading: "Callout heading",
701+
content: "<p>Callout content</p>",
702+
};
703+
704+
const pageCopyForRsv: VaccinePageContent = getFilteredContentForVaccine(
705+
VaccineType.RSV,
706+
JSON.stringify(genericVaccineContentAPIResponse),
707+
);
708+
709+
expect(pageCopyForRsv.callout).toEqual(expectedCallout);
710+
});
711+
712+
it("should not return callout section when Callout is missing", () => {
713+
const responseWithoutCallout = contentWithoutCallout();
714+
715+
const pageCopyForFlu: VaccinePageContent = getFilteredContentForVaccine(
716+
VaccineType.RSV,
717+
JSON.stringify(responseWithoutCallout),
718+
);
719+
720+
expect(pageCopyForFlu.callout).toBeUndefined();
721+
});
696722
});
697723
});

src/services/content-api/parsers/content-filter-service.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { getFilteredContentForWhoopingCoughVaccine } from "@src/services/content
33
import {
44
ContentApiVaccineResponse,
55
HasPartSubsection,
6+
HeadingWithContent,
67
MainEntityOfPage,
78
Overview,
89
VaccinePageContent,
@@ -113,6 +114,45 @@ const _extractAnyOtherSubsection = (part: HasPartSubsection): VaccinePageSubsect
113114
};
114115
};
115116

117+
const _findCalloutElement = (response: ContentApiVaccineResponse): HasPartSubsection | undefined => {
118+
for (const section of response.mainEntityOfPage) {
119+
if (section.hasPart && Array.isArray(section.hasPart)) {
120+
const callout = section.hasPart.find((element) => element.name === "Callout");
121+
if (callout) {
122+
return callout;
123+
}
124+
}
125+
}
126+
return undefined;
127+
};
128+
129+
function _hasCallout(response: ContentApiVaccineResponse): boolean {
130+
return !!_findCalloutElement(response);
131+
}
132+
133+
function _extractCalloutHeading(response: ContentApiVaccineResponse): string {
134+
const calloutElement = _findCalloutElement(response);
135+
136+
if (!calloutElement || !calloutElement.text) {
137+
return "";
138+
}
139+
140+
const match = calloutElement.text.match(/<h3>(.*?)<\/h3>/);
141+
return match ? match[1] : "";
142+
}
143+
144+
function _extractCalloutContent(response: ContentApiVaccineResponse): string {
145+
const calloutElement = _findCalloutElement(response);
146+
147+
if (!calloutElement || !calloutElement.text) {
148+
return "";
149+
}
150+
151+
const content = calloutElement.text.replace(/<h3>.*?<\/h3>/, "").trim();
152+
153+
return content;
154+
}
155+
116156
const _removeExcludedHyperlinks = (subsections: VaccinePageSubsection[]) => {
117157
const nbsHyperlinkPattern: RegExp =
118158
/<a [^>]*?href="[^>]*?\/nhs-services\/vaccination-and-booking-services\/book-[^>]*?>(.*?)<\/a>/g;
@@ -208,6 +248,11 @@ const getFilteredContentForStandardVaccine = (apiContent: string): VaccinePageCo
208248
subsections: _extractPartsForAspect(content, "SideEffectsHealthAspect"),
209249
};
210250

251+
let callout: HeadingWithContent | undefined;
252+
if (_hasCallout(content)) {
253+
callout = { heading: _extractCalloutHeading(content), content: _extractCalloutContent(content) };
254+
}
255+
211256
const webpageLink: URL = new URL(content.webpage);
212257

213258
return {
@@ -217,6 +262,7 @@ const getFilteredContentForStandardVaccine = (apiContent: string): VaccinePageCo
217262
howToGetVaccine,
218263
vaccineSideEffects,
219264
webpageLink,
265+
callout,
220266
};
221267
};
222268

src/services/content-api/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export type VaccinePageContent = {
109109
howToGetVaccine: VaccinePageSection;
110110
vaccineSideEffects: VaccinePageSection;
111111
webpageLink: URL;
112+
callout?: HeadingWithContent;
112113
};
113114

114115
export type StyledPageSection = {
@@ -128,6 +129,7 @@ export type StyledVaccineContent = {
128129
howToGetVaccine: StyledPageSection;
129130
vaccineSideEffects: StyledPageSection;
130131
webpageLink: URL;
132+
callout?: HeadingWithContent;
131133
};
132134

133135
export type ContentApiVaccinationsResponse = {

test-data/content-api/data.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,20 @@ export const genericVaccineContentAPIResponse: ContentApiVaccineResponse = {
554554
},
555555
],
556556
},
557+
{
558+
identifier: "0",
559+
name: "section heading",
560+
position: 1,
561+
"@type": "WebPageElement",
562+
hasPart: [
563+
{
564+
position: 0,
565+
"@type": "WebPageElement",
566+
name: "Callout",
567+
text: "<h3>Callout heading</h3><p>Callout content</p>",
568+
},
569+
],
570+
},
557571
],
558572
webpage: new URL("https://www.nhs.uk/vaccinations/generic-vaccine/"),
559573
};

test-data/content-api/helpers.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,21 @@ const contentWithoutBenefitsHealthAspect = () => {
1111
return responseWithoutBenefitsHealthAspect;
1212
};
1313

14-
export { contentWithoutBenefitsHealthAspect };
14+
const contentWithoutCallout = (): ContentApiVaccineResponse => {
15+
const responseWithoutCallout: ContentApiVaccineResponse = {
16+
...genericVaccineContentAPIResponse,
17+
mainEntityOfPage: genericVaccineContentAPIResponse.mainEntityOfPage.map((section) => {
18+
// Callouts are nested deep inside 'section heading' elements
19+
if (section.hasPart && Array.isArray(section.hasPart)) {
20+
return {
21+
...section,
22+
hasPart: section.hasPart.filter((element) => element.name !== "Callout"),
23+
};
24+
}
25+
return section;
26+
}),
27+
};
28+
return responseWithoutCallout;
29+
};
30+
31+
export { contentWithoutBenefitsHealthAspect, contentWithoutCallout };

0 commit comments

Comments
 (0)