forked from baron/baron-sso
adminfront 및 백엔드: ReBAC 기반 각 탭별 읽기/쓰기 권한 제어 구현
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import { renderHook } from "@testing-library/react";
|
||||
import type React from "react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { fetchTenant, fetchMe } from "../../../lib/adminApi";
|
||||
import { useTenantPermission } from "./useTenantPermission";
|
||||
import { TenantPermissionGuard } from "../components/TenantPermissionGuard";
|
||||
|
||||
vi.mock("../../../lib/adminApi", () => ({
|
||||
fetchMe: vi.fn(),
|
||||
fetchTenant: vi.fn(),
|
||||
}));
|
||||
|
||||
function createWrapper() {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: { retry: false },
|
||||
},
|
||||
});
|
||||
return ({ children }: { children: React.ReactNode }) => (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
describe("useTenantPermission", () => {
|
||||
it("returns true for all permissions if user is super_admin", async () => {
|
||||
vi.mocked(fetchMe).mockResolvedValue({
|
||||
id: "user-super",
|
||||
role: "super_admin",
|
||||
} as any);
|
||||
|
||||
vi.mocked(fetchTenant).mockResolvedValue({
|
||||
id: "tenant-1",
|
||||
name: "Super Tenant",
|
||||
userPermissions: { view: false, manage: false, manage_admins: false },
|
||||
} as any);
|
||||
|
||||
const { result } = renderHook(() => useTenantPermission("tenant-1"), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.isLoading).toBe(false);
|
||||
});
|
||||
|
||||
expect(result.current.hasPermission("view")).toBe(true);
|
||||
expect(result.current.hasPermission("manage")).toBe(true);
|
||||
expect(result.current.hasPermission("manage_admins")).toBe(true);
|
||||
});
|
||||
|
||||
it("returns permissions mapped from userPermissions for normal admins/users", async () => {
|
||||
vi.mocked(fetchMe).mockResolvedValue({
|
||||
id: "user-admin",
|
||||
role: "tenant_admin",
|
||||
} as any);
|
||||
|
||||
vi.mocked(fetchTenant).mockResolvedValue({
|
||||
id: "tenant-2",
|
||||
name: "Tenant Admin Corp",
|
||||
userPermissions: { view: true, manage: true, manage_admins: false },
|
||||
} as any);
|
||||
|
||||
const { result } = renderHook(() => useTenantPermission("tenant-2"), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.isLoading).toBe(false);
|
||||
});
|
||||
|
||||
expect(result.current.hasPermission("view")).toBe(true);
|
||||
expect(result.current.hasPermission("manage")).toBe(true);
|
||||
expect(result.current.hasPermission("manage_admins")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("TenantPermissionGuard", () => {
|
||||
it("renders children when user has permission", async () => {
|
||||
vi.mocked(fetchMe).mockResolvedValue({
|
||||
id: "user-admin",
|
||||
role: "tenant_admin",
|
||||
} as any);
|
||||
|
||||
vi.mocked(fetchTenant).mockResolvedValue({
|
||||
id: "tenant-3",
|
||||
userPermissions: { view: true, manage: true, manage_admins: false },
|
||||
} as any);
|
||||
|
||||
render(
|
||||
<TenantPermissionGuard tenantId="tenant-3" relation="manage" fallback={<div>Access Denied</div>}>
|
||||
<div>Access Granted</div>
|
||||
</TenantPermissionGuard>,
|
||||
{ wrapper: createWrapper() }
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Access Granted")).toBeInTheDocument();
|
||||
});
|
||||
expect(screen.queryByText("Access Denied")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders fallback when user lacks permission", async () => {
|
||||
vi.mocked(fetchMe).mockResolvedValue({
|
||||
id: "user-admin",
|
||||
role: "tenant_admin",
|
||||
} as any);
|
||||
|
||||
vi.mocked(fetchTenant).mockResolvedValue({
|
||||
id: "tenant-4",
|
||||
userPermissions: { view: true, manage: false, manage_admins: false },
|
||||
} as any);
|
||||
|
||||
render(
|
||||
<TenantPermissionGuard tenantId="tenant-4" relation="manage" fallback={<div>Access Denied</div>}>
|
||||
<div>Access Granted</div>
|
||||
</TenantPermissionGuard>,
|
||||
{ wrapper: createWrapper() }
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Access Denied")).toBeInTheDocument();
|
||||
});
|
||||
expect(screen.queryByText("Access Granted")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user