dify/web/service/access-control/__tests__/use-workspace-access-rules.spec.tsx
Stephen Zhou a84c2d36a3
style: format with vp fmt (#38803)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:57:46 +00:00

133 lines
4.2 KiB
TypeScript

import type { ReactNode } from 'react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { act, renderHook, waitFor } from '@testing-library/react'
import { del, get, post, put } from '@/service/base'
import {
useCopyAccessRule,
useCreateAccessRule,
useDeleteAccessRule,
useInfiniteWorkspaceAppAccessRules,
useInfiniteWorkspaceDatasetAccessRules,
useUpdateAccessRule,
} from '../use-workspace-access-rules'
vi.mock('@/service/base', () => ({
del: vi.fn(),
get: vi.fn(),
post: vi.fn(),
put: vi.fn(),
}))
const createWrapper = () => {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
})
return ({ children }: { children: ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
}
describe('use-workspace-access-rules', () => {
beforeEach(() => {
vi.clearAllMocks()
vi.mocked(get).mockResolvedValue({ items: [], pagination: {} })
vi.mocked(post).mockResolvedValue({})
vi.mocked(put).mockResolvedValue({})
vi.mocked(del).mockResolvedValue({})
})
// Queries load workspace-level app and dataset access policies from separate endpoints.
describe('Queries', () => {
it('should fetch workspace app access rules', async () => {
renderHook(() => useInfiniteWorkspaceAppAccessRules({ page: 1, limit: 20, language: 'zh' }), {
wrapper: createWrapper(),
})
await waitFor(() => {
expect(get).toHaveBeenCalledWith('/workspaces/current/rbac/workspace/apps/access-policy', {
params: { page: 1, limit: 20, language: 'zh' },
})
})
})
it('should fetch workspace dataset access rules', async () => {
renderHook(
() => useInfiniteWorkspaceDatasetAccessRules({ page: 1, limit: 20, language: 'ja' }),
{ wrapper: createWrapper() },
)
await waitFor(() => {
expect(get).toHaveBeenCalledWith(
'/workspaces/current/rbac/workspace/datasets/access-policy',
{
params: { page: 1, limit: 20, language: 'ja' },
},
)
})
})
})
// Rule mutations normalize form data to the API body expected by RBAC access policies.
describe('Rule Mutations', () => {
it('should create and update access rules', async () => {
const createHook = renderHook(() => useCreateAccessRule(), { wrapper: createWrapper() })
const updateHook = renderHook(() => useUpdateAccessRule(), { wrapper: createWrapper() })
await act(async () => {
await createHook.result.current.mutateAsync({
resourceType: 'app',
name: 'App rule',
description: 'App access',
permission_keys: ['app.acl.edit'],
})
await updateHook.result.current.mutateAsync({
id: 'policy-1',
resourceType: 'dataset',
name: 'Dataset rule',
description: 'Dataset access',
permission_keys: ['dataset.acl.edit'],
})
})
expect(post).toHaveBeenCalledWith('/workspaces/current/rbac/access-policies', {
body: {
resource_type: 'app',
name: 'App rule',
description: 'App access',
permission_keys: ['app.acl.edit'],
},
})
expect(put).toHaveBeenCalledWith('/workspaces/current/rbac/access-policies/policy-1', {
body: {
id: 'policy-1',
name: 'Dataset rule',
description: 'Dataset access',
permission_keys: ['dataset.acl.edit'],
},
})
})
it('should copy and delete access rules by id', async () => {
const copyHook = renderHook(() => useCopyAccessRule('app'), { wrapper: createWrapper() })
const deleteHook = renderHook(() => useDeleteAccessRule('dataset'), {
wrapper: createWrapper(),
})
await act(async () => {
await copyHook.result.current.mutateAsync('policy-1')
await deleteHook.result.current.mutateAsync('policy-2')
})
expect(post).toHaveBeenCalledWith(
'/workspaces/current/rbac/access-policies/policy-1/copy',
{},
)
expect(del).toHaveBeenCalledWith('/workspaces/current/rbac/access-policies/policy-2', {})
})
})
})