diff --git a/packages/forms/src/components/TextInput.test.tsx b/packages/forms/src/components/TextInput.test.tsx index 19230ddd..740a11a4 100644 --- a/packages/forms/src/components/TextInput.test.tsx +++ b/packages/forms/src/components/TextInput.test.tsx @@ -1,27 +1,26 @@ +import { AMAProvider } from '@react-native-ama/core'; import * as UseChecks from '@react-native-ama/core/src/hooks/useChecks'; -import { fireEvent, render } from '@testing-library/react-native'; +import { act, fireEvent, render } from '@testing-library/react-native'; import * as React from 'react'; import { Text } from 'react-native'; import { ERROR_STYLE } from '~internal'; import * as UseFormField from '../hooks/useFormField'; -import { TextInput } from './TextInput'; +import { TextInput, TextInputProps } from './TextInput'; beforeEach(() => { jest.clearAllMocks(); }); describe('TextInput', () => { - it('register itself as form field by using the useFormField hook', () => { + it('register itself as form field by using the useFormField hook', async () => { const useFormField = jest.spyOn(UseFormField, 'useFormField'); - render( - Test} - hasValidation={false} - returnKeyType="done" - />, - ); + await renderTextInput({ + labelComponent: Test, + hasValidation: false, + returnKeyType: 'done', + }); expect(useFormField.mock.calls[0][0]).toMatchObject({ ref: expect.objectContaining({ current: expect.any(Object) }), @@ -34,160 +33,164 @@ describe('TextInput', () => { }); }); - it('renders the given labelComponent before the text input when labelPosition is undefined', () => { - const renderAPI = render( - labelComponent} - returnKeyType="done" - hasValidation={false} - />, - ); + it('renders the given labelComponent before the text input when labelPosition is undefined', async () => { + const renderAPI = await renderTextInput({ + labelComponent: labelComponent, + returnKeyType: 'done', + hasValidation: false, + }); expect(renderAPI.toJSON()).toMatchInlineSnapshot(` - Array [ + labelComponent - , + , - ] + style={{}} + /> + `); }); - it('renders the given labelComponent after the text input when labelPosition is "afterInput"', () => { - const renderAPI = render( - labelComponent after} - labelPosition="afterInput" - returnKeyType="done" - hasValidation={false} - />, - ); + it('renders the given labelComponent after the text input when labelPosition is "afterInput"', async () => { + const renderAPI = await renderTextInput({ + labelComponent: labelComponent after, + labelPosition: 'afterInput', + returnKeyType: 'done', + hasValidation: false, + }); expect(renderAPI.toJSON()).toMatchInlineSnapshot(` - Array [ + , + style={{}} + /> labelComponent after - , - ] + + `); }); - it('renders the given errorComponent after the labelComponent when errorPosition is "belowLabel"', () => { - const renderAPI = render( - the labelComponent} - returnKeyType="done" - hasValidation={true} - errorComponent={This is the errorComponent} - errorPosition="belowLabel" - hasError={true} - />, - ); + it('renders the given errorComponent after the labelComponent when errorPosition is "belowLabel"', async () => { + const renderAPI = await renderTextInput({ + labelComponent: the labelComponent, + returnKeyType: 'done', + hasValidation: true, + errorComponent: This is the errorComponent, + errorPosition: 'belowLabel', + hasError: true, + }); expect(renderAPI.toJSON()).toMatchInlineSnapshot(` - Array [ + the labelComponent - , - + + This is the errorComponent - , + , - ] + style={{}} + /> + `); }); - it('renders the given errorComponent after the input when errorPosition is "afterInput"', () => { - const renderAPI = render( - the labelComponent} - returnKeyType="done" - hasValidation={true} - errorComponent={This is the errorComponent} - errorPosition="afterInput" - hasError={true} - />, - ); + it('renders the given errorComponent after the input when errorPosition is "afterInput"', async () => { + const renderAPI = await renderTextInput({ + labelComponent: the labelComponent, + returnKeyType: 'done', + hasValidation: true, + errorComponent: This is the errorComponent, + errorPosition: 'afterInput', + hasError: true, + }); expect(renderAPI.toJSON()).toMatchInlineSnapshot(` - Array [ + the labelComponent - , + , - + style={{}} + /> + This is the errorComponent - , - ] + + `); }); - it('hides the labelComponent from the screen readers', () => { - const renderAPI = render( - Test} - labelPosition="afterInput" - returnKeyType="done" - hasValidation={false} - />, - ); + it('hides the labelComponent from the screen readers', async () => { + const renderAPI = await renderTextInput({ + labelComponent: Test, + labelPosition: 'afterInput', + returnKeyType: 'done', + hasValidation: false, + }); expect(renderAPI.getByTestId('text').props.importantForAccessibility).toBe( 'no', @@ -197,22 +200,18 @@ describe('TextInput', () => { ).toBe(true); }); - it('hides the errorComponent component from the screen readers', () => { - const renderAPI = render( - Test} - labelPosition="afterInput" - returnKeyType="done" - hasValidation={true} - errorComponent={ - - This is the errorComponent - - } - errorPosition="afterInput" - hasError={true} - />, - ); + it('hides the errorComponent component from the screen readers', async () => { + const renderAPI = await renderTextInput({ + labelComponent: Test, + labelPosition: 'afterInput', + returnKeyType: 'done', + hasValidation: true, + errorComponent: ( + This is the errorComponent + ), + errorPosition: 'afterInput', + hasError: true, + }); expect( renderAPI.getByTestId('errorComponent-test-id').props @@ -232,14 +231,12 @@ describe('TextInput', () => { isLastField, } as any); - const renderAPI = render( - labelComponent} - labelPosition="afterInput" - testID="test-id" - hasValidation={false} - />, - ); + const renderAPI = await renderTextInput({ + labelComponent: labelComponent, + labelPosition: 'afterInput', + testID: 'test-id', + hasValidation: false, + }); await fireEvent(renderAPI.getByTestId('test-id'), 'onLayout'); @@ -248,21 +245,19 @@ describe('TextInput', () => { ); }); - it('sets the `returnKeyType="done"` if is last field registered', () => { + it('sets the `returnKeyType="done"` if is last field registered', async () => { const isLastField = jest.fn().mockReturnValue(true); jest.spyOn(UseFormField, 'useFormField').mockReturnValue({ isLastField, } as any); - const renderAPI = render( - labelComponent} - labelPosition="afterInput" - testID="test-id" - hasValidation={false} - />, - ); + const renderAPI = await renderTextInput({ + labelComponent: labelComponent, + labelPosition: 'afterInput', + testID: 'test-id', + hasValidation: false, + }); fireEvent(renderAPI.getByTestId('test-id'), 'onLayout'); @@ -280,15 +275,13 @@ describe('TextInput', () => { isLastField, } as any); - const renderAPI = render( - labelComponent} - labelPosition="afterInput" - testID="test-id" - returnKeyType="google" - hasValidation={false} - />, - ); + const renderAPI = await renderTextInput({ + labelComponent: labelComponent, + labelPosition: 'afterInput', + testID: 'test-id', + returnKeyType: 'google', + hasValidation: false, + }); await fireEvent(renderAPI.getByTestId('test-id'), 'onLayout'); @@ -301,30 +294,26 @@ describe('TextInput', () => { describe('accessibilityLabel', () => { describe('Given no accessibility labelComponent is provided', () => { - it('Then applies the given labelComponent content as accessibilityLabel', () => { - const renderAPI = render( - First name:} - returnKeyType="done" - testID="text-input" - hasValidation={false} - />, - ); + it('Then applies the given labelComponent content as accessibilityLabel', async () => { + const renderAPI = await renderTextInput({ + labelComponent: First name:, + returnKeyType: 'done', + testID: 'text-input', + hasValidation: false, + }); expect( renderAPI.getByTestId('text-input').props.accessibilityLabel, ).toBe('First name:'); }); - it('strips the ending * from the labelComponent content before using as accessibility labelComponent', () => { - const renderAPI = render( - First name (required)*} - returnKeyType="done" - testID="text-input" - hasValidation={false} - />, - ); + it('strips the ending * from the labelComponent content before using as accessibility labelComponent', async () => { + const renderAPI = await renderTextInput({ + labelComponent: First name (required)*, + returnKeyType: 'done', + testID: 'text-input', + hasValidation: false, + }); expect( renderAPI.getByTestId('text-input').props.accessibilityLabel, @@ -332,16 +321,14 @@ describe('TextInput', () => { }); }); - it('uses the accessibilityLabel only if provided', () => { - const renderAPI = render( - First name (required)*} - returnKeyType="done" - testID="text-input" - accessibilityLabel="Please insert your first name" - hasValidation={false} - />, - ); + it('uses the accessibilityLabel only if provided', async () => { + const renderAPI = await renderTextInput({ + labelComponent: First name (required)*, + returnKeyType: 'done', + testID: 'text-input', + accessibilityLabel: 'Please insert your first name', + hasValidation: false, + }); expect(renderAPI.getByTestId('text-input').props.accessibilityLabel).toBe( 'Please insert your first name', @@ -349,7 +336,7 @@ describe('TextInput', () => { }); }); - it('calls focusNextFormField onSubmitEditing event', () => { + it('calls focusNextFormField onSubmitEditing event', async () => { const focusNextFormField = jest.fn(); jest.spyOn(UseFormField, 'useFormField').mockReturnValue({ @@ -358,16 +345,14 @@ describe('TextInput', () => { const fn = jest.fn(); - const renderAPI = render( - First name (required)*} - returnKeyType="next" - testID="text-input" - accessibilityLabel="Please insert your first name" - onSubmitEditing={fn} - hasValidation={false} - />, - ); + const renderAPI = await renderTextInput({ + labelComponent: First name (required)*, + returnKeyType: 'next', + testID: 'text-input', + accessibilityLabel: 'Please insert your first name', + onSubmitEditing: fn, + hasValidation: false, + }); fireEvent( renderAPI.getByTestId('text-input'), @@ -378,65 +363,58 @@ describe('TextInput', () => { expect(fn).toHaveBeenCalledWith('whatever'); }); - it('ignores the errorComponent message if hasError is not true', () => { - const renderAPI = render( - First name (required)*} - returnKeyType="next" - testID="text-input" - accessibilityLabel="Please insert your first name" - hasValidation={true} - hasError={false} - errorMessage={'This is the errorComponent'} - errorComponent={<>} - />, - ); + it('ignores the errorComponent message if hasError is not true', async () => { + const renderAPI = await renderTextInput({ + labelComponent: First name (required)*, + returnKeyType: 'next', + testID: 'text-input', + accessibilityLabel: 'Please insert your first name', + hasValidation: true, + hasError: false, + errorMessage: 'This is the errorComponent', + errorComponent: <>, + }); expect(renderAPI.getByTestId('text-input').props.accessibilityHint).toBe( '', ); }); - it('when hasError uses the text from the errorComponent as part of the accessibilityHint', () => { - const renderAPI = render( - First name (required)*} - returnKeyType="next" - testID="text-input" - accessibilityLabel="Please insert your first name" - accessibilityHint="The hint" - hasValidation={true} - hasError={true} - errorComponent={The first name cannot be blank} - />, - ); - + it('when hasError uses the text from the errorComponent as part of the accessibilityHint', async () => { + const renderAPI = await renderTextInput({ + labelComponent: First name (required)*, + returnKeyType: 'next', + testID: 'text-input', + accessibilityLabel: 'Please insert your first name', + accessibilityHint: 'The hint', + hasValidation: true, + hasError: true, + errorComponent: The first name cannot be blank, + }); expect(renderAPI.getByTestId('text-input').props.accessibilityHint).toBe( 'The hint, The first name cannot be blank', ); }); - it('when hasError uses the errorText, if specified, as part of the accessibilityHint', () => { - const renderAPI = render( - First name (required)*} - returnKeyType="next" - testID="text-input" - accessibilityLabel="Please insert your first name" - accessibilityHint="The hint" - hasValidation={true} - hasError={true} - errorMessage="This text will be used" - errorComponent={The first name cannot be blank} - />, - ); + it('when hasError uses the errorText, if specified, as part of the accessibilityHint', async () => { + const renderAPI = await renderTextInput({ + labelComponent: First name (required)*, + returnKeyType: 'next', + testID: 'text-input', + accessibilityLabel: 'Please insert your first name', + accessibilityHint: 'The hint', + hasValidation: true, + hasError: true, + errorMessage: 'This text will be used', + errorComponent: The first name cannot be blank, + }); expect(renderAPI.getByTestId('text-input').props.accessibilityHint).toBe( 'The hint, This text will be used', ); }); - it('apply the style returned by useFormField', () => { + it('apply the style returned by useFormField', async () => { const focusNextFormField = jest.fn(); jest.spyOn(UseFormField, 'useFormField').mockReturnValue({ @@ -444,15 +422,13 @@ describe('TextInput', () => { style: ERROR_STYLE, } as any); - const renderAPI = render( - First name (required)*} - returnKeyType="next" - testID="text-input" - accessibilityLabel="Please insert your first name" - hasValidation={false} - />, - ); + const renderAPI = await renderTextInput({ + labelComponent: First name (required)*, + returnKeyType: 'next', + testID: 'text-input', + accessibilityLabel: 'Please insert your first name', + hasValidation: false, + }); expect(renderAPI.getByTestId('text-input').props.style).toEqual( ERROR_STYLE, @@ -486,40 +462,50 @@ describe('TextInput', () => { TextInputWithoutDev = require('./TextInput').TextInput; }); - it('does not perform any check', () => { - render( - First name (required)*} - returnKeyType="next" - testID="text-input" - accessibilityLabel="Please insert your first name" - hasValidation={false} - />, - ); + it('does not perform any check', async () => { + await renderTextInput({ + labelComponent: First name (required)*, + returnKeyType: 'next', + testID: 'text-input', + accessibilityLabel: 'Please insert your first name', + hasValidation: false, + }); expect(noUndefinedProperty).not.toHaveBeenCalled(); }); - it('does not apply the debug style', () => { + it('does not apply the debug style', async () => { jest.spyOn(UseFormField, 'useFormField').mockReturnValue({ style: ERROR_STYLE, } as any); - const { getByTestId } = render( - First name (required)*} - returnKeyType="next" - testID="text-input" - accessibilityLabel="Please insert your first name" - hasValidation={false} - />, - ); + const { getByTestId } = await renderTextInput({ + labelComponent: First name (required)*, + returnKeyType: 'next', + testID: 'text-input', + accessibilityLabel: 'Please insert your first name', + hasValidation: false, + }); expect(getByTestId('text-input').props.style).toEqual(undefined); }); }); }); +const renderTextInput = async (props: TextInputProps) => { + const result = render( + + + , + ); + + await act(async () => { + await new Promise(process.nextTick); + }); + + return result; +}; + jest.mock('../hooks/useFormField', () => { return { useFormField: jest.fn().mockReturnValue({}),