Skip to content

Commit 65b0f25

Browse files
VIA-629 AJ/EO Fix bottom margin in ActionLink and NBS Button and show HR for all but last actions or rules
1 parent ce5516f commit 65b0f25

File tree

13 files changed

+85
-155
lines changed

13 files changed

+85
-155
lines changed

src/app/_components/eligibility/EligibilityActions.test.tsx

Lines changed: 44 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,20 @@ jest.mock("@src/app/_components/nbs/NBSBookingAction", () => ({
1717

1818
describe("EligibilityActions", () => {
1919
describe("when actions are present", () => {
20-
describe("infotext", () => {
21-
it("should display infotext content successfully", () => {
20+
describe("should show delineator based on last action", () => {
21+
it("does not show for single action", async () => {
2222
render(
2323
EligibilityActions({
24-
actions: [actionBuilder().withType(ActionDisplayType.infotext).andContent("Test Content").build()],
24+
actions: [actionBuilder().withType(ActionDisplayType.infotext).andContent("Test Content 1").build()],
2525
vaccineType: VaccineType.RSV,
2626
}),
2727
);
2828

29-
expectContentStringToBeVisible("Test Content");
29+
const content1: HTMLElement = screen.getByText("Test Content 1");
30+
expect(content1.closest('[data-testid="markdown-with-styling"]')?.nextElementSibling?.tagName).not.toBe("HR");
3031
});
3132

32-
it("should display multiple infotexts successfully", () => {
33+
it("shows below first but not the second for two actions", async () => {
3334
render(
3435
EligibilityActions({
3536
actions: [
@@ -40,23 +41,22 @@ describe("EligibilityActions", () => {
4041
}),
4142
);
4243

43-
expectEachContentStringToBeVisible(["Test Content 1", "Test Content 2"]);
44+
const content1: HTMLElement = screen.getByText("Test Content 1");
45+
const content2: HTMLElement = screen.getByText("Test Content 2");
46+
47+
expect(content1.closest('[data-testid="markdown-with-styling"]')?.nextElementSibling?.tagName).toBe("HR");
48+
expect(content2.closest('[data-testid="markdown-with-styling"]')?.nextElementSibling?.tagName).not.toBe("HR");
4449
});
4550

46-
it("should display delineator depending on flag", () => {
51+
it("shows below all but the last one for multiple mixed action types", async () => {
4752
render(
4853
EligibilityActions({
4954
actions: [
50-
actionBuilder()
51-
.withType(ActionDisplayType.infotext)
52-
.andContent("Test Content 1")
53-
.andDelineator(true)
54-
.build(),
55-
actionBuilder()
56-
.withType(ActionDisplayType.infotext)
57-
.andContent("Test Content 2")
58-
.andDelineator(false)
59-
.build(),
55+
actionBuilder().withType(ActionDisplayType.infotext).andContent("Test Content 1").build(),
56+
actionBuilder().withType(ActionDisplayType.card).andContent("Test Content 2").build(),
57+
actionBuilder().withType(ActionDisplayType.buttonWithCard).andContent("Test Content 3").build(),
58+
actionBuilder().withType(ActionDisplayType.buttonWithInfo).andContent("Test Content 4").build(),
59+
actionBuilder().withType(ActionDisplayType.actionLinkWithInfo).andContent("Test Content 5").build(),
6060
],
6161
vaccineType: VaccineType.RSV,
6262
}),
@@ -66,56 +66,64 @@ describe("EligibilityActions", () => {
6666
const content2: HTMLElement = screen.getByText("Test Content 2");
6767

6868
expect(content1.closest('[data-testid="markdown-with-styling"]')?.nextElementSibling?.tagName).toBe("HR");
69-
expect(content2.closest('[data-testid="markdown-with-styling"]')?.nextElementSibling?.tagName).not.toBe("HR");
69+
expect(content2.closest('[data-testid="markdown-with-styling"]')?.nextElementSibling?.tagName).toBe("HR");
70+
expectDelineatorToBePresentAfterElementWithSelector("Test Content 3", ".nhsuk-card");
71+
expectDelineatorToBePresentAfterElementWithSelector("Test Content 4", '[data-testid="action-paragraph"]');
72+
expectDelineatorToNotBePresentAfterElementWithSelector("Test Content 5", '[data-testid="action-paragraph"]');
7073
});
7174
});
7275

73-
describe("card", () => {
74-
it("should display card content successfully", () => {
76+
describe("infotext", () => {
77+
it("should display infotext content successfully", () => {
7578
render(
7679
EligibilityActions({
77-
actions: [actionBuilder().withType(ActionDisplayType.card).andContent("Test Content").build()],
80+
actions: [actionBuilder().withType(ActionDisplayType.infotext).andContent("Test Content").build()],
7881
vaccineType: VaccineType.RSV,
7982
}),
8083
);
8184

8285
expectContentStringToBeVisible("Test Content");
8386
});
8487

85-
it("should display multiple cards successfully", () => {
88+
it("should display multiple infotexts successfully", () => {
8689
render(
8790
EligibilityActions({
8891
actions: [
89-
actionBuilder().withType(ActionDisplayType.card).andContent("Test Content 1").build(),
90-
actionBuilder().withType(ActionDisplayType.card).andContent("Test Content 2").build(),
92+
actionBuilder().withType(ActionDisplayType.infotext).andContent("Test Content 1").build(),
93+
actionBuilder().withType(ActionDisplayType.infotext).andContent("Test Content 2").build(),
9194
],
9295
vaccineType: VaccineType.RSV,
9396
}),
9497
);
9598

9699
expectEachContentStringToBeVisible(["Test Content 1", "Test Content 2"]);
97100
});
101+
});
98102

99-
it("should display delineator depending on flag", () => {
103+
describe("card", () => {
104+
it("should display card content successfully", () => {
105+
render(
106+
EligibilityActions({
107+
actions: [actionBuilder().withType(ActionDisplayType.card).andContent("Test Content").build()],
108+
vaccineType: VaccineType.RSV,
109+
}),
110+
);
111+
112+
expectContentStringToBeVisible("Test Content");
113+
});
114+
115+
it("should display multiple cards successfully", () => {
100116
render(
101117
EligibilityActions({
102118
actions: [
103-
actionBuilder()
104-
.withType(ActionDisplayType.card)
105-
.andContent("Test Content 1")
106-
.andDelineator(false)
107-
.build(),
108-
actionBuilder().withType(ActionDisplayType.card).andContent("Test Content 2").andDelineator(true).build(),
119+
actionBuilder().withType(ActionDisplayType.card).andContent("Test Content 1").build(),
120+
actionBuilder().withType(ActionDisplayType.card).andContent("Test Content 2").build(),
109121
],
110122
vaccineType: VaccineType.RSV,
111123
}),
112124
);
113125

114-
const content1: HTMLElement = screen.getByText("Test Content 1");
115-
const content2: HTMLElement = screen.getByText("Test Content 2");
116-
117-
expect(content1.closest('[data-testid="markdown-with-styling"]')?.nextElementSibling?.tagName).not.toBe("HR");
118-
expect(content2.closest('[data-testid="markdown-with-styling"]')?.nextElementSibling?.tagName).toBe("HR");
126+
expectEachContentStringToBeVisible(["Test Content 1", "Test Content 2"]);
119127
});
120128
});
121129

@@ -174,29 +182,6 @@ describe("EligibilityActions", () => {
174182

175183
expect(card).not.toBeInTheDocument();
176184
});
177-
178-
it("should display delineator depending on flag", () => {
179-
render(
180-
EligibilityActions({
181-
actions: [
182-
actionBuilder()
183-
.withType(ActionDisplayType.buttonWithCard)
184-
.andContent("Test Content 1")
185-
.andDelineator(true)
186-
.build(),
187-
actionBuilder()
188-
.withType(ActionDisplayType.buttonWithCard)
189-
.andContent("Test Content 2")
190-
.andDelineator(false)
191-
.build(),
192-
],
193-
vaccineType: VaccineType.RSV,
194-
}),
195-
);
196-
197-
expectDelineatorToBePresentAfterElementWithSelector("Test Content 1", ".nhsuk-card");
198-
expectDelineatorToNotBePresentAfterElementWithSelector("Test Content 2", ".nhsuk-card");
199-
});
200185
});
201186

202187
describe("buttonWithInfo", () => {
@@ -254,29 +239,6 @@ describe("EligibilityActions", () => {
254239

255240
expect(card).not.toBeInTheDocument();
256241
});
257-
258-
it("should display delineator depending on flag", () => {
259-
render(
260-
EligibilityActions({
261-
actions: [
262-
actionBuilder()
263-
.withType(ActionDisplayType.buttonWithInfo)
264-
.andContent("Test Content 1")
265-
.andDelineator(true)
266-
.build(),
267-
actionBuilder()
268-
.withType(ActionDisplayType.buttonWithInfo)
269-
.andContent("Test Content 2")
270-
.andDelineator(false)
271-
.build(),
272-
],
273-
vaccineType: VaccineType.RSV,
274-
}),
275-
);
276-
277-
expectDelineatorToBePresentAfterElementWithSelector("Test Content 1", '[data-testid="action-paragraph"]');
278-
expectDelineatorToNotBePresentAfterElementWithSelector("Test Content 2", '[data-testid="action-paragraph"]');
279-
});
280242
});
281243

282244
describe("actionLinkWithInfo", () => {
@@ -348,29 +310,6 @@ describe("EligibilityActions", () => {
348310

349311
expect(card).not.toBeInTheDocument();
350312
});
351-
352-
it("should display delineator depending on flag", () => {
353-
render(
354-
EligibilityActions({
355-
actions: [
356-
actionBuilder()
357-
.withType(ActionDisplayType.actionLinkWithInfo)
358-
.andContent("Test Content 1")
359-
.andDelineator(true)
360-
.build(),
361-
actionBuilder()
362-
.withType(ActionDisplayType.actionLinkWithInfo)
363-
.andContent("Test Content 2")
364-
.andDelineator(false)
365-
.build(),
366-
],
367-
vaccineType: VaccineType.RSV,
368-
}),
369-
);
370-
371-
expectDelineatorToBePresentAfterElementWithSelector("Test Content 1", '[data-testid="action-paragraph"]');
372-
expectDelineatorToNotBePresentAfterElementWithSelector("Test Content 2", '[data-testid="action-paragraph"]');
373-
});
374313
});
375314
});
376315

src/app/_components/eligibility/EligibilityActions.tsx

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@ interface EligibilityActionProps {
1212
}
1313

1414
const EligibilityActions = ({ actions, vaccineType }: EligibilityActionProps): (JSX.Element | undefined)[] => {
15-
return actions.map((action: Action) => {
15+
return actions.map((action: Action, index: number) => {
16+
const isNotLastAction: boolean = index < actions.length - 1;
17+
1618
switch (action.type) {
1719
case ActionDisplayType.infotext: {
18-
return <InfoText content={action.content} delineator={action.delineator} />;
20+
return <InfoText key={index} content={action.content} delineator={isNotLastAction} />;
1921
}
22+
2023
case ActionDisplayType.card: {
21-
return <Card content={action.content} delineator={action.delineator} />;
24+
return <Card key={index} content={action.content} delineator={isNotLastAction} />;
2225
}
26+
2327
case ActionDisplayType.buttonWithCard: {
2428
const card = action.content && <BasicCard content={action.content} delineator={false} />;
2529
const button = action.button && (
@@ -28,17 +32,18 @@ const EligibilityActions = ({ actions, vaccineType }: EligibilityActionProps): (
2832
url={action.button.url}
2933
label={action.button.label}
3034
renderAs={"button"}
31-
delineator={action.delineator}
35+
delineator={false}
3236
/>
3337
);
3438
return (
35-
<div key={action.content} data-testid="action-auth-button-components">
39+
<div key={index} data-testid="action-auth-button-components">
3640
{card}
3741
{button}
38-
{action.delineator && <hr />}
42+
{isNotLastAction && <hr />}
3943
</div>
4044
);
4145
}
46+
4247
case ActionDisplayType.buttonWithInfo: {
4348
const info = action.content && <InfoText content={action.content} delineator={false} />;
4449
const button = action.button && (
@@ -47,22 +52,23 @@ const EligibilityActions = ({ actions, vaccineType }: EligibilityActionProps): (
4752
url={action.button.url}
4853
label={action.button.label}
4954
renderAs={"button"}
50-
delineator={action.delineator}
55+
delineator={false}
5156
/>
5257
);
5358
return (
54-
<div key={action.content} data-testid="action-auth-button-components">
59+
<div key={index} data-testid="action-auth-button-components">
5560
{info}
5661
{button}
57-
{action.delineator && <hr />}
62+
{isNotLastAction && <hr />}
5863
</div>
5964
);
6065
}
66+
6167
case ActionDisplayType.actionLinkWithInfo: {
6268
const info = action.content && <InfoText content={action.content} delineator={false} />;
6369
const link = action.button && (
6470
<ActionLink
65-
className={action.delineator ? "nhsuk-u-margin-bottom-0" : undefined}
71+
className={"nhsuk-u-margin-bottom-0"} // we can remove margin as there is no text below the action link currently
6672
asElement="a"
6773
href={action.button.url.href}
6874
rel="noopener"
@@ -72,10 +78,10 @@ const EligibilityActions = ({ actions, vaccineType }: EligibilityActionProps): (
7278
</ActionLink>
7379
);
7480
return (
75-
<div key={action.content} data-testid="action-auth-link-components">
81+
<div key={index} data-testid="action-auth-link-components">
7682
{info}
7783
{link}
78-
{action.delineator && <hr />}
84+
{isNotLastAction && <hr />}
7985
</div>
8086
);
8187
}
@@ -117,14 +123,14 @@ type ButtonProps = {
117123
delineator: boolean;
118124
};
119125

120-
const Button = ({ vaccineType, url, label, renderAs, delineator }: ButtonProps): JSX.Element => {
126+
const Button = ({ vaccineType, url, label, renderAs }: ButtonProps): JSX.Element => {
121127
return (
122128
<NBSBookingActionForBaseUrl
123129
vaccineType={vaccineType}
124130
url={url.href}
125131
displayText={label}
126132
renderAs={renderAs}
127-
reduceBottomPadding={delineator}
133+
reduceBottomPadding={true}
128134
/>
129135
);
130136
};

src/app/_components/eligibility/RSVEligibilityFallback.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ const RSVEligibilityFallback = (props: {
2424
<h3>{HEADINGS.IF_THIS_APPLIES}</h3>
2525
{props.howToGetVaccineFallback}
2626
<PharmacyBookingInfo vaccineType={props.vaccineType} />
27-
<hr />
2827
</div>
2928
);
3029
};

src/app/_components/eligibility/SuitabilityRules.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ describe("SuitabilityRules", () => {
4040
expectContentToBeVisible("Test Content 2");
4141
});
4242

43-
it("should display delineator depending on flag", () => {
43+
it("should display delineator for all but last rule", () => {
4444
render(
4545
SuitabilityRules({
4646
suitabilityRules: [
@@ -93,7 +93,7 @@ describe("SuitabilityRules", () => {
9393
expectContentToBeVisible("Test Content 2");
9494
});
9595

96-
it("should display delineator depending on flag", () => {
96+
it("should display delineator for all but last rule", () => {
9797
render(
9898
SuitabilityRules({
9999
suitabilityRules: [

src/app/_components/eligibility/SuitabilityRules.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,26 @@ interface SuitabilityRuleProps {
88
}
99

1010
const SuitabilityRules = ({ suitabilityRules }: SuitabilityRuleProps): (JSX.Element | undefined)[] => {
11-
return suitabilityRules.map((suitabilityRule: SuitabilityRule) => {
11+
return suitabilityRules.map((suitabilityRule: SuitabilityRule, index: number) => {
12+
const isNotLastRule: boolean = index < suitabilityRules.length - 1;
13+
1214
switch (suitabilityRule.type) {
1315
case RuleDisplayType.card: {
1416
return (
1517
<div key={suitabilityRule.content} data-testid="suitability-rule-card">
16-
<BasicCard content={suitabilityRule.content} delineator={suitabilityRule.delineator} />
18+
<BasicCard content={suitabilityRule.content} delineator={isNotLastRule} />
1719
</div>
1820
);
1921
}
2022
case RuleDisplayType.infotext: {
2123
return (
2224
<div key={suitabilityRule.content} data-testid="suitability-rule-paragraph">
23-
<MarkdownWithStyling content={suitabilityRule.content} delineator={suitabilityRule.delineator} />
25+
<MarkdownWithStyling content={suitabilityRule.content} delineator={isNotLastRule} />
2426
</div>
2527
);
2628
}
2729
}
2830
});
2931
};
32+
3033
export { SuitabilityRules };

0 commit comments

Comments
 (0)