test(web): add 291 tests for parsers, hooks, and UI components
Lib utilities: scopeImportParser (31), status-styles (58), planningEntryIds (10), uuid (11). Hooks: useFilters (28), useRowOrder (18), usePermissions (30), useViewPrefs (24). Components: AnimatedModal (14), DateInput (22), InfoTooltip (13), ProgressRing (19). Web test suite: 75 → 87 files, 553 → 844 tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
|
||||
import { renderHook } from "@testing-library/react";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Mock next-auth/react so the hook can run without a real auth provider.
|
||||
// ---------------------------------------------------------------------------
|
||||
const mockUseSession = vi.fn();
|
||||
|
||||
vi.mock("next-auth/react", () => ({
|
||||
useSession: () => mockUseSession(),
|
||||
}));
|
||||
|
||||
const { usePermissions } = await import("./usePermissions.js");
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helper: build a mock session object with the given role.
|
||||
// ---------------------------------------------------------------------------
|
||||
function sessionWith(role: string) {
|
||||
return { data: { user: { role } } };
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tests
|
||||
// ---------------------------------------------------------------------------
|
||||
describe("usePermissions", () => {
|
||||
beforeEach(() => {
|
||||
mockUseSession.mockReset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// No session / unauthenticated
|
||||
// -------------------------------------------------------------------------
|
||||
describe("when there is no session", () => {
|
||||
it("falls back to role USER when data is null", () => {
|
||||
mockUseSession.mockReturnValue({ data: null });
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.role).toBe("USER");
|
||||
});
|
||||
|
||||
it("falls back to role USER when data is undefined", () => {
|
||||
mockUseSession.mockReturnValue({ data: undefined });
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.role).toBe("USER");
|
||||
});
|
||||
|
||||
it("falls back to role USER when user has no role property", () => {
|
||||
mockUseSession.mockReturnValue({ data: { user: {} } });
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.role).toBe("USER");
|
||||
});
|
||||
|
||||
it("denies all privileged permissions for anonymous user", () => {
|
||||
mockUseSession.mockReturnValue({ data: null });
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewCosts).toBe(false);
|
||||
expect(result.current.canEdit).toBe(false);
|
||||
expect(result.current.canManageUsers).toBe(false);
|
||||
expect(result.current.canManageBlueprints).toBe(false);
|
||||
expect(result.current.canViewScores).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// ADMIN role
|
||||
// -------------------------------------------------------------------------
|
||||
describe("ADMIN role", () => {
|
||||
beforeEach(() => {
|
||||
mockUseSession.mockReturnValue(sessionWith("ADMIN"));
|
||||
});
|
||||
|
||||
it("exposes role as ADMIN", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.role).toBe("ADMIN");
|
||||
});
|
||||
|
||||
it("canViewCosts is true", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewCosts).toBe(true);
|
||||
});
|
||||
|
||||
it("canEdit is true", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canEdit).toBe(true);
|
||||
});
|
||||
|
||||
it("canManageUsers is true", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canManageUsers).toBe(true);
|
||||
});
|
||||
|
||||
it("canManageBlueprints is true", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canManageBlueprints).toBe(true);
|
||||
});
|
||||
|
||||
it("canViewScores is true", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewScores).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// MANAGER role
|
||||
// -------------------------------------------------------------------------
|
||||
describe("MANAGER role", () => {
|
||||
beforeEach(() => {
|
||||
mockUseSession.mockReturnValue(sessionWith("MANAGER"));
|
||||
});
|
||||
|
||||
it("exposes role as MANAGER", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.role).toBe("MANAGER");
|
||||
});
|
||||
|
||||
it("canViewCosts is true", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewCosts).toBe(true);
|
||||
});
|
||||
|
||||
it("canEdit is true", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canEdit).toBe(true);
|
||||
});
|
||||
|
||||
it("canManageUsers is false", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canManageUsers).toBe(false);
|
||||
});
|
||||
|
||||
it("canManageBlueprints is false", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canManageBlueprints).toBe(false);
|
||||
});
|
||||
|
||||
it("canViewScores is true", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewScores).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// CONTROLLER role
|
||||
// -------------------------------------------------------------------------
|
||||
describe("CONTROLLER role", () => {
|
||||
beforeEach(() => {
|
||||
mockUseSession.mockReturnValue(sessionWith("CONTROLLER"));
|
||||
});
|
||||
|
||||
it("exposes role as CONTROLLER", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.role).toBe("CONTROLLER");
|
||||
});
|
||||
|
||||
it("canViewCosts is true", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewCosts).toBe(true);
|
||||
});
|
||||
|
||||
it("canEdit is false (CONTROLLER is not in EDIT_ROLES)", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canEdit).toBe(false);
|
||||
});
|
||||
|
||||
it("canManageUsers is false", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canManageUsers).toBe(false);
|
||||
});
|
||||
|
||||
it("canManageBlueprints is false", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canManageBlueprints).toBe(false);
|
||||
});
|
||||
|
||||
it("canViewScores is false (CONTROLLER is not in SCORE_ROLES)", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewScores).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// USER role (default / authenticated but unprivileged)
|
||||
// -------------------------------------------------------------------------
|
||||
describe("USER role", () => {
|
||||
beforeEach(() => {
|
||||
mockUseSession.mockReturnValue(sessionWith("USER"));
|
||||
});
|
||||
|
||||
it("exposes role as USER", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.role).toBe("USER");
|
||||
});
|
||||
|
||||
it("canViewCosts is false", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewCosts).toBe(false);
|
||||
});
|
||||
|
||||
it("canEdit is false", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canEdit).toBe(false);
|
||||
});
|
||||
|
||||
it("canManageUsers is false", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canManageUsers).toBe(false);
|
||||
});
|
||||
|
||||
it("canManageBlueprints is false", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canManageBlueprints).toBe(false);
|
||||
});
|
||||
|
||||
it("canViewScores is false", () => {
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewScores).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Unknown / arbitrary role
|
||||
// -------------------------------------------------------------------------
|
||||
describe("unknown role", () => {
|
||||
it("denies all privileged permissions for an unknown role string", () => {
|
||||
mockUseSession.mockReturnValue(sessionWith("SUPER_DUPER_ADMIN"));
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.canViewCosts).toBe(false);
|
||||
expect(result.current.canEdit).toBe(false);
|
||||
expect(result.current.canManageUsers).toBe(false);
|
||||
expect(result.current.canManageBlueprints).toBe(false);
|
||||
expect(result.current.canViewScores).toBe(false);
|
||||
});
|
||||
|
||||
it("still surfaces the raw role string for arbitrary roles", () => {
|
||||
mockUseSession.mockReturnValue(sessionWith("VIEWER"));
|
||||
const { result } = renderHook(() => usePermissions());
|
||||
expect(result.current.role).toBe("VIEWER");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user