Skip to content

Commit ac0b4ed

Browse files
fixed test
1 parent 1d5b2b6 commit ac0b4ed

File tree

2 files changed

+82
-13
lines changed

2 files changed

+82
-13
lines changed

packages/cpt-ui/__tests__/EpsTabs.test.tsx

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
useLocation
77
} from "react-router-dom"
88
import {render, screen, waitFor} from "@testing-library/react"
9+
import userEvent from "@testing-library/user-event"
910
import "@testing-library/jest-dom"
1011

1112
import EpsTabs, {TabHeader} from "@/components/EpsTabs"
@@ -15,8 +16,8 @@ function LocationIndicator() {
1516
return <div data-testid="current-path">{location.pathname}</div>
1617
}
1718

18-
type HarnessProps = { variant?: "default" | "large" }
19-
function Harness({variant = "default"}: HarnessProps) {
19+
type HarnessProps = { variant?: "default" | "large"; includeQuery?: boolean }
20+
function Harness({variant = "default", includeQuery = false}: HarnessProps) {
2021
const location = useLocation()
2122
const tabHeaderArray: Array<TabHeader> = [
2223
{title: "(1)", link: "/prescription-list-current"},
@@ -26,12 +27,13 @@ function Harness({variant = "default"}: HarnessProps) {
2627

2728
return (
2829
<EpsTabs
29-
activeTabPath={location.pathname}
30+
activeTabPath={includeQuery ? location.pathname + location.search : location.pathname}
3031
tabHeaderArray={tabHeaderArray}
3132
variant={variant}
3233
>
3334
<div>
3435
<input data-testid="dummy-input" />
36+
<textarea data-testid="dummy-textarea" />
3537
<LocationIndicator />
3638
<div data-testid="panel-content">Panel</div>
3739
</div>
@@ -53,31 +55,31 @@ describe("EpsTabs", () => {
5355
expect(screen.getByTestId("current-path")).toHaveTextContent("/prescription-list-current")
5456

5557
// ArrowRight to future
56-
window.dispatchEvent(new KeyboardEvent("keydown", {key: "ArrowRight"}))
58+
await userEvent.keyboard("{ArrowRight}")
5759
await waitFor(() => {
5860
expect(screen.getByTestId("current-path")).toHaveTextContent("/prescription-list-future")
5961
})
6062

6163
// ArrowRight to past
62-
window.dispatchEvent(new KeyboardEvent("keydown", {key: "ArrowRight"}))
64+
await userEvent.keyboard("{ArrowRight}")
6365
await waitFor(() => {
6466
expect(screen.getByTestId("current-path")).toHaveTextContent("/prescription-list-past")
6567
})
6668

6769
// ArrowRight at last stays on past
68-
window.dispatchEvent(new KeyboardEvent("keydown", {key: "ArrowRight"}))
70+
await userEvent.keyboard("{ArrowRight}")
6971
await waitFor(() => {
7072
expect(screen.getByTestId("current-path")).toHaveTextContent("/prescription-list-past")
7173
})
7274

7375
// ArrowLeft goes back to future
74-
window.dispatchEvent(new KeyboardEvent("keydown", {key: "ArrowLeft"}))
76+
await userEvent.keyboard("{ArrowLeft}")
7577
await waitFor(() => {
7678
expect(screen.getByTestId("current-path")).toHaveTextContent("/prescription-list-future")
7779
})
7880
})
7981

80-
it("does not navigate when focus is inside an input", () => {
82+
it("does not navigate when focus is inside an input", async () => {
8183
render(
8284
<MemoryRouter initialEntries={["/prescription-list-current"]}>
8385
<Routes>
@@ -89,8 +91,75 @@ describe("EpsTabs", () => {
8991
// Focus input then press ArrowRight – should not change tab
9092
const input = screen.getByTestId("dummy-input") as HTMLInputElement
9193
input.focus()
92-
window.dispatchEvent(new KeyboardEvent("keydown", {key: "ArrowRight"}))
94+
await userEvent.keyboard("{ArrowRight}")
95+
expect(screen.getByTestId("current-path")).toHaveTextContent("/prescription-list-current")
96+
})
97+
98+
it("does not navigate when focus is inside a textarea", async () => {
99+
render(
100+
<MemoryRouter initialEntries={["/prescription-list-current"]}>
101+
<Routes>
102+
<Route path="*" element={<Harness />} />
103+
</Routes>
104+
</MemoryRouter>
105+
)
106+
107+
const textarea = screen.getByTestId("dummy-textarea") as HTMLTextAreaElement
108+
textarea.focus()
109+
await userEvent.keyboard("{ArrowRight}")
110+
expect(screen.getByTestId("current-path")).toHaveTextContent("/prescription-list-current")
111+
})
112+
113+
it("navigates correctly when activeTabPath includes a query string", async () => {
114+
render(
115+
<MemoryRouter initialEntries={["/prescription-list-current?nhsNumber=123456"]}>
116+
<Routes>
117+
<Route path="*" element={<Harness includeQuery />} />
118+
</Routes>
119+
</MemoryRouter>
120+
)
121+
122+
// With query in activeTabPath, startsWith should still match and allow navigation
93123
expect(screen.getByTestId("current-path")).toHaveTextContent("/prescription-list-current")
124+
await userEvent.keyboard("{ArrowRight}")
125+
await waitFor(() => {
126+
expect(screen.getByTestId("current-path")).toHaveTextContent("/prescription-list-future")
127+
})
128+
})
129+
130+
it("cleans up keydown listener on unmount", async () => {
131+
const {unmount} = render(
132+
<MemoryRouter initialEntries={["/prescription-list-current"]}>
133+
<Routes>
134+
<Route path="*" element={<Harness />} />
135+
</Routes>
136+
</MemoryRouter>
137+
)
138+
139+
unmount()
140+
// Dispatching events after unmount should not change the path
141+
window.dispatchEvent(new KeyboardEvent("keydown", {key: "ArrowRight"}))
142+
// Nothing to assert about path change here since component is unmounted;
143+
// this test ensures no errors are thrown during cleanup.
144+
expect(true).toBe(true)
145+
})
146+
147+
it("sets aria-selected and tabIndex correctly for active/inactive tabs", () => {
148+
render(
149+
<MemoryRouter initialEntries={["/prescription-list-current"]}>
150+
<Routes>
151+
<Route path="*" element={<Harness />} />
152+
</Routes>
153+
</MemoryRouter>
154+
)
155+
156+
const currentTab = screen.getByTestId("eps-tab-heading /prescription-list-current")
157+
const futureTab = screen.getByTestId("eps-tab-heading /prescription-list-future")
158+
159+
expect(currentTab).toHaveAttribute("aria-selected", "true")
160+
expect(currentTab).toHaveAttribute("tabIndex", "0")
161+
expect(futureTab).toHaveAttribute("aria-selected", "false")
162+
expect(futureTab).toHaveAttribute("tabIndex", "-1")
94163
})
95164

96165
it("applies the large variant class", () => {

packages/cpt-ui/src/components/EpsTabs.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default function EpsTabs({
3838
}
3939
const tabs = tabHeaderArray
4040
const currentTabIndex = tabs.findIndex(
41-
(tab) => tab.link.includes(activeTabPath)
41+
(tab) => activeTabPath.startsWith(tab.link)
4242
)
4343

4444
let newTabIndex = currentTabIndex
@@ -52,13 +52,13 @@ export default function EpsTabs({
5252
const newTab = tabs[newTabIndex]
5353
navigate(newTab.link)
5454
}
55-
}, [navigate])
55+
}, [navigate, tabHeaderArray, activeTabPath])
5656

5757
useEffect(() => {
58-
window.addEventListener("keydown", handleKeyDown)
58+
document.addEventListener("keydown", handleKeyDown)
5959

6060
return () => {
61-
window.removeEventListener("keydown", handleKeyDown)
61+
document.removeEventListener("keydown", handleKeyDown)
6262
}
6363
}, [handleKeyDown])
6464

0 commit comments

Comments
 (0)