Skip to content

Commit d8fb2a0

Browse files
VIA-226 JS Refactor to module style and add recursive check
1 parent aff9457 commit d8fb2a0

File tree

9 files changed

+157
-130
lines changed

9 files changed

+157
-130
lines changed

pact/all.pact.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import axios, { AxiosResponse } from "axios";
22
import dotenv from 'dotenv';
3-
import { matchRSVResponse } from "./pact-helpers";
3+
import { matchRSVResponse } from "./helpers";
44

55
describe('Content API', () => {
66
beforeAll(async () => {
7-
dotenv.config({path: ".env.local"}); // Load environment variables from .env file
7+
dotenv.config({path: ".env.local"});
88
});
99

1010
test("vaccineContent contract", async () => {

pact/helpers/Matchers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const dateMatcher = (actual: string) => {
2+
expect(Date.parse(actual)).not.toBeNaN();
3+
}

pact/helpers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { matchContentAPIResponse as matchRSVResponse } from "./model/ContentAPIResponse";

pact/helpers/model/Breadcrumb.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export type BreadcrumbListItem = {
2+
"@type": "ListItem";
3+
"position": number;
4+
"item": {
5+
"@id": string;
6+
"name": string;
7+
"genre": string[];
8+
}
9+
}
10+
11+
export type Breadcrumb = {
12+
"@context": "http://schema.org";
13+
"@type": "BreadcrumbList";
14+
"itemListElement": BreadcrumbListItem[];
15+
}
16+
17+
export const matchBreadcrumbListItem = (actual: BreadcrumbListItem, position: number) => {
18+
expect(actual["position"]).toBe(position);
19+
}
20+
21+
export const matchBreadcrumb = (actual: Breadcrumb) => {
22+
expect(actual["itemListElement"].length).not.toBe(0);
23+
let cur;
24+
for (let i = 0; i < actual["itemListElement"].length; i++) {
25+
cur = actual["itemListElement"][i];
26+
matchBreadcrumbListItem(cur, i);
27+
}
28+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { Breadcrumb, matchBreadcrumb } from "./Breadcrumb";
2+
import { HealthTopicContent } from "./HealthTopicContent";
3+
import { LinkRole, matchRelatedLink } from "./LinkRole";
4+
import { matchWebPageElement, WebPageElement } from "./WebPageElement";
5+
import { dateMatcher } from "../Matchers";
6+
7+
export type ContentAPIResponse = {
8+
"@context": "http://schema.org";
9+
"@type": "MedicalWebPage";
10+
"name": "RSV vaccine";
11+
"copyrightHolder": {
12+
"@type": "Organization";
13+
"name": "Crown Copyright";
14+
}
15+
"license": "https://developer.api.nhs.uk/terms";
16+
"author": {
17+
"url": "https://www.nhs.uk";
18+
"logo": "https://assets.nhs.uk/nhsuk-cms/images/nhs-attribution.width-510.png";
19+
"email": "[email protected]";
20+
"@type": "Organization";
21+
"name": "NHS website";
22+
}
23+
"about": {
24+
"name": "RSV vaccine";
25+
"@type": "WebPage";
26+
"alternatename": ["Respiratory syncytial virus (RSV) vaccine"];
27+
}
28+
"description": string;
29+
"url": string
30+
"genre": ["Vaccine"];
31+
"keywords": "";
32+
"dateModified": string;
33+
"lastReviewed": string[];
34+
"breadcrumb": Breadcrumb;
35+
"hasPart": HealthTopicContent[];
36+
"relatedLink": LinkRole[];
37+
"contentSubTypes": [];
38+
"mainEntityOfPage": WebPageElement[]
39+
}
40+
41+
export const matchMainEntityOfPage = (actual: WebPageElement[]) => {
42+
let outer;
43+
expect(actual.length).toBeGreaterThanOrEqual(1);
44+
for (let i = 0; i < actual.length; i++) {
45+
outer = actual[i];
46+
matchWebPageElement(outer, i);
47+
}
48+
}
49+
50+
export const matchParts = (actual: HealthTopicContent[]) => {
51+
expect(actual.length).not.toBe(0);
52+
let outer, inner;
53+
for (let i = 0; i < actual.length; i++) {
54+
outer = actual[i];
55+
expect(outer["@type"]).toBe("HealthTopicContent");
56+
expect(actual[i].hasPart.length).not.toBe(0);
57+
for (let j = 0; j < outer["hasPart"].length; j++) {
58+
inner = outer["hasPart"][j];
59+
expect(inner["@type"]).toBe("WebPageElement");
60+
}
61+
}
62+
}
63+
64+
export const matchLastReviewed = (actual: string[]) => {
65+
expect(actual.length).not.toBe(0);
66+
for (const dateString in actual) dateMatcher(dateString);
67+
}
68+
69+
export const matchContentAPIResponse = (actual: ContentAPIResponse) => {
70+
dateMatcher(actual["dateModified"]);
71+
matchBreadcrumb(actual["breadcrumb"]);
72+
matchLastReviewed(actual["lastReviewed"]);
73+
matchParts(actual["hasPart"]);
74+
matchRelatedLink(actual.relatedLink)
75+
matchMainEntityOfPage(actual["mainEntityOfPage"]);
76+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { WebPageElement } from "@project/pact/helpers/model/WebPageElement";
2+
3+
export type HealthTopicContent = {
4+
"@type": string;
5+
"hasHealthAspect": string;
6+
"url": string;
7+
"description": string;
8+
"hasPart": WebPageElement[];
9+
"headline": string;
10+
}

pact/helpers/model/LinkRole.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export type LinkRole = {
2+
"@type": string;
3+
"url": string;
4+
"name": string;
5+
"linkRelationship": string;
6+
"position": number;
7+
}
8+
9+
export const matchRelatedLink = (actual: LinkRole[]) => {
10+
let outer;
11+
expect(actual.length).not.toBe(0);
12+
for (let i = 0; i < actual.length; i++) {
13+
outer = actual[i];
14+
expect(outer["@type"]).toBe("LinkRole");
15+
expect(outer["position"]).toBe(i);
16+
}
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export type WebPageElement = {
2+
"@type": string;
3+
"text": string;
4+
"headline"?: string;
5+
"position"?: number;
6+
"identifier"?: number;
7+
"name"?: "lead paragraph" | "section heading" | "markdown";
8+
"mainEntityOfPage"?: WebPageElement[];
9+
}
10+
11+
export const matchWebPageElement = (actual: WebPageElement, position: number) => {
12+
if (actual.position) expect(actual.position).toBe(position);
13+
if (actual.position) expect(actual.identifier).toBeDefined();
14+
if (actual.identifier) expect(actual.position).toBeDefined();
15+
if (actual.mainEntityOfPage) {
16+
for (let i = 0; i < actual.mainEntityOfPage.length; i++) {
17+
matchWebPageElement(actual.mainEntityOfPage[i], i);
18+
}
19+
}
20+
}

pact/pact-helpers.ts

Lines changed: 0 additions & 128 deletions
This file was deleted.

0 commit comments

Comments
 (0)