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(); }); });