import type { UseQueryResult } from '@tanstack/react-query' import type { ModalContextState } from '@/context/modal-context' import type { ApiBasedExtension } from '@/models/common' import { fireEvent, render, screen } from '@testing-library/react' import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants' import { useModalContext } from '@/context/modal-context' import { useApiBasedExtensions } from '@/service/use-common' import ApiBasedExtensionSelector from './selector' vi.mock('@/context/modal-context', () => ({ useModalContext: vi.fn(), })) vi.mock('@/service/use-common', () => ({ useApiBasedExtensions: vi.fn(), })) describe('ApiBasedExtensionSelector', () => { const mockOnChange = vi.fn() const mockSetShowAccountSettingModal = vi.fn() const mockSetShowApiBasedExtensionModal = vi.fn() const mockRefetch = vi.fn() const mockData: ApiBasedExtension[] = [ { id: '1', name: 'Extension 1', api_endpoint: 'https://api1.test' }, { id: '2', name: 'Extension 2', api_endpoint: 'https://api2.test' }, ] beforeEach(() => { vi.clearAllMocks() vi.mocked(useModalContext).mockReturnValue({ setShowAccountSettingModal: mockSetShowAccountSettingModal, setShowApiBasedExtensionModal: mockSetShowApiBasedExtensionModal, } as unknown as ModalContextState) vi.mocked(useApiBasedExtensions).mockReturnValue({ data: mockData, refetch: mockRefetch, isPending: false, isError: false, } as unknown as UseQueryResult) }) describe('Rendering', () => { it('should render placeholder when no value is selected', () => { // Act render() // Assert expect(screen.getByText('common.apiBasedExtension.selector.placeholder')).toBeInTheDocument() }) it('should render selected item name', async () => { // Act render() // Assert expect(screen.getByText('Extension 1')).toBeInTheDocument() }) }) describe('Dropdown Interactions', () => { it('should open dropdown when clicked', async () => { // Act render() const trigger = screen.getByText('common.apiBasedExtension.selector.placeholder') fireEvent.click(trigger) // Assert expect(await screen.findByText('common.apiBasedExtension.selector.title')).toBeInTheDocument() }) it('should call onChange and closes dropdown when an extension is selected', async () => { // Act render() fireEvent.click(screen.getByText('common.apiBasedExtension.selector.placeholder')) const option = await screen.findByText('Extension 2') fireEvent.click(option) // Assert expect(mockOnChange).toHaveBeenCalledWith('2') }) }) describe('Manage and Add Extensions', () => { it('should open account settings when clicking manage', async () => { // Act render() fireEvent.click(screen.getByText('common.apiBasedExtension.selector.placeholder')) const manageButton = await screen.findByText('common.apiBasedExtension.selector.manage') fireEvent.click(manageButton) // Assert expect(mockSetShowAccountSettingModal).toHaveBeenCalledWith({ payload: ACCOUNT_SETTING_TAB.API_BASED_EXTENSION, }) }) it('should open add modal when clicking add button and refetches on save', async () => { // Act render() fireEvent.click(screen.getByText('common.apiBasedExtension.selector.placeholder')) const addButton = await screen.findByText('common.operation.add') fireEvent.click(addButton) // Assert expect(mockSetShowApiBasedExtensionModal).toHaveBeenCalledWith(expect.objectContaining({ payload: {}, })) // Trigger callback const lastCall = mockSetShowApiBasedExtensionModal.mock.calls[0][0] if (typeof lastCall === 'object' && lastCall !== null && 'onSaveCallback' in lastCall) { if (lastCall.onSaveCallback) { lastCall.onSaveCallback() expect(mockRefetch).toHaveBeenCalled() } } }) }) })