Skip to content

Commit 75750c8

Browse files
committed
Add test coverage for the new page
1 parent ec41aca commit 75750c8

File tree

4 files changed

+188
-40
lines changed

4 files changed

+188
-40
lines changed

packages/cpt-ui/__tests__/SelectYourRolePage.test.jsx

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import "@testing-library/jest-dom";
2+
import { render, screen, waitFor } from "@testing-library/react";
3+
import SelectYourRolePage from "../app/selectyourrole/page";
4+
import React from "react";
5+
import { AuthContext } from "@/context/AuthContext";
6+
7+
// Mock `next/navigation` globally
8+
jest.mock("next/navigation", () => ({
9+
usePathname: jest.fn(),
10+
useRouter: jest.fn(),
11+
}));
12+
13+
// Define a global fetch mock
14+
const mockFetch = jest.fn();
15+
global.fetch = mockFetch;
16+
17+
describe("SelectYourRolePage", () => {
18+
const mockAuthContextValue = {
19+
isSignedIn: false,
20+
idToken: "",
21+
};
22+
23+
// Helper: Renders component with optional custom AuthContext value
24+
const renderWithAuth = (authValue: any = mockAuthContextValue) => {
25+
return render(
26+
<AuthContext.Provider value={authValue}>
27+
<SelectYourRolePage />
28+
</AuthContext.Provider>
29+
);
30+
};
31+
32+
beforeEach(() => {
33+
jest.clearAllMocks();
34+
});
35+
36+
it("renders a heading by default (not signed in) but eventually shows an error", async () => {
37+
// Not signed in
38+
renderWithAuth({
39+
isSignedIn: false,
40+
idToken: "",
41+
});
42+
43+
// Wait for error summary to appear
44+
await waitFor(() => {
45+
const errorHeading = screen.getByRole("heading", { name: /Error during role selection/i })
46+
expect(errorHeading).toBeInTheDocument();
47+
const errorText = screen.getByText("No login session found");
48+
expect(errorText).toBeInTheDocument();
49+
});
50+
});
51+
52+
it("renders loading state when signed in but fetch hasn't resolved yet", async () => {
53+
// Mock fetch to never resolve
54+
mockFetch.mockImplementation(() => new Promise(() => {}));
55+
56+
renderWithAuth({
57+
isSignedIn: true,
58+
idToken: "fake-token",
59+
});
60+
61+
// Should show "Loading..." text
62+
const loadingText = screen.getByText(/loading.../i);
63+
expect(loadingText).toBeInTheDocument();
64+
});
65+
66+
it("renders error summary if fetch returns non-200 status", async () => {
67+
// Mock fetch to return 500 status
68+
mockFetch.mockResolvedValue({
69+
status: 500,
70+
});
71+
72+
renderWithAuth({
73+
isSignedIn: true,
74+
idToken: "fake-token",
75+
});
76+
77+
// Expect error summary to appear
78+
await waitFor(() => {
79+
const errorHeading = screen.getByRole("heading", { name: /Error during role selection/i });
80+
expect(errorHeading).toBeInTheDocument();
81+
const errorItem = screen.getByText("Failed to fetch CPT user info");
82+
expect(errorItem).toBeInTheDocument();
83+
});
84+
});
85+
86+
it("renders error summary if fetch returns 200 but the JSON body has no userInfo key", async () => {
87+
// Mock a 200 response without `userInfo`
88+
mockFetch.mockResolvedValue({
89+
status: 200,
90+
json: async () => ({}), // Missing userInfo
91+
});
92+
93+
renderWithAuth({
94+
isSignedIn: true,
95+
idToken: "fake-token",
96+
});
97+
98+
// Expect error summary to appear
99+
await waitFor(() => {
100+
const errorHeading = screen.getByRole("heading", { name: /Error during role selection/i });
101+
expect(errorHeading).toBeInTheDocument();
102+
const errorItem = screen.getByText("Failed to fetch CPT user info");
103+
expect(errorItem).toBeInTheDocument();
104+
});
105+
});
106+
107+
it("renders the page content when valid userInfo is returned", async () => {
108+
const mockUserInfo = {
109+
roles_with_access: [
110+
{
111+
role_name: "Pharmacist",
112+
role_id: "pharm1",
113+
org_code: "ORG123",
114+
org_name: "Test Pharmacy Org",
115+
site_name: "Pharmacy Site",
116+
site_address: "1 Fake Street",
117+
},
118+
],
119+
roles_without_access: [
120+
{
121+
role_name: "Technician",
122+
role_id: "tech1",
123+
org_code: "ORG456",
124+
org_name: "Tech Org",
125+
site_name: "Technician Site",
126+
site_address: "2 Fake Street",
127+
},
128+
],
129+
};
130+
131+
// Mock a successful 200 response
132+
mockFetch.mockResolvedValue({
133+
status: 200,
134+
json: async () => ({
135+
userInfo: mockUserInfo,
136+
}),
137+
});
138+
139+
renderWithAuth({
140+
isSignedIn: true,
141+
idToken: "fake-token",
142+
});
143+
144+
// Wait for normal state to appear (no errors)
145+
await waitFor(() => {
146+
// Title
147+
const heading = screen.getByRole("heading", { level: 1 });
148+
expect(heading).toHaveTextContent("Select your role"); // from SELECT_ROLE_PAGE_TEXT
149+
});
150+
151+
// Check the caption
152+
const caption = screen.getByText(/Select the role you wish to use to access the service/i);
153+
expect(caption).toBeInTheDocument();
154+
155+
// Check that the "contentinfo" container is rendered
156+
const container = screen.getByRole("contentinfo");
157+
expect(container).toBeInTheDocument();
158+
159+
// Check for confirm button text
160+
const confirmButton = screen.getByRole("button", { name: /Confirm and continue/i });
161+
expect(confirmButton).toBeInTheDocument();
162+
163+
// Roles Without Access details expander
164+
const expander = screen.getByText("Roles without access");
165+
expect(expander).toBeInTheDocument();
166+
167+
// Expand details if needed or just confirm the table is present
168+
// For the table, look for the "Tech Org" text or the column values
169+
const orgCell = await screen.findByText(/Tech Org \(ODS: ORG456\)/i);
170+
expect(orgCell).toBeInTheDocument();
171+
172+
const roleCell = await screen.findByText("Technician");
173+
expect(roleCell).toBeInTheDocument();
174+
});
175+
});

