nxtgauge-admin-solid/tests/vitest/components/ProfessionAdminListPage.test.tsx

183 lines
4.5 KiB
TypeScript
Raw Permalink Normal View History

import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent, waitFor } from "@solidjs/testing-library";
import { createSignal } from "solid-js";
import ProfessionAdminListPage from "~/components/admin/ProfessionAdminListPage";
// Mock fetch globally
const mockFetch = vi.fn();
global.fetch = mockFetch;
describe("ProfessionAdminListPage", () => {
beforeEach(() => {
mockFetch.mockClear();
});
it("renders page title and subtitle", async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: async () => [
{
id: "1",
first_name: "John",
last_name: "Doe",
email: "john@example.com",
phone: "1234567890",
status: "ACTIVE",
created_at: "2024-01-01T00:00:00Z",
},
],
});
render(() =>
ProfessionAdminListPage({
endpoint: "/api/admin/test",
title: "Test Management",
subtitle: "Manage test records",
emptyLabel: "No test records found.",
viewHref: (id) => `/admin/test/${id}`,
})
);
await waitFor(() => {
expect(screen.getByText("Test Management")).toBeInTheDocument();
expect(screen.getByText("Manage test records")).toBeInTheDocument();
});
});
it("filters by search query", async () => {
const mockData = [
{
id: "1",
first_name: "Alice",
last_name: "Smith",
email: "alice@example.com",
phone: "",
status: "ACTIVE",
created_at: "2024-01-01T00:00:00Z",
},
{
id: "2",
first_name: "Bob",
last_name: "Jones",
email: "bob@example.com",
phone: "",
status: "INACTIVE",
created_at: "2024-01-02T00:00:00Z",
},
];
mockFetch.mockResolvedValueOnce({
ok: true,
json: async () => mockData,
});
render(() =>
ProfessionAdminListPage({
endpoint: "/api/admin/test",
title: "Test",
subtitle: "",
emptyLabel: "Empty",
viewHref: (id) => `/admin/test/${id}`,
})
);
await waitFor(() => {
expect(screen.getByText("Alice Smith")).toBeInTheDocument();
expect(screen.getByText("Bob Jones")).toBeInTheDocument();
});
const input = screen.getByPlaceholderText("Search by name or email...");
fireEvent.input(input, { target: { value: "alice" } });
await waitFor(() => {
expect(screen.getByText("Alice Smith")).toBeInTheDocument();
expect(screen.queryByText("Bob Jones")).not.toBeInTheDocument();
});
});
it("shows empty state when no data", async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: async () => [],
});
render(() =>
ProfessionAdminListPage({
endpoint: "/api/admin/test",
title: "Test",
subtitle: "",
emptyLabel: "No records.",
viewHref: (id) => `/admin/test/${id}`,
})
);
await waitFor(() => {
expect(screen.getByText("No records.")).toBeInTheDocument();
});
});
it("handles fetch error gracefully", async () => {
mockFetch.mockResolvedValueOnce({
ok: false,
status: 500,
});
render(() =>
ProfessionAdminListPage({
endpoint: "/api/admin/test",
title: "Test",
subtitle: "",
emptyLabel: "Empty",
viewHref: (id) => `/admin/test/${id}`,
})
);
await waitFor(() => {
expect(screen.getByText(/Failed to load/)).toBeInTheDocument();
});
});
it("export button calls exportCsv and downloads file", async () => {
const mockData = [
{
id: "1",
first_name: "Alice",
last_name: "Smith",
email: "alice@example.com",
phone: "123",
status: "ACTIVE",
created_at: "2024-01-01T00:00:00Z",
},
];
mockFetch.mockResolvedValueOnce({
ok: true,
json: async () => mockData,
});
// Mock URL.createObjectURL and link.click
const mockClick = vi.fn();
global.URL.createObjectURL = vi.fn(() => "blob:test");
global.document.createElement = vi.fn(() => ({ click: mockClick, href: "" }));
render(() =>
ProfessionAdminListPage({
endpoint: "/api/admin/test",
title: "Test",
subtitle: "",
emptyLabel: "Empty",
viewHref: (id) => `/admin/test/${id}`,
})
);
await waitFor(() => {
expect(screen.getByText("Alice Smith")).toBeInTheDocument();
});
const exportBtn = screen.getByText("Export");
fireEvent.click(exportBtn);
expect(mockClick).toHaveBeenCalled();
});
});