import type { PluginDetail } from '@/app/components/plugins/types' import { fireEvent, render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import EndpointList from './endpoint-list' vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key, }), })) vi.mock('@/context/i18n', () => ({ useDocLink: () => (path: string) => `https://docs.example.com${path}`, })) vi.mock('@/utils/classnames', () => ({ cn: (...args: (string | undefined | false | null)[]) => args.filter(Boolean).join(' '), })) const mockEndpoints = [ { id: 'ep-1', name: 'Endpoint 1', url: 'https://api.example.com', declaration: { settings: [], endpoints: [] } }, ] let mockEndpointListData: { endpoints: typeof mockEndpoints } | undefined const mockInvalidateEndpointList = vi.fn() const mockCreateEndpoint = vi.fn() vi.mock('@/service/use-endpoints', () => ({ useEndpointList: () => ({ data: mockEndpointListData }), useInvalidateEndpointList: () => mockInvalidateEndpointList, useCreateEndpoint: ({ onSuccess }: { onSuccess: () => void }) => ({ mutate: (data: unknown) => { mockCreateEndpoint(data) onSuccess() }, }), })) vi.mock('@/app/components/tools/utils/to-form-schema', () => ({ toolCredentialToFormSchemas: (schemas: unknown[]) => schemas, })) vi.mock('./endpoint-card', () => ({ default: ({ data }: { data: { name: string } }) => (
{data.name}
), })) vi.mock('./endpoint-modal', () => ({ default: ({ onCancel, onSaved }: { onCancel: () => void, onSaved: (state: unknown) => void }) => (
), })) const createPluginDetail = (): PluginDetail => ({ id: 'test-id', created_at: '2024-01-01', updated_at: '2024-01-02', name: 'Test Plugin', plugin_id: 'test-plugin', plugin_unique_identifier: 'test-uid', declaration: { endpoint: { settings: [], endpoints: [] }, tool: undefined, } as unknown as PluginDetail['declaration'], installation_id: 'install-1', tenant_id: 'tenant-1', endpoints_setups: 0, endpoints_active: 0, version: '1.0.0', latest_version: '1.0.0', latest_unique_identifier: 'test-uid', source: 'marketplace' as PluginDetail['source'], meta: undefined, status: 'active', deprecated_reason: '', alternative_plugin_id: '', }) describe('EndpointList', () => { beforeEach(() => { vi.clearAllMocks() mockEndpointListData = { endpoints: mockEndpoints } }) describe('Rendering', () => { it('should render endpoint list', () => { render() expect(screen.getByText('detailPanel.endpoints')).toBeInTheDocument() }) it('should render endpoint cards', () => { render() expect(screen.getByTestId('endpoint-card')).toBeInTheDocument() expect(screen.getByText('Endpoint 1')).toBeInTheDocument() }) it('should return null when no data', () => { mockEndpointListData = undefined const { container } = render() expect(container).toBeEmptyDOMElement() }) it('should show empty message when no endpoints', () => { mockEndpointListData = { endpoints: [] } render() expect(screen.getByText('detailPanel.endpointsEmpty')).toBeInTheDocument() }) it('should render add button', () => { render() const addButton = screen.getAllByRole('button').find(btn => btn.classList.contains('action-btn')) expect(addButton).toBeDefined() }) }) describe('User Interactions', () => { it('should show modal when add button clicked', () => { render() const addButton = screen.getAllByRole('button').find(btn => btn.classList.contains('action-btn')) if (addButton) fireEvent.click(addButton) expect(screen.getByTestId('endpoint-modal')).toBeInTheDocument() }) it('should hide modal when cancel clicked', () => { render() const addButton = screen.getAllByRole('button').find(btn => btn.classList.contains('action-btn')) if (addButton) fireEvent.click(addButton) expect(screen.getByTestId('endpoint-modal')).toBeInTheDocument() fireEvent.click(screen.getByTestId('modal-cancel')) expect(screen.queryByTestId('endpoint-modal')).not.toBeInTheDocument() }) it('should call createEndpoint when save clicked', () => { render() const addButton = screen.getAllByRole('button').find(btn => btn.classList.contains('action-btn')) if (addButton) fireEvent.click(addButton) fireEvent.click(screen.getByTestId('modal-save')) expect(mockCreateEndpoint).toHaveBeenCalled() }) }) describe('Border Style', () => { it('should render with border style based on tool existence', () => { const detail = createPluginDetail() detail.declaration.tool = {} as PluginDetail['declaration']['tool'] render() // Verify the component renders correctly expect(screen.getByText('detailPanel.endpoints')).toBeInTheDocument() }) }) describe('Multiple Endpoints', () => { it('should render multiple endpoint cards', () => { mockEndpointListData = { endpoints: [ { id: 'ep-1', name: 'Endpoint 1', url: 'https://api1.example.com', declaration: { settings: [], endpoints: [] } }, { id: 'ep-2', name: 'Endpoint 2', url: 'https://api2.example.com', declaration: { settings: [], endpoints: [] } }, ], } render() expect(screen.getAllByTestId('endpoint-card')).toHaveLength(2) }) }) describe('Tooltip', () => { it('should render with tooltip content', () => { render() // Tooltip is rendered - the add button should be visible const addButton = screen.getAllByRole('button').find(btn => btn.classList.contains('action-btn')) expect(addButton).toBeDefined() }) }) describe('Create Endpoint Flow', () => { it('should invalidate endpoint list after successful create', () => { render() const addButton = screen.getAllByRole('button').find(btn => btn.classList.contains('action-btn')) if (addButton) fireEvent.click(addButton) fireEvent.click(screen.getByTestId('modal-save')) expect(mockInvalidateEndpointList).toHaveBeenCalledWith('test-plugin') }) it('should pass correct params to createEndpoint', () => { render() const addButton = screen.getAllByRole('button').find(btn => btn.classList.contains('action-btn')) if (addButton) fireEvent.click(addButton) fireEvent.click(screen.getByTestId('modal-save')) expect(mockCreateEndpoint).toHaveBeenCalledWith({ pluginUniqueID: 'test-uid', state: { name: 'New Endpoint' }, }) }) }) })