packages/cpt-ui/app/selectyourrole/page.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ export default function SelectYourRolePage() {
7373
useEffect(() => {
7474
if (auth?.isSignedIn) {
7575
fetchTrackerUserInfo()
76+
} else {
77+
setError("No login session found")
7678
}
7779
}, [auth?.isSignedIn, fetchTrackerUserInfo])
7880

packages/cpt-ui/jest.config.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
import nextJest from "next/jest"
2+
23
const createJestConfig = nextJest({
34
dir: "./"
45
})
6+
57
const customJestConfig = {
68
collectCoverage: true,
79
coverageDirectory: "coverage",
810
coverageProvider: "v8",
11+
rootDir: "./",
912
moduleDirectories: ["node_modules", "<rootDir>/"],
10-
testEnvironment: "jest-environment-jsdom"
13+
testEnvironment: "jest-environment-jsdom",
14+
moduleNameMapper: {
15+
"^@/context/(.*)$": "<rootDir>/context/$1",
16+
"^@/constants/(.*)$": "<rootDir>/constants/$1",
17+
"^@/assets/(.*)$": "<rootDir>/assets/$1",
18+
"^@/components/(.*)$": "<rootDir>/components/$1"
19+
}
1120
}
21+
1222
module.exports = createJestConfig(customJestConfig)

0 commit comments

Comments
 (0)