// Licensed to Cloudera, Inc. under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. Cloudera, Inc. licenses this file // to you 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. import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import '@testing-library/jest-dom'; import FormInput, { FieldType, BaseFieldConfig } from './FormInput'; describe('FormInput Component', () => { const mockOnChange = jest.fn(); const defaultProps = { loading: false, onChange: mockOnChange }; beforeEach(() => { mockOnChange.mockClear(); }); describe('INPUT field type', () => { const inputField: BaseFieldConfig = { name: 'testInput', type: FieldType.INPUT, label: 'Test Input', placeholder: 'Enter text', className: 'test-class' }; it('should render input field with correct props', () => { render(); const input = screen.getByDisplayValue('test value'); expect(input).toBeInTheDocument(); expect(input).toHaveAttribute('placeholder', 'Enter text'); expect(input).toHaveClass('test-class'); }); it('should call onChange when input value changes', () => { render(); const input = screen.getByPlaceholderText('Enter text'); fireEvent.change(input, { target: { value: 'new value' } }); expect(mockOnChange).toHaveBeenCalledWith('testInput', 'new value'); }); it('should render label for input field', () => { render(); expect(screen.getByText('Test Input')).toBeInTheDocument(); }); it('should render tooltip icon when tooltip is provided', () => { const inputWithTooltip: BaseFieldConfig = { name: 'testInputTooltip', type: FieldType.INPUT, label: 'Input with Tooltip', tooltip: 'This is an input tooltip' }; render(); expect(screen.getByRole('img', { name: /info-circle/i })).toBeInTheDocument(); }); it('should handle visibility conditions - render when not hidden', () => { const visibilityField: BaseFieldConfig = { name: 'conditionalField', type: FieldType.INPUT, label: 'Conditional Field', hidden: false }; render(); expect(screen.queryByDisplayValue('')).toBeInTheDocument(); expect(screen.queryByRole('textbox', { name: /conditional field/i })).toBeInTheDocument(); }); it('should handle visibility conditions - not render when hidden', () => { const visibilityField: BaseFieldConfig = { name: 'conditionalField', type: FieldType.INPUT, label: 'Conditional Field', hidden: true }; render(); expect(screen.queryByRole('textbox', { name: /conditional field/i })).not.toBeInTheDocument(); }); }); describe('SELECT field type', () => { const selectField: BaseFieldConfig = { name: 'testSelect', type: FieldType.SELECT, label: 'Test Select', placeholder: 'Choose option', options: [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2' } ] }; it('should render select field with options', () => { render(); const select = screen.getByRole('combobox'); expect(select).toBeInTheDocument(); expect(screen.getByText('Option 1')).toBeInTheDocument(); }); it('should call onChange when select value changes', async () => { const user = userEvent.setup(); const onChangeSpy = jest.fn(); render( ); const select = screen.getByRole('combobox'); expect(select).toBeInTheDocument(); expect(screen.getByText('Option 1')).toBeInTheDocument(); await user.click(select); const option2 = screen.getByText('Option 2'); await user.click(option2); expect(onChangeSpy).toHaveBeenCalledWith('testSelect', 'option2'); }); it('should render tooltip icon when tooltip is provided', () => { const selectWithTooltip: BaseFieldConfig = { name: 'testSelectTooltip', type: FieldType.SELECT, label: 'Select with Tooltip', tooltip: 'This is a select tooltip', options: [{ value: 'option1', label: 'Option 1' }] }; render(); expect(screen.getByRole('img', { name: /info-circle/i })).toBeInTheDocument(); }); }); describe('CHECKBOX field type', () => { const checkboxField: BaseFieldConfig = { name: 'testCheckbox', type: FieldType.CHECKBOX, label: 'Test Checkbox', tooltip: 'This is a tooltip' }; it('should render checkbox field', () => { render(); const checkbox = screen.getByRole('checkbox'); expect(checkbox).toBeInTheDocument(); expect(checkbox).toBeChecked(); expect(screen.getByText('Test Checkbox')).toBeInTheDocument(); }); it('should call onChange when checkbox is toggled', () => { render(); const checkbox = screen.getByRole('checkbox'); fireEvent.click(checkbox); expect(mockOnChange).toHaveBeenCalledWith('testCheckbox', true); }); it('should render when default value is true', () => { render(); const checkbox = screen.getByRole('checkbox'); expect(checkbox).toBeInTheDocument(); expect(checkbox).toBeChecked(); }); it('should render when default value is false', () => { render(); const checkbox = screen.getByRole('checkbox'); expect(checkbox).toBeInTheDocument(); expect(checkbox).not.toBeChecked(); }); it('should render tooltip icon when tooltip is provided', () => { render(); expect(screen.getByRole('img', { name: /info-circle/i })).toBeInTheDocument(); }); }); describe('RADIO field type', () => { const radioField: BaseFieldConfig = { name: 'testRadio', type: FieldType.RADIO, label: 'Test Radio', options: [ { value: 'radio1', label: 'Radio 1' }, { value: 'radio2', label: 'Radio 2' } ] }; it('should render radio group with options', () => { render(); expect(screen.getByText('Radio 1')).toBeInTheDocument(); expect(screen.getByText('Radio 2')).toBeInTheDocument(); const radio1 = screen.getByDisplayValue('radio1'); const radio2 = screen.getByDisplayValue('radio2'); expect(radio1).toBeChecked(); expect(radio2).not.toBeChecked(); }); it('should call onChange when radio option changes', () => { render(); const radio2 = screen.getByDisplayValue('radio2'); fireEvent.click(radio2); expect(mockOnChange).toHaveBeenCalledWith('testRadio', 'radio2'); }); it('should render with default value', () => { render( ); const radio2 = screen.getByDisplayValue('radio2'); expect(radio2).toBeChecked(); }); it('should render tooltip icon when tooltip is provided', () => { const radioWithTooltip: BaseFieldConfig = { name: 'testRadioTooltip', type: FieldType.RADIO, label: 'Radio with Tooltip', tooltip: 'This is a radio tooltip', options: [{ value: 'radio1', label: 'Radio 1' }] }; render(); expect(screen.getByRole('img', { name: /info-circle/i })).toBeInTheDocument(); }); }); });