Skip to content

Commit

Permalink
test: track error states
Browse files Browse the repository at this point in the history
  • Loading branch information
arunanshub committed Feb 20, 2025
1 parent 5dce7e5 commit 36c0723
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 35 deletions.
11 changes: 10 additions & 1 deletion src/app/v2/policy/list/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@ import { Plus } from "lucide-react";
import Link from "next/link";
import { getPolicies } from "./actions";
import { columns } from "./columns";
import { toast } from "sonner";
import { useEffect } from "react";

export default function PolicyListClient() {
const { data: policies } = useQuery({
const { data: policies, error } = useQuery({
queryKey: ["policies"],
queryFn: () => getPolicies(),
initialData: [],
});

// show a toast if there is an error
useEffect(() => {
if (error) {
toast.error("Failed to fetch policies");
}
}, [error]);

return (
<div className="container mx-auto py-6">
<div className="mb-6 flex items-center justify-between">
Expand Down
66 changes: 32 additions & 34 deletions src/app/v2/policy/list/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,26 @@ import {
} from "@buf/safedep_api.bufbuild_es/safedep/messages/policy/v1/policy_pb";
import { act } from "react";

// Create a mock object with a mock function for getPolicies vi.hoisted ensures
// the mock is created before all tests
const mocks = vi.hoisted(() => ({
getPolicies: vi.fn(),

// sonner library's toast object
toast: {
success: vi.fn(),
error: vi.fn(),
},
}));

// Mock the sonner library to replace the toast object with our mock object
vi.mock("sonner", () => ({
toast: mocks.toast,
}));

// Mock the ./actions module to replace getPolicies with our mock function
vi.mock("./actions", () => ({
getPolicies: vi.fn(
() =>
[
{
id: "1",
name: "Policy 1",
version: PolicyVersion.V1,
type: PolicyType.DENY,
labels: ["label1", "label2"],
rulesCount: 1,
target: PolicyTarget.VET,
},
{
id: "2",
name: "Policy 2",
version: PolicyVersion.V2,
type: PolicyType.ALLOW,
labels: ["label3"],
rulesCount: 3,
target: PolicyTarget.VET,
},
{
id: "3",
name: "Policy 3",
version: PolicyVersion.V2,
type: PolicyType.ALLOW,
labels: ["label3", "some-label"],
rulesCount: 3,
target: PolicyTarget.VET,
},
] satisfies Policy[],
),
getPolicies: mocks.getPolicies,
}));

// Utility to create a fresh QueryClient for each test
Expand Down Expand Up @@ -113,6 +100,7 @@ describe("Policy list page", () => {
}

it("can be mounted", async () => {
mocks.getPolicies.mockResolvedValue([]);
await Page();
});

Expand Down Expand Up @@ -143,8 +131,6 @@ describe("Policy list page", () => {
});

it("renders table rows with correct content", async () => {
await setupComponent();

const expectedPolicies = [
{
id: "1",
Expand Down Expand Up @@ -174,6 +160,9 @@ describe("Policy list page", () => {
target: PolicyTarget.VET,
},
] satisfies Policy[];
mocks.getPolicies.mockResolvedValue(expectedPolicies);

await setupComponent();

await waitFor(() => {
// Get all rows (excluding header row)
Expand Down Expand Up @@ -204,4 +193,13 @@ describe("Policy list page", () => {
}
});
});

it("renders error toast when policy fetch fails", async () => {
mocks.getPolicies.mockRejectedValue(new Error("Failed to fetch policies"));
await setupComponent();

await waitFor(() => {
expect(mocks.toast.error).toHaveBeenCalledOnce();
});
});
});

0 comments on commit 36c0723

Please sign in to comment.