Skip to content
This repository was archived by the owner on Jul 8, 2025. It is now read-only.

Commit b9bc1ec

Browse files
committed
test: add App tests
1 parent 44ab1ac commit b9bc1ec

File tree

5 files changed

+102
-3
lines changed

5 files changed

+102
-3
lines changed

src/App.test.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { render } from "@/lib/test-utils";
2+
import { screen, waitFor } from "@testing-library/react";
3+
import { describe, expect, it, vi } from "vitest";
4+
import App from "./App";
5+
import React from "react";
6+
7+
vi.mock("recharts", async (importOriginal) => {
8+
const originalModule = (await importOriginal()) as Record<string, unknown>;
9+
return {
10+
...originalModule,
11+
ResponsiveContainer: ({ children }: { children: React.ReactNode }) => {
12+
return <div data-testid="mock-responsive-container">{children}</div>;
13+
},
14+
};
15+
});
16+
17+
describe("App", () => {
18+
it("should render header", async () => {
19+
render(<App />);
20+
expect(screen.getByText(/toggle sidebar/i)).toBeVisible();
21+
expect(screen.getByText("Certificates")).toBeVisible();
22+
expect(screen.getByText("Help")).toBeVisible();
23+
expect(screen.getByRole("banner")).toBeVisible();
24+
expect(
25+
screen.getByRole("heading", { name: /codeGate dashboard/i }),
26+
).toBeVisible();
27+
expect(
28+
screen.getByRole("link", {
29+
name: /certificate security/i,
30+
}),
31+
).toBeVisible();
32+
expect(
33+
screen.getByRole("link", {
34+
name: /continue setup/i,
35+
}),
36+
).toBeVisible();
37+
38+
expect(
39+
screen.getByRole("link", {
40+
name: /copilot setup/i,
41+
}),
42+
).toBeVisible();
43+
expect(
44+
screen.getByRole("link", {
45+
name: /download/i,
46+
}),
47+
).toBeVisible();
48+
expect(
49+
screen.getByRole("link", {
50+
name: /documentation/i,
51+
}),
52+
).toBeVisible();
53+
await waitFor(() =>
54+
expect(
55+
screen.getByRole("link", { name: /codeGate dashboard/i }),
56+
).toBeVisible(),
57+
);
58+
});
59+
60+
it("should render breadcrumb", async () => {
61+
render(<App />);
62+
await waitFor(() =>
63+
expect(
64+
screen.getByRole("link", { name: /codeGate dashboard/i }),
65+
).toBeVisible(),
66+
);
67+
expect(screen.getByRole("link", { name: "Dashboard" })).toBeVisible();
68+
});
69+
});

src/components/Header.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Separator } from "./ui/separator";
44

55
export function Header() {
66
return (
7-
<div className="flex-shrink-0 h-16 px-3 items-center flex w-full bg-teal-25 opacity-1 border-b-blue-200 border-b">
7+
<header className="flex-shrink-0 h-16 px-3 items-center flex w-full bg-teal-25 opacity-1 border-b-blue-200 border-b">
88
<div className="flex items-center flex-1">
99
<SidebarTrigger />
1010
<Separator orientation="vertical" className="h-8 mx-3" />
@@ -72,6 +72,6 @@ export function Header() {
7272
</div>
7373
</div>
7474
</div>
75-
</div>
75+
</header>
7676
);
7777
}

src/lib/test-utils.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { SidebarProvider } from "@/components/ui/sidebar";
12
import { RenderOptions, render } from "@testing-library/react";
23
import React from "react";
34
import {
@@ -19,7 +20,10 @@ const renderWithProviders = (
1920
render(
2021
<MemoryRouter {...options?.routeConfig}>
2122
<Routes>
22-
<Route path={options?.pathConfig ?? "/"} element={children} />
23+
<Route
24+
path={options?.pathConfig ?? "*"}
25+
element={<SidebarProvider>{children}</SidebarProvider>}
26+
/>
2327
</Routes>
2428
</MemoryRouter>,
2529
);

vitest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export default defineConfig({
4040
"test?(-*).?(c|m)[jt]s?(x)",
4141
"**/*{.,-}{test,spec}?(-d).?(c|m)[jt]s?(x)",
4242
"**/__tests__/**",
43+
"**/test-utils.tsx",
4344
"**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*",
4445
"**/vitest.{workspace,projects}.[jt]s?(on)",
4546
"**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}",

vitest.setup.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ import { cleanup } from "@testing-library/react";
55
import { afterEach, expect, beforeAll, afterAll, vi } from "vitest";
66
import failOnConsole from "vitest-fail-on-console";
77

8+
class MockEventSource {
9+
onmessage: ((event: MessageEvent) => void) | null = null;
10+
11+
constructor() {}
12+
13+
close() {}
14+
15+
triggerMessage(data: string) {
16+
if (this.onmessage) {
17+
this.onmessage({ data } as MessageEvent);
18+
}
19+
}
20+
}
21+
822
expect.extend(testingLibraryMatchers);
923

1024
afterEach(() => {
@@ -16,6 +30,17 @@ beforeAll(() => {
1630
onUnhandledRequest: "error",
1731
});
1832

33+
global.window.matchMedia = vi.fn().mockImplementation((query) => ({
34+
matches: false,
35+
media: query,
36+
onchange: null,
37+
addEventListener: vi.fn(),
38+
removeEventListener: vi.fn(),
39+
dispatchEvent: vi.fn(),
40+
}));
41+
42+
global.EventSource = MockEventSource as unknown as typeof EventSource;
43+
1944
global.ResizeObserver = class ResizeObserver {
2045
disconnect() {
2146
// do nothing

0 commit comments

Comments
 (0)