2022-11-22 22:04:27 +01:00
/* eslint-disable jest/require-top-level-describe */
import React from 'react' ;
import { fireEvent , render } from '@testing-library/react' ;
import {
renderControlledInput ,
renderWithUserEvent ,
} from '../../../../test/lib/render-helpers' ;
import { SIZES } from '../../../helpers/constants/design-system' ;
import { FormTextField } from './form-text-field' ;
describe ( 'FormTextField' , ( ) => {
it ( 'should render correctly' , ( ) => {
const { getByRole , container } = render ( < FormTextField / > ) ;
expect ( getByRole ( 'textbox' ) ) . toBeDefined ( ) ;
expect ( container ) . toMatchSnapshot ( ) ;
} ) ;
// autoComplete
it ( 'should render with autoComplete' , ( ) => {
const { getByTestId } = render (
< FormTextField
autoComplete
inputProps = { { 'data-testid' : 'form-text-field-auto-complete' } }
/ > ,
) ;
expect ( getByTestId ( 'form-text-field-auto-complete' ) ) . toHaveAttribute (
'autocomplete' ,
'on' ,
) ;
} ) ;
// autoFocus
it ( 'should render with autoFocus' , ( ) => {
const { getByRole } = render ( < FormTextField autoFocus / > ) ;
expect ( getByRole ( 'textbox' ) ) . toHaveFocus ( ) ;
} ) ;
// className
it ( 'should render with custom className' , ( ) => {
const { getByTestId } = render (
< FormTextField data - testid = "form-text-field" className = "test-class" / > ,
) ;
expect ( getByTestId ( 'form-text-field' ) ) . toHaveClass ( 'test-class' ) ;
} ) ;
// defaultValue
it ( 'should render with a defaultValue' , ( ) => {
const { getByRole } = render (
< FormTextField defaultValue = "default value" / > ,
) ;
expect ( getByRole ( 'textbox' ) . value ) . toBe ( 'default value' ) ;
} ) ;
// disabled
it ( 'should render in disabled state and not focus or be clickable' , async ( ) => {
const mockOnClick = jest . fn ( ) ;
const mockOnFocus = jest . fn ( ) ;
const { getByRole , user , getByLabelText } = renderWithUserEvent (
< FormTextField
label = "test label"
id = "test-id"
disabled
onFocus = { mockOnFocus }
onClick = { mockOnClick }
/ > ,
) ;
await user . click ( getByLabelText ( 'test label' ) ) ;
expect ( mockOnFocus ) . toHaveBeenCalledTimes ( 0 ) ;
await user . type ( getByRole ( 'textbox' ) , 'test value' ) ;
expect ( getByRole ( 'textbox' ) ) . not . toHaveValue ( 'test value' ) ;
expect ( getByRole ( 'textbox' ) ) . toBeDisabled ( ) ;
expect ( mockOnClick ) . toHaveBeenCalledTimes ( 0 ) ;
expect ( mockOnFocus ) . toHaveBeenCalledTimes ( 0 ) ;
} ) ;
// error
it ( 'should render with error classNames on TextField and HelpText components when error is true' , ( ) => {
const { getByTestId , getByText } = render (
< FormTextField
error
textFieldProps = { { 'data-testid' : 'text-field' } }
helpText = "test help text"
/ > ,
) ;
expect ( getByTestId ( 'text-field' ) ) . toHaveClass ( 'mm-text-field-base--error' ) ;
expect ( getByText ( 'test help text' ) ) . toHaveClass (
2022-12-01 18:26:19 +01:00
'mm-text--color-error-default' ,
2022-11-22 22:04:27 +01:00
) ;
} ) ;
// helpText
it ( 'should render with helpText' , ( ) => {
const { getByText } = render ( < FormTextField helpText = "test help text" / > ) ;
expect ( getByText ( 'test help text' ) ) . toBeDefined ( ) ;
} ) ;
// helpTextProps
it ( 'should render with helpText and helpTextProps' , ( ) => {
const { getByText , getByTestId } = render (
< FormTextField
helpText = "test help text"
helpTextProps = { { 'data-testid' : 'help-text-test' } }
/ > ,
) ;
expect ( getByText ( 'test help text' ) ) . toBeDefined ( ) ;
expect ( getByTestId ( 'help-text-test' ) ) . toBeDefined ( ) ;
} ) ;
// id
it ( 'should render the FormTextField with an id and pass it to input and Label as htmlFor. When clicking on Label the input should have focus' , async ( ) => {
const onFocus = jest . fn ( ) ;
const { getByRole , getByLabelText , user } = renderWithUserEvent (
< FormTextField label = "test label" id = "test-id" onFocus = { onFocus } / > ,
) ;
expect ( getByRole ( 'textbox' ) ) . toHaveAttribute ( 'id' , 'test-id' ) ;
await user . click ( getByLabelText ( 'test label' ) ) ;
expect ( onFocus ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( getByRole ( 'textbox' ) ) . toHaveFocus ( ) ;
} ) ;
// inputProps
it ( 'should render with inputProps' , ( ) => {
const { getByTestId } = render (
< FormTextField inputProps = { { 'data-testid' : 'test-id' } } / > ,
) ;
expect ( getByTestId ( 'test-id' ) ) . toBeDefined ( ) ;
} ) ;
// inputRef
it ( 'should render with working ref using inputRef prop' , ( ) => {
// Because the 'ref' attribute wont flow down to the DOM
// I'm not exactly sure how to test this?
const mockRef = jest . fn ( ) ;
const { getByRole } = render ( < FormTextField inputRef = { mockRef } / > ) ;
expect ( getByRole ( 'textbox' ) ) . toBeDefined ( ) ;
expect ( mockRef ) . toHaveBeenCalledTimes ( 1 ) ;
} ) ;
// label
it ( 'should render with a label' , ( ) => {
const { getByLabelText } = render (
< FormTextField id = "test-id" label = "test label" / > ,
) ;
expect ( getByLabelText ( 'test label' ) ) . toBeDefined ( ) ;
} ) ;
// labelProps
it ( 'should render with a labelProps' , ( ) => {
const { getByTestId , getByLabelText } = render (
< FormTextField
label = "test label"
labelProps = { { 'data-testid' : 'label-test-id' } }
id = "test-id"
/ > ,
) ;
expect ( getByLabelText ( 'test label' ) ) . toBeDefined ( ) ;
expect ( getByTestId ( 'label-test-id' ) ) . toBeDefined ( ) ;
} ) ;
// leftAccessory, // rightAccessory
it ( 'should render with right and left accessories' , ( ) => {
const { getByRole , getByText } = render (
< FormTextField
leftAccessory = { < div > left accessory < / d i v > }
rightAccessory = { < div > right accessory < / d i v > }
/ > ,
) ;
expect ( getByRole ( 'textbox' ) ) . toBeDefined ( ) ;
expect ( getByText ( 'left accessory' ) ) . toBeDefined ( ) ;
expect ( getByText ( 'right accessory' ) ) . toBeDefined ( ) ;
} ) ;
// maxLength;
it ( 'should render with maxLength and not allow more than the set characters' , async ( ) => {
const { getByRole , user } = renderWithUserEvent (
< FormTextField maxLength = { 5 } / > ,
) ;
const formTextField = getByRole ( 'textbox' ) ;
await user . type ( formTextField , '1234567890' ) ;
expect ( getByRole ( 'textbox' ) ) . toBeDefined ( ) ;
expect ( formTextField . maxLength ) . toBe ( 5 ) ;
expect ( formTextField . value ) . toBe ( '12345' ) ;
expect ( formTextField . value ) . toHaveLength ( 5 ) ;
} ) ;
// name
it ( 'should render with name prop' , ( ) => {
const { getByRole } = render ( < FormTextField name = "test-name" / > ) ;
expect ( getByRole ( 'textbox' ) ) . toHaveAttribute ( 'name' , 'test-name' ) ;
} ) ;
// onBlur, // onFocus
it ( 'should render and fire onFocus and onBlur events' , async ( ) => {
const onFocus = jest . fn ( ) ;
const onBlur = jest . fn ( ) ;
const { getByTestId , user } = renderWithUserEvent (
< FormTextField
inputProps = { { 'data-testid' : 'form-text-field' } }
onFocus = { onFocus }
onBlur = { onBlur }
/ > ,
) ;
const formTextField = getByTestId ( 'form-text-field' ) ;
await user . click ( formTextField ) ;
expect ( onFocus ) . toHaveBeenCalledTimes ( 1 ) ;
fireEvent . blur ( formTextField ) ;
expect ( onBlur ) . toHaveBeenCalledTimes ( 1 ) ;
} ) ;
// onChange
it ( 'should render and fire onChange event' , async ( ) => {
const onChange = jest . fn ( ) ;
const { user , getByRole } = renderWithUserEvent (
< FormTextField onChange = { onChange } / > ,
) ;
await user . type ( getByRole ( 'textbox' ) , 'test' ) ;
expect ( onChange ) . toHaveBeenCalledTimes ( 4 ) ;
} ) ;
// placeholder
it ( 'should render with placeholder' , ( ) => {
const { getByTestId } = render (
< FormTextField
placeholder = "test placeholder"
inputProps = { { 'data-testid' : 'form-text-field-auto-complete' } }
/ > ,
) ;
expect ( getByTestId ( 'form-text-field-auto-complete' ) ) . toHaveAttribute (
'placeholder' ,
'test placeholder' ,
) ;
} ) ;
// readOnly
it ( 'should render with readOnly attr when readOnly is true' , async ( ) => {
const { getByRole , user } = renderWithUserEvent (
< FormTextField
readOnly
value = "test value"
data - testid = "read-only"
inputProps = { { 'data-testid' : 'text-field-base-readonly' } }
/ > ,
) ;
await user . type ( getByRole ( 'textbox' ) , 'test' ) ;
expect ( getByRole ( 'textbox' ) ) . toHaveValue ( 'test value' ) ;
expect ( getByRole ( 'textbox' ) ) . toHaveAttribute ( 'readonly' , '' ) ;
} ) ;
// required
it ( 'should render with required asterisk after Label' , ( ) => {
const { getByTestId } = render (
< FormTextField
required
label = "test label"
labelProps = { { 'data-testid' : 'label-test-id' } }
/ > ,
) ;
expect ( getByTestId ( 'label-test-id' ) ) . toHaveTextContent ( 'test label*' ) ;
} ) ;
// size = SIZES.MD
it ( 'should render with different size classes' , ( ) => {
const { getByTestId } = render (
< >
< FormTextField
size = { SIZES . SM }
textFieldProps = { { 'data-testid' : 'sm' } }
/ >
< FormTextField
size = { SIZES . MD }
textFieldProps = { { 'data-testid' : 'md' } }
/ >
< FormTextField
size = { SIZES . LG }
textFieldProps = { { 'data-testid' : 'lg' } }
/ >
< / > ,
) ;
expect ( getByTestId ( 'sm' ) ) . toHaveClass ( 'mm-text-field-base--size-sm' ) ;
expect ( getByTestId ( 'md' ) ) . toHaveClass ( 'mm-text-field-base--size-md' ) ;
expect ( getByTestId ( 'lg' ) ) . toHaveClass ( 'mm-text-field-base--size-lg' ) ;
} ) ;
// textFieldProps
it ( 'should render with textFieldProps' , ( ) => {
const { getByTestId } = render (
< FormTextField textFieldProps = { { 'data-testid' : 'test-text-field' } } / > ,
) ;
expect ( getByTestId ( 'test-text-field' ) ) . toBeDefined ( ) ;
} ) ;
// truncate
it ( 'should render with truncate class as true by default and remove it when truncate is false' , ( ) => {
const { getByTestId } = render (
< >
< FormTextField textFieldProps = { { 'data-testid' : 'truncate' } } / >
< FormTextField
truncate = { false }
textFieldProps = { { 'data-testid' : 'no-truncate' } }
/ >
< / > ,
) ;
expect ( getByTestId ( 'truncate' ) ) . toHaveClass ( 'mm-text-field-base--truncate' ) ;
expect ( getByTestId ( 'no-truncate' ) ) . not . toHaveClass (
'mm-text-field-base--truncate' ,
) ;
} ) ;
// showClearButton
it ( 'should render showClearButton button when showClearButton is true and value exists' , async ( ) => {
// As showClearButton is intended to be used with a controlled input we need to use renderControlledInput
const { user , getByRole } = renderControlledInput ( FormTextField , {
showClearButton : true ,
} ) ;
await user . type ( getByRole ( 'textbox' ) , 'test value' ) ;
expect ( getByRole ( 'textbox' ) ) . toHaveValue ( 'test value' ) ;
expect ( getByRole ( 'button' , { name : /Clear/u } ) ) . toBeDefined ( ) ;
} ) ;
// clearButtonOnClick
it ( 'should fire onClick event when passed to clearButtonOnClick when clear button is clicked' , async ( ) => {
// As showClearButton is intended to be used with a controlled input we need to use renderControlledInput
const fn = jest . fn ( ) ;
const { user , getByRole } = renderControlledInput ( FormTextField , {
showClearButton : true ,
clearButtonOnClick : fn ,
} ) ;
await user . type ( getByRole ( 'textbox' ) , 'test value' ) ;
await user . click ( getByRole ( 'button' , { name : /Clear/u } ) ) ;
expect ( fn ) . toHaveBeenCalledTimes ( 1 ) ;
} ) ;
// clearButtonProps,
it ( 'should fire onClick event when passed to clearButtonProps.onClick prop' , async ( ) => {
// As showClearButton is intended to be used with a controlled input we need to use renderControlledInput
const fn = jest . fn ( ) ;
const { user , getByRole } = renderControlledInput ( FormTextField , {
showClearButton : true ,
clearButtonProps : { onClick : fn } ,
} ) ;
await user . type ( getByRole ( 'textbox' ) , 'test value' ) ;
await user . click ( getByRole ( 'button' , { name : /Clear/u } ) ) ;
expect ( fn ) . toHaveBeenCalledTimes ( 1 ) ;
} ) ;
// type,
it ( 'should render with different types' , ( ) => {
const { getByTestId } = render (
< >
< FormTextField inputProps = { { 'data-testid' : 'form-text-field-text' } } / >
< FormTextField
type = "number"
inputProps = { { 'data-testid' : 'form-text-field-number' } }
/ >
< FormTextField
type = "password"
inputProps = { { 'data-testid' : 'form-text-field-password' } }
/ >
< / > ,
) ;
expect ( getByTestId ( 'form-text-field-text' ) ) . toHaveAttribute ( 'type' , 'text' ) ;
expect ( getByTestId ( 'form-text-field-number' ) ) . toHaveAttribute (
'type' ,
'number' ,
) ;
expect ( getByTestId ( 'form-text-field-password' ) ) . toHaveAttribute (
'type' ,
'password' ,
) ;
} ) ;
} ) ;