@@ -30,7 +30,7 @@ resize: none; // height: 28px; border-radius: 0px; - overflow-y: hidden; + overflow-y: scroll; padding: 0px; font-size: 16px; max-height: 82px; @@ -55,8 +55,4 @@ height: 20px; width: 1px; margin: 0px 8px; -} - -// theme === 'dark' -// ? '#40404E' -// : '#EBEFF5', +} \ No newline at end of file @@ -0,0 +1,127 @@ +import '@testing-library/jest-dom' +import { act, fireEvent, screen, waitFor } from '@testing-library/react' +import { jestRender } from '#/../jest/utils/render' +import { windowMock } from '#/../jest/utils/window-mock' +import { ModelInput } from './model-input' + +jest.mock('next/router') +jest.mock('@sentry/nextjs') + +windowMock() + +const defaultProps = { + image: null, + loading: false, + desktop: true, + unpinImage: jest.fn(), + sendMessage: jest.fn().mockReturnValue(true), + imageLoad: jest.fn(), + styles: 'chats' as const, + input_types: [{ type: 'text', required: true, versions: ['v1'] }], + viewMobileSettings: jest.fn(), + currentVersion: 'v1', + blocked: false, +} + +describe('renders textarea with correct placeholder', () => { + it('successfully show modal', async () => { + jestRender() + const textarea = screen.getByPlaceholderText('Ваше сообщение') + expect(textarea).toBeInTheDocument() + }) + + it('updates textarea value on user input', () => { + jestRender() + const textarea = screen.getByPlaceholderText('Ваше сообщение') as HTMLTextAreaElement + + fireEvent.change(textarea, { target: { value: 'Test input' } }) + expect(textarea.value).toBe('Test input') + }) + + it('adjusts height on input', () => { + jestRender() + const textarea = screen.getByPlaceholderText('Ваше сообщение') as HTMLTextAreaElement + + Object.defineProperty(textarea, 'scrollHeight', { configurable: true, value: 80 }) + + fireEvent.input(textarea) + expect(textarea.style.height).toBe('80px') + }) + + it('textarea is disabled when disabled is true', () => { + const props = { ...defaultProps, blocked: true } + jestRender() + const textarea = screen.getByPlaceholderText('Ввод текста недоступен для этой модели') as HTMLTextAreaElement + expect(textarea).toBeDisabled() + }) + + it('calls sendMessage on Enter and clears textarea on success', () => { + const sendMessageMock = jest.fn().mockReturnValue(true) + const props = { ...defaultProps, sendMessage: sendMessageMock } + jestRender() + + const textarea = screen.getByPlaceholderText('Ваше сообщение') as HTMLTextAreaElement + + fireEvent.change(textarea, { target: { value: 'Test message' } }) + fireEvent.keyDown(textarea, { key: 'Enter', shiftKey: false }) + + expect(sendMessageMock).toHaveBeenCalledWith('Test message', ['text']) + expect(textarea.value).toBe('') + }) + + it('does not call sendMessage on Shift+Enter', () => { + const sendMessageMock = jest.fn() + const props = { ...defaultProps, sendMessage: sendMessageMock } + jestRender() + + const textarea = screen.getByPlaceholderText('Ваше сообщение') as HTMLTextAreaElement + + fireEvent.change(textarea, { target: { value: 'Should not send' } }) + fireEvent.keyDown(textarea, { key: 'Enter', shiftKey: true }) + + expect(sendMessageMock).not.toHaveBeenCalled() + }) + + it('sets initial value from resendValue', () => { + const props = { ...defaultProps, resendValue: 'Previous message' } + jestRender() + + const textarea = screen.getByDisplayValue('Previous message') as HTMLTextAreaElement + expect(textarea).toBeInTheDocument() + }) + + it('disables textarea if input_types does not include supported text type', async () => { + const props = { + ...defaultProps, + input_types: [{ type: 'image', required: true, versions: ['v1'] }], // no 'text' type + } + + jestRender() + await waitFor(() => { + const textarea = screen.getByPlaceholderText('Ввод текста недоступен для этой модели') as HTMLTextAreaElement + expect(textarea).toBeDisabled() + }) + }) + + it('enables textarea if text input type is supported for currentVersion', async () => { + const props = { + ...defaultProps, + input_types: [{ type: 'text', required: true, versions: ['v1'] }], + currentVersion: 'v1', + } + + jestRender() + await waitFor(() => { + const textarea = screen.getByPlaceholderText('Ваше сообщение') as HTMLTextAreaElement + expect(textarea).not.toBeDisabled() + }) + }) + + it('updates value on change and does not break', () => { + jestRender() + const textarea = screen.getByPlaceholderText('Ваше сообщение') as HTMLTextAreaElement + + fireEvent.change(textarea, { target: { value: 'Side effect test' } }) + expect(textarea.value).toBe('Side effect test') + }) +})