nxtgauge-admin-solid/tests/vitest/components/ProfessionAdminListPage.test.tsx
Tracewebstudio Dev bed7035ec5
All checks were successful
build-and-release / build (push) Successful in 1m19s
fix: TypeScript errors, test quality, and admin panel correctness
- tsconfig.json: add @types/node for playwright/test configs
- lib/api.ts: handle both array and wrapped packages response from tracecoin endpoint
- lib/server/gateway.ts: use import.meta.env instead of process.env
- routes/admin/pricing.tsx: fix packages() usage after api.ts fix
- routes/admin/roles/*.tsx: fix Set<string> types and module filter types
- routes/admin/users/[id]/edit.tsx: add phone? to local User type
- routes/admin/users/details/[id].tsx: fix roleFilter param type narrowing
- components/admin/DashboardDesignPreview.tsx: fix budget→budget, responses→responseTag
- vite.config.ts: type proxy callbacks as any
- test/setup.ts: fix IntersectionObserver mock, add vitest/globals reference
- tests/e2e: fix PNG type mismatches, add as any for mock overrides
- tests/vitest: fix global.createElement mock type, vitest globals reference
- tests/tsconfig.json: test-specific tsconfig with node types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-17 00:47:43 +02:00

183 lines
4.6 KiB
TypeScript

/// <reference types="vitest/globals" />
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: "" })) as any;
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();
});
});