import type { DataSourceCredential } from './types' import { fireEvent, render, screen } from '@testing-library/react' import { CredentialTypeEnum } from '@/app/components/plugins/plugin-auth/types' import Item from './item' /** * Item Component Tests * Using Unit approach to focus on the renaming logic and view state. */ // Helper to trigger rename via the real Operator component's dropdown const triggerRename = async () => { const dropdownTrigger = screen.getByRole('button') fireEvent.click(dropdownTrigger) const renameOption = await screen.findByText('common.operation.rename') fireEvent.click(renameOption) } describe('Item Component', () => { const mockOnAction = vi.fn() const mockCredentialItem: DataSourceCredential = { id: 'test-id', name: 'Test Credential', credential: {}, type: CredentialTypeEnum.OAUTH2, is_default: false, avatar_url: '', } beforeEach(() => { vi.clearAllMocks() }) describe('Initial View Mode', () => { it('should render the credential name and "connected" status', () => { // Act render() // Assert expect(screen.getByText('Test Credential')).toBeInTheDocument() expect(screen.getByText('connected')).toBeInTheDocument() expect(screen.getByRole('button')).toBeInTheDocument() // Dropdown trigger }) }) describe('Rename Mode Interactions', () => { it('should switch to rename mode when Trigger Rename is clicked', async () => { // Arrange render() // Act await triggerRename() expect(screen.getByPlaceholderText('common.placeholder.input')).toBeInTheDocument() expect(screen.getByText('common.operation.save')).toBeInTheDocument() expect(screen.getByText('common.operation.cancel')).toBeInTheDocument() }) it('should update rename input value when changed', async () => { // Arrange render() await triggerRename() const input = screen.getByPlaceholderText('common.placeholder.input') // Act fireEvent.change(input, { target: { value: 'Updated Name' } }) // Assert expect(input).toHaveValue('Updated Name') }) it('should call onAction with "rename" and correct payload when Save is clicked', async () => { // Arrange render() await triggerRename() const input = screen.getByPlaceholderText('common.placeholder.input') fireEvent.change(input, { target: { value: 'New Name' } }) // Act fireEvent.click(screen.getByText('common.operation.save')) // Assert expect(mockOnAction).toHaveBeenCalledWith( 'rename', mockCredentialItem, { credential_id: 'test-id', name: 'New Name', }, ) // Should switch back to view mode expect(screen.queryByPlaceholderText('common.placeholder.input')).not.toBeInTheDocument() expect(screen.getByText('Test Credential')).toBeInTheDocument() }) it('should exit rename mode without calling onAction when Cancel is clicked', async () => { // Arrange render() await triggerRename() const input = screen.getByPlaceholderText('common.placeholder.input') fireEvent.change(input, { target: { value: 'Cancelled Name' } }) // Act fireEvent.click(screen.getByText('common.operation.cancel')) // Assert expect(mockOnAction).not.toHaveBeenCalled() // Should switch back to view mode expect(screen.queryByPlaceholderText('common.placeholder.input')).not.toBeInTheDocument() expect(screen.getByText('Test Credential')).toBeInTheDocument() }) }) describe('Event Bubbling', () => { it('should stop event propagation when interacting with rename mode elements', async () => { // Arrange const parentClick = vi.fn() render(
, ) // Act & Assert // We need to enter rename mode first await triggerRename() parentClick.mockClear() fireEvent.click(screen.getByPlaceholderText('common.placeholder.input')) expect(parentClick).not.toHaveBeenCalled() fireEvent.click(screen.getByText('common.operation.save')) expect(parentClick).not.toHaveBeenCalled() // Re-enter rename mode for cancel test await triggerRename() parentClick.mockClear() fireEvent.click(screen.getByText('common.operation.cancel')) expect(parentClick).not.toHaveBeenCalled() }) }) describe('Error Handling', () => { it('should not throw if onAction is missing', async () => { // Arrange & Act // @ts-expect-error - Testing runtime tolerance for missing prop render() await triggerRename() // Assert expect(() => fireEvent.click(screen.getByText('common.operation.save'))).not.toThrow() }) }) })