import type { IChatItem } from '@/app/components/base/chat/chat/type' import { fireEvent, render, screen } from '@testing-library/react' import { useStore } from '@/app/components/app/store' import MessageLogModal from '../index' let clickAwayHandler: (() => void) | null = null vi.mock('ahooks', () => ({ useClickAway: (fn: () => void) => { clickAwayHandler = fn }, })) vi.mock('@/app/components/app/store', () => ({ useStore: vi.fn(), })) vi.mock('@/app/components/workflow/run', () => ({ default: ({ activeTab, runDetailUrl, tracingListUrl, }: { activeTab: string runDetailUrl: string tracingListUrl: string }) => (
), })) const mockLog = { id: 'msg-1', content: 'mock log message', workflow_run_id: 'run-1', isAnswer: true, } describe('MessageLogModal', () => { const onCancel = vi.fn() beforeEach(() => { vi.clearAllMocks() clickAwayHandler = null // oxlint-disable-next-line typescript/no-explicit-any vi.mocked(useStore).mockImplementation((selector: any) => selector({ appDetail: { id: 'app-1' }, }), ) }) describe('Render', () => { it('renders nothing if currentLogItem is missing', () => { const { container } = render() expect(container.firstChild).toBeNull() }) it('renders nothing if currentLogItem.workflow_run_id is missing', () => { const { container } = render( , ) expect(container.firstChild).toBeNull() }) it('renders modal with correct title and Run component', () => { render() expect(screen.getByText(/title/i))!.toBeInTheDocument() expect(screen.getByTestId('workflow-run'))!.toBeInTheDocument() }) }) describe('Props', () => { it('passes correct props to Run component', () => { render( , ) const runComponent = screen.getByTestId('workflow-run') expect(runComponent.getAttribute('data-active-tab')).toBe('TRACING') expect(runComponent.getAttribute('data-run-detail-url')).toBe( '/apps/app-1/workflow-runs/run-1', ) expect(runComponent.getAttribute('data-tracing-list-url')).toBe( '/apps/app-1/workflow-runs/run-1/node-executions', ) }) it('sets fixed style when fixedWidth is false (floating)', () => { const { container } = render( , ) const modal = screen.getByRole('dialog') expect(container).not.toContainElement(modal) expect(document.body).toContainElement(modal) }) it('sets fixed width when fixedWidth is true', () => { const { container } = render( , ) const panel = container.firstElementChild as HTMLElement expect(panel).toHaveClass('relative', 'z-10') expect(panel.style.width).toBe('1000px') }) }) describe('Interaction', () => { it('calls onCancel when close icon is clicked', () => { render() const closeButton = screen.getByRole('button', { name: 'common.operation.close' }) expect(closeButton)!.toBeInTheDocument() fireEvent.click(closeButton) expect(onCancel).toHaveBeenCalledTimes(1) }) it('calls onCancel when clicked away', () => { render( , ) expect(clickAwayHandler).toBeTruthy() clickAwayHandler!() expect(onCancel).toHaveBeenCalledTimes(1) }) it('does not use click away to close the floating dialog', () => { render() expect(clickAwayHandler).toBeTruthy() clickAwayHandler!() expect(onCancel).not.toHaveBeenCalled() }) }) })