mirror of
https://github.com/langgenius/dify.git
synced 2026-05-03 08:58:09 +08:00
test(web): add comprehensive unit and integration tests for plugins and tools modules (#32220)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
This commit is contained in:
@ -0,0 +1,186 @@
|
||||
import { renderHook } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { AuthCategory, CredentialTypeEnum } from '../../types'
|
||||
import {
|
||||
useAddPluginCredentialHook,
|
||||
useDeletePluginCredentialHook,
|
||||
useDeletePluginOAuthCustomClientHook,
|
||||
useGetPluginCredentialInfoHook,
|
||||
useGetPluginCredentialSchemaHook,
|
||||
useGetPluginOAuthClientSchemaHook,
|
||||
useGetPluginOAuthUrlHook,
|
||||
useInvalidPluginCredentialInfoHook,
|
||||
useInvalidPluginOAuthClientSchemaHook,
|
||||
useSetPluginDefaultCredentialHook,
|
||||
useSetPluginOAuthCustomClientHook,
|
||||
useUpdatePluginCredentialHook,
|
||||
} from '../use-credential'
|
||||
|
||||
// Mock service hooks
|
||||
const mockUseGetPluginCredentialInfo = vi.fn().mockReturnValue({ data: null, isLoading: false })
|
||||
const mockUseDeletePluginCredential = vi.fn().mockReturnValue({ mutateAsync: vi.fn() })
|
||||
const mockUseInvalidPluginCredentialInfo = vi.fn().mockReturnValue(vi.fn())
|
||||
const mockUseSetPluginDefaultCredential = vi.fn().mockReturnValue({ mutateAsync: vi.fn() })
|
||||
const mockUseGetPluginCredentialSchema = vi.fn().mockReturnValue({ data: [], isLoading: false })
|
||||
const mockUseAddPluginCredential = vi.fn().mockReturnValue({ mutateAsync: vi.fn() })
|
||||
const mockUseUpdatePluginCredential = vi.fn().mockReturnValue({ mutateAsync: vi.fn() })
|
||||
const mockUseGetPluginOAuthUrl = vi.fn().mockReturnValue({ mutateAsync: vi.fn() })
|
||||
const mockUseGetPluginOAuthClientSchema = vi.fn().mockReturnValue({ data: null, isLoading: false })
|
||||
const mockUseInvalidPluginOAuthClientSchema = vi.fn().mockReturnValue(vi.fn())
|
||||
const mockUseSetPluginOAuthCustomClient = vi.fn().mockReturnValue({ mutateAsync: vi.fn() })
|
||||
const mockUseDeletePluginOAuthCustomClient = vi.fn().mockReturnValue({ mutateAsync: vi.fn() })
|
||||
const mockInvalidToolsByType = vi.fn()
|
||||
|
||||
vi.mock('@/service/use-plugins-auth', () => ({
|
||||
useGetPluginCredentialInfo: (...args: unknown[]) => mockUseGetPluginCredentialInfo(...args),
|
||||
useDeletePluginCredential: (...args: unknown[]) => mockUseDeletePluginCredential(...args),
|
||||
useInvalidPluginCredentialInfo: (...args: unknown[]) => mockUseInvalidPluginCredentialInfo(...args),
|
||||
useSetPluginDefaultCredential: (...args: unknown[]) => mockUseSetPluginDefaultCredential(...args),
|
||||
useGetPluginCredentialSchema: (...args: unknown[]) => mockUseGetPluginCredentialSchema(...args),
|
||||
useAddPluginCredential: (...args: unknown[]) => mockUseAddPluginCredential(...args),
|
||||
useUpdatePluginCredential: (...args: unknown[]) => mockUseUpdatePluginCredential(...args),
|
||||
useGetPluginOAuthUrl: (...args: unknown[]) => mockUseGetPluginOAuthUrl(...args),
|
||||
useGetPluginOAuthClientSchema: (...args: unknown[]) => mockUseGetPluginOAuthClientSchema(...args),
|
||||
useInvalidPluginOAuthClientSchema: (...args: unknown[]) => mockUseInvalidPluginOAuthClientSchema(...args),
|
||||
useSetPluginOAuthCustomClient: (...args: unknown[]) => mockUseSetPluginOAuthCustomClient(...args),
|
||||
useDeletePluginOAuthCustomClient: (...args: unknown[]) => mockUseDeletePluginOAuthCustomClient(...args),
|
||||
}))
|
||||
|
||||
vi.mock('@/service/use-tools', () => ({
|
||||
useInvalidToolsByType: () => mockInvalidToolsByType,
|
||||
}))
|
||||
|
||||
const toolPayload = {
|
||||
category: AuthCategory.tool,
|
||||
provider: 'test-provider',
|
||||
providerType: 'builtin',
|
||||
}
|
||||
|
||||
describe('use-credential hooks', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('useGetPluginCredentialInfoHook', () => {
|
||||
it('should call service with correct URL when enabled', () => {
|
||||
renderHook(() => useGetPluginCredentialInfoHook(toolPayload, true))
|
||||
expect(mockUseGetPluginCredentialInfo).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/credential/info`,
|
||||
)
|
||||
})
|
||||
|
||||
it('should pass empty string when disabled', () => {
|
||||
renderHook(() => useGetPluginCredentialInfoHook(toolPayload, false))
|
||||
expect(mockUseGetPluginCredentialInfo).toHaveBeenCalledWith('')
|
||||
})
|
||||
})
|
||||
|
||||
describe('useDeletePluginCredentialHook', () => {
|
||||
it('should call service with correct URL', () => {
|
||||
renderHook(() => useDeletePluginCredentialHook(toolPayload))
|
||||
expect(mockUseDeletePluginCredential).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/delete`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useInvalidPluginCredentialInfoHook', () => {
|
||||
it('should return a function that invalidates both credential info and tools', () => {
|
||||
const { result } = renderHook(() => useInvalidPluginCredentialInfoHook(toolPayload))
|
||||
|
||||
result.current()
|
||||
|
||||
const invalidFn = mockUseInvalidPluginCredentialInfo.mock.results[0].value
|
||||
expect(invalidFn).toHaveBeenCalled()
|
||||
expect(mockInvalidToolsByType).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('useSetPluginDefaultCredentialHook', () => {
|
||||
it('should call service with correct URL', () => {
|
||||
renderHook(() => useSetPluginDefaultCredentialHook(toolPayload))
|
||||
expect(mockUseSetPluginDefaultCredential).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/default-credential`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useGetPluginCredentialSchemaHook', () => {
|
||||
it('should call service with correct schema URL for API_KEY', () => {
|
||||
renderHook(() => useGetPluginCredentialSchemaHook(toolPayload, CredentialTypeEnum.API_KEY))
|
||||
expect(mockUseGetPluginCredentialSchema).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/credential/schema/${CredentialTypeEnum.API_KEY}`,
|
||||
)
|
||||
})
|
||||
|
||||
it('should call service with correct schema URL for OAUTH2', () => {
|
||||
renderHook(() => useGetPluginCredentialSchemaHook(toolPayload, CredentialTypeEnum.OAUTH2))
|
||||
expect(mockUseGetPluginCredentialSchema).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/credential/schema/${CredentialTypeEnum.OAUTH2}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useAddPluginCredentialHook', () => {
|
||||
it('should call service with correct URL', () => {
|
||||
renderHook(() => useAddPluginCredentialHook(toolPayload))
|
||||
expect(mockUseAddPluginCredential).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/add`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useUpdatePluginCredentialHook', () => {
|
||||
it('should call service with correct URL', () => {
|
||||
renderHook(() => useUpdatePluginCredentialHook(toolPayload))
|
||||
expect(mockUseUpdatePluginCredential).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/update`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useGetPluginOAuthUrlHook', () => {
|
||||
it('should call service with correct URL', () => {
|
||||
renderHook(() => useGetPluginOAuthUrlHook(toolPayload))
|
||||
expect(mockUseGetPluginOAuthUrl).toHaveBeenCalledWith(
|
||||
`/oauth/plugin/${toolPayload.provider}/tool/authorization-url`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useGetPluginOAuthClientSchemaHook', () => {
|
||||
it('should call service with correct URL', () => {
|
||||
renderHook(() => useGetPluginOAuthClientSchemaHook(toolPayload))
|
||||
expect(mockUseGetPluginOAuthClientSchema).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/oauth/client-schema`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useInvalidPluginOAuthClientSchemaHook', () => {
|
||||
it('should call service with correct URL', () => {
|
||||
renderHook(() => useInvalidPluginOAuthClientSchemaHook(toolPayload))
|
||||
expect(mockUseInvalidPluginOAuthClientSchema).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/oauth/client-schema`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useSetPluginOAuthCustomClientHook', () => {
|
||||
it('should call service with correct URL', () => {
|
||||
renderHook(() => useSetPluginOAuthCustomClientHook(toolPayload))
|
||||
expect(mockUseSetPluginOAuthCustomClient).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/oauth/custom-client`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useDeletePluginOAuthCustomClientHook', () => {
|
||||
it('should call service with correct URL', () => {
|
||||
renderHook(() => useDeletePluginOAuthCustomClientHook(toolPayload))
|
||||
expect(mockUseDeletePluginOAuthCustomClient).toHaveBeenCalledWith(
|
||||
`/workspaces/current/tool-provider/builtin/${toolPayload.provider}/oauth/custom-client`,
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -0,0 +1,80 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { AuthCategory, CredentialTypeEnum } from '../../types'
|
||||
import { useGetApi } from '../use-get-api'
|
||||
|
||||
describe('useGetApi', () => {
|
||||
const provider = 'test-provider'
|
||||
|
||||
describe('tool category', () => {
|
||||
it('returns correct API paths for tool category', () => {
|
||||
const api = useGetApi({ category: AuthCategory.tool, provider })
|
||||
expect(api.getCredentialInfo).toBe(`/workspaces/current/tool-provider/builtin/${provider}/credential/info`)
|
||||
expect(api.setDefaultCredential).toBe(`/workspaces/current/tool-provider/builtin/${provider}/default-credential`)
|
||||
expect(api.getCredentials).toBe(`/workspaces/current/tool-provider/builtin/${provider}/credentials`)
|
||||
expect(api.addCredential).toBe(`/workspaces/current/tool-provider/builtin/${provider}/add`)
|
||||
expect(api.updateCredential).toBe(`/workspaces/current/tool-provider/builtin/${provider}/update`)
|
||||
expect(api.deleteCredential).toBe(`/workspaces/current/tool-provider/builtin/${provider}/delete`)
|
||||
expect(api.getOauthUrl).toBe(`/oauth/plugin/${provider}/tool/authorization-url`)
|
||||
})
|
||||
|
||||
it('returns a function for getCredentialSchema', () => {
|
||||
const api = useGetApi({ category: AuthCategory.tool, provider })
|
||||
expect(typeof api.getCredentialSchema).toBe('function')
|
||||
const schemaUrl = api.getCredentialSchema('api-key' as never)
|
||||
expect(schemaUrl).toBe(`/workspaces/current/tool-provider/builtin/${provider}/credential/schema/api-key`)
|
||||
})
|
||||
|
||||
it('includes OAuth client endpoints', () => {
|
||||
const api = useGetApi({ category: AuthCategory.tool, provider })
|
||||
expect(api.getOauthClientSchema).toBe(`/workspaces/current/tool-provider/builtin/${provider}/oauth/client-schema`)
|
||||
expect(api.setCustomOauthClient).toBe(`/workspaces/current/tool-provider/builtin/${provider}/oauth/custom-client`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('datasource category', () => {
|
||||
it('returns correct API paths for datasource category', () => {
|
||||
const api = useGetApi({ category: AuthCategory.datasource, provider })
|
||||
expect(api.getCredentials).toBe(`/auth/plugin/datasource/${provider}`)
|
||||
expect(api.addCredential).toBe(`/auth/plugin/datasource/${provider}`)
|
||||
expect(api.updateCredential).toBe(`/auth/plugin/datasource/${provider}/update`)
|
||||
expect(api.deleteCredential).toBe(`/auth/plugin/datasource/${provider}/delete`)
|
||||
expect(api.setDefaultCredential).toBe(`/auth/plugin/datasource/${provider}/default`)
|
||||
expect(api.getOauthUrl).toBe(`/oauth/plugin/${provider}/datasource/get-authorization-url`)
|
||||
})
|
||||
|
||||
it('returns empty string for getCredentialInfo', () => {
|
||||
const api = useGetApi({ category: AuthCategory.datasource, provider })
|
||||
expect(api.getCredentialInfo).toBe('')
|
||||
})
|
||||
|
||||
it('returns a function for getCredentialSchema that returns empty string', () => {
|
||||
const api = useGetApi({ category: AuthCategory.datasource, provider })
|
||||
expect(api.getCredentialSchema(CredentialTypeEnum.API_KEY)).toBe('')
|
||||
})
|
||||
})
|
||||
|
||||
describe('other categories', () => {
|
||||
it('returns empty strings as fallback for unsupported category', () => {
|
||||
const api = useGetApi({ category: AuthCategory.model, provider })
|
||||
expect(api.getCredentialInfo).toBe('')
|
||||
expect(api.setDefaultCredential).toBe('')
|
||||
expect(api.getCredentials).toBe('')
|
||||
expect(api.addCredential).toBe('')
|
||||
expect(api.updateCredential).toBe('')
|
||||
expect(api.deleteCredential).toBe('')
|
||||
expect(api.getOauthUrl).toBe('')
|
||||
})
|
||||
|
||||
it('returns a function for getCredentialSchema that returns empty string', () => {
|
||||
const api = useGetApi({ category: AuthCategory.model, provider })
|
||||
expect(api.getCredentialSchema(CredentialTypeEnum.API_KEY)).toBe('')
|
||||
})
|
||||
})
|
||||
|
||||
describe('default category', () => {
|
||||
it('defaults to tool category when category is not specified', () => {
|
||||
const api = useGetApi({ provider } as { category: AuthCategory, provider: string })
|
||||
expect(api.getCredentialInfo).toContain('tool-provider')
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -0,0 +1,191 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { act, renderHook } from '@testing-library/react'
|
||||
import * as React from 'react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { usePluginAuthAction } from '../../hooks/use-plugin-auth-action'
|
||||
import { AuthCategory } from '../../types'
|
||||
|
||||
const mockDeletePluginCredential = vi.fn().mockResolvedValue({})
|
||||
const mockSetPluginDefaultCredential = vi.fn().mockResolvedValue({})
|
||||
const mockUpdatePluginCredential = vi.fn().mockResolvedValue({})
|
||||
const mockNotify = vi.fn()
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
useToastContext: () => ({
|
||||
notify: mockNotify,
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('../../hooks/use-credential', () => ({
|
||||
useDeletePluginCredentialHook: () => ({
|
||||
mutateAsync: mockDeletePluginCredential,
|
||||
}),
|
||||
useSetPluginDefaultCredentialHook: () => ({
|
||||
mutateAsync: mockSetPluginDefaultCredential,
|
||||
}),
|
||||
useUpdatePluginCredentialHook: () => ({
|
||||
mutateAsync: mockUpdatePluginCredential,
|
||||
}),
|
||||
}))
|
||||
|
||||
const pluginPayload = {
|
||||
category: AuthCategory.tool,
|
||||
provider: 'test-provider',
|
||||
}
|
||||
|
||||
function createWrapper() {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: false } },
|
||||
})
|
||||
return function Wrapper({ children }: { children: ReactNode }) {
|
||||
return React.createElement(QueryClientProvider, { client: queryClient }, children)
|
||||
}
|
||||
}
|
||||
|
||||
describe('usePluginAuthAction', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should initialize with default state', () => {
|
||||
const { result } = renderHook(() => usePluginAuthAction(pluginPayload), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
expect(result.current.doingAction).toBe(false)
|
||||
expect(result.current.deleteCredentialId).toBeNull()
|
||||
expect(result.current.editValues).toBeNull()
|
||||
})
|
||||
|
||||
it('should open and close confirm dialog', () => {
|
||||
const { result } = renderHook(() => usePluginAuthAction(pluginPayload), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
act(() => {
|
||||
result.current.openConfirm('cred-1')
|
||||
})
|
||||
expect(result.current.deleteCredentialId).toBe('cred-1')
|
||||
|
||||
act(() => {
|
||||
result.current.closeConfirm()
|
||||
})
|
||||
expect(result.current.deleteCredentialId).toBeNull()
|
||||
})
|
||||
|
||||
it('should handle edit action', () => {
|
||||
const { result } = renderHook(() => usePluginAuthAction(pluginPayload), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
const editVals = { key: 'value' }
|
||||
act(() => {
|
||||
result.current.handleEdit('cred-1', editVals)
|
||||
})
|
||||
expect(result.current.editValues).toEqual(editVals)
|
||||
})
|
||||
|
||||
it('should handle remove action by setting deleteCredentialId', () => {
|
||||
const { result } = renderHook(() => usePluginAuthAction(pluginPayload), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
act(() => {
|
||||
result.current.handleEdit('cred-1', { key: 'value' })
|
||||
})
|
||||
|
||||
act(() => {
|
||||
result.current.handleRemove()
|
||||
})
|
||||
expect(result.current.deleteCredentialId).toBe('cred-1')
|
||||
})
|
||||
|
||||
it('should handle confirm delete', async () => {
|
||||
const mockOnUpdate = vi.fn()
|
||||
const { result } = renderHook(() => usePluginAuthAction(pluginPayload, mockOnUpdate), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
act(() => {
|
||||
result.current.openConfirm('cred-1')
|
||||
})
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleConfirm()
|
||||
})
|
||||
|
||||
expect(mockDeletePluginCredential).toHaveBeenCalledWith({ credential_id: 'cred-1' })
|
||||
expect(mockNotify).toHaveBeenCalledWith(expect.objectContaining({ type: 'success' }))
|
||||
expect(mockOnUpdate).toHaveBeenCalled()
|
||||
expect(result.current.deleteCredentialId).toBeNull()
|
||||
})
|
||||
|
||||
it('should handle set default credential', async () => {
|
||||
const mockOnUpdate = vi.fn()
|
||||
const { result } = renderHook(() => usePluginAuthAction(pluginPayload, mockOnUpdate), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleSetDefault('cred-1')
|
||||
})
|
||||
|
||||
expect(mockSetPluginDefaultCredential).toHaveBeenCalledWith('cred-1')
|
||||
expect(mockNotify).toHaveBeenCalledWith(expect.objectContaining({ type: 'success' }))
|
||||
expect(mockOnUpdate).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should handle rename credential', async () => {
|
||||
const mockOnUpdate = vi.fn()
|
||||
const { result } = renderHook(() => usePluginAuthAction(pluginPayload, mockOnUpdate), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleRename({
|
||||
credential_id: 'cred-1',
|
||||
name: 'New Name',
|
||||
})
|
||||
})
|
||||
|
||||
expect(mockUpdatePluginCredential).toHaveBeenCalledWith({
|
||||
credential_id: 'cred-1',
|
||||
name: 'New Name',
|
||||
})
|
||||
expect(mockNotify).toHaveBeenCalledWith(expect.objectContaining({ type: 'success' }))
|
||||
expect(mockOnUpdate).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should prevent concurrent actions during doingAction', async () => {
|
||||
const { result } = renderHook(() => usePluginAuthAction(pluginPayload), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
act(() => {
|
||||
result.current.handleSetDoingAction(true)
|
||||
})
|
||||
expect(result.current.doingAction).toBe(true)
|
||||
|
||||
act(() => {
|
||||
result.current.openConfirm('cred-1')
|
||||
})
|
||||
await act(async () => {
|
||||
await result.current.handleConfirm()
|
||||
})
|
||||
expect(mockDeletePluginCredential).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should handle confirm without pending credential ID', async () => {
|
||||
const { result } = renderHook(() => usePluginAuthAction(pluginPayload), {
|
||||
wrapper: createWrapper(),
|
||||
})
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleConfirm()
|
||||
})
|
||||
|
||||
expect(mockDeletePluginCredential).not.toHaveBeenCalled()
|
||||
expect(result.current.deleteCredentialId).toBeNull()
|
||||
})
|
||||
})
|
||||
@ -0,0 +1,110 @@
|
||||
import { renderHook } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { AuthCategory, CredentialTypeEnum } from '../../types'
|
||||
import { usePluginAuth } from '../use-plugin-auth'
|
||||
|
||||
// Mock dependencies
|
||||
const mockCredentials = [
|
||||
{ id: '1', credential_type: CredentialTypeEnum.API_KEY, is_default: false },
|
||||
{ id: '2', credential_type: CredentialTypeEnum.OAUTH2, is_default: true },
|
||||
]
|
||||
|
||||
const mockCredentialInfo = vi.fn().mockReturnValue({
|
||||
credentials: mockCredentials,
|
||||
supported_credential_types: [CredentialTypeEnum.API_KEY, CredentialTypeEnum.OAUTH2],
|
||||
allow_custom_token: true,
|
||||
})
|
||||
|
||||
const mockInvalidate = vi.fn()
|
||||
|
||||
vi.mock('../use-credential', () => ({
|
||||
useGetPluginCredentialInfoHook: (_payload: unknown, enable?: boolean) => ({
|
||||
data: enable ? mockCredentialInfo() : undefined,
|
||||
isLoading: false,
|
||||
}),
|
||||
useInvalidPluginCredentialInfoHook: () => mockInvalidate,
|
||||
}))
|
||||
|
||||
vi.mock('@/context/app-context', () => ({
|
||||
useAppContext: () => ({
|
||||
isCurrentWorkspaceManager: true,
|
||||
}),
|
||||
}))
|
||||
|
||||
const basePayload = {
|
||||
category: AuthCategory.tool,
|
||||
provider: 'test-provider',
|
||||
}
|
||||
|
||||
describe('usePluginAuth', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should return authorized state when credentials exist', () => {
|
||||
const { result } = renderHook(() => usePluginAuth(basePayload, true))
|
||||
|
||||
expect(result.current.isAuthorized).toBe(true)
|
||||
expect(result.current.credentials).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('should detect OAuth and API Key support', () => {
|
||||
const { result } = renderHook(() => usePluginAuth(basePayload, true))
|
||||
|
||||
expect(result.current.canOAuth).toBe(true)
|
||||
expect(result.current.canApiKey).toBe(true)
|
||||
})
|
||||
|
||||
it('should return disabled=false for workspace managers', () => {
|
||||
const { result } = renderHook(() => usePluginAuth(basePayload, true))
|
||||
|
||||
expect(result.current.disabled).toBe(false)
|
||||
})
|
||||
|
||||
it('should return notAllowCustomCredential=false when allowed', () => {
|
||||
const { result } = renderHook(() => usePluginAuth(basePayload, true))
|
||||
|
||||
expect(result.current.notAllowCustomCredential).toBe(false)
|
||||
})
|
||||
|
||||
it('should return unauthorized when enable is false', () => {
|
||||
const { result } = renderHook(() => usePluginAuth(basePayload, false))
|
||||
|
||||
expect(result.current.isAuthorized).toBe(false)
|
||||
expect(result.current.credentials).toEqual([])
|
||||
})
|
||||
|
||||
it('should provide invalidate function', () => {
|
||||
const { result } = renderHook(() => usePluginAuth(basePayload, true))
|
||||
|
||||
expect(result.current.invalidPluginCredentialInfo).toBe(mockInvalidate)
|
||||
})
|
||||
|
||||
it('should handle empty credentials', () => {
|
||||
mockCredentialInfo.mockReturnValueOnce({
|
||||
credentials: [],
|
||||
supported_credential_types: [],
|
||||
allow_custom_token: false,
|
||||
})
|
||||
|
||||
const { result } = renderHook(() => usePluginAuth(basePayload, true))
|
||||
|
||||
expect(result.current.isAuthorized).toBe(false)
|
||||
expect(result.current.canOAuth).toBe(false)
|
||||
expect(result.current.canApiKey).toBe(false)
|
||||
expect(result.current.notAllowCustomCredential).toBe(true)
|
||||
})
|
||||
|
||||
it('should handle only API Key support', () => {
|
||||
mockCredentialInfo.mockReturnValueOnce({
|
||||
credentials: [{ id: '1' }],
|
||||
supported_credential_types: [CredentialTypeEnum.API_KEY],
|
||||
allow_custom_token: true,
|
||||
})
|
||||
|
||||
const { result } = renderHook(() => usePluginAuth(basePayload, true))
|
||||
|
||||
expect(result.current.canApiKey).toBe(true)
|
||||
expect(result.current.canOAuth).toBe(false)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user