// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. ========= import { Inputbox } from '@/components/ChatBox/BottomBox/InputBox'; import { fireEvent, render } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; vi.mock('@/components/ChatBox/BottomBox/RichChatInput', async () => { const { forwardRef } = await import('react'); return { RichChatInput: forwardRef< HTMLDivElement, { value?: string; onKeyDown?: React.KeyboardEventHandler; } >(({ value, onKeyDown }, ref) => (
{value}
)), }; }); function primaryAction(container: HTMLElement) { return container.querySelector( '[data-composer-primary-action]' )!; } describe('Inputbox primary action', () => { it('rotates the default arrow upward when text becomes sendable', () => { const onSend = vi.fn(); const { container, rerender } = render( ); expect(primaryAction(container)).toHaveAttribute( 'data-composer-primary-action', 'idle' ); expect(primaryAction(container)).toBeDisabled(); expect( container.querySelector('[data-composer-primary-icon="arrow"]') ).toHaveClass('rotate-0', 'motion-reduce:transition-none'); rerender(); expect(primaryAction(container)).toHaveAttribute( 'data-composer-primary-action', 'send' ); expect(primaryAction(container)).not.toBeDisabled(); expect( container.querySelector('[data-composer-primary-icon="arrow"]') ).toHaveClass('-rotate-90'); fireEvent.click(primaryAction(container)); expect(onSend).toHaveBeenCalledOnce(); }); it('uses pause and resume while an empty composer controls a live task', () => { const onPauseTask = vi.fn(); const onResumeTask = vi.fn(); const { container, rerender } = render( ); expect(primaryAction(container)).toHaveAttribute( 'data-composer-primary-action', 'pause' ); fireEvent.click(primaryAction(container)); expect(onPauseTask).toHaveBeenCalledOnce(); rerender( ); expect(primaryAction(container)).toHaveAttribute( 'data-composer-primary-action', 'resume' ); fireEvent.click(primaryAction(container)); expect(onResumeTask).toHaveBeenCalledOnce(); }); it('prioritizes sending text or files over pause and resume', () => { const onSend = vi.fn(); const onPauseTask = vi.fn(); const { container, rerender } = render( ); expect(primaryAction(container)).toHaveAttribute( 'data-composer-primary-action', 'send' ); fireEvent.click(primaryAction(container)); expect(onSend).toHaveBeenCalledOnce(); expect(onPauseTask).not.toHaveBeenCalled(); rerender( ); expect(primaryAction(container)).toHaveAttribute( 'data-composer-primary-action', 'send' ); fireEvent.click(primaryAction(container)); expect(onSend).toHaveBeenCalledTimes(2); expect(onPauseTask).not.toHaveBeenCalled(); }); it('sends a running-task follow-up with Return but not Shift+Return', () => { const onSend = vi.fn(); const { getByTestId } = render( ); fireEvent.keyDown(getByTestId('rich-chat-input'), { key: 'Enter', shiftKey: true, }); expect(onSend).not.toHaveBeenCalled(); fireEvent.keyDown(getByTestId('rich-chat-input'), { key: 'Enter' }); expect(onSend).toHaveBeenCalledOnce(); }); });