Skip to content

Commit

Permalink
fix (FormItem): fix multi select error never shown
Browse files Browse the repository at this point in the history
  • Loading branch information
jannikbuschke committed Nov 28, 2021
1 parent 0934b61 commit 11269b2
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 3 deletions.
44 changes: 44 additions & 0 deletions src/field/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import '@testing-library/jest-dom/extend-expect'
import React from 'react'
import { Formik } from 'formik'
import { render, fireEvent, waitForDomChange } from '@testing-library/react'
import Form from '../form/form'
import Input from '../input'
import { act } from 'react-dom/test-utils'

const Container = ({ fast }: { fast: boolean }) => {
return (
<Formik initialValues={{ field: 'initial value' }} onSubmit={() => {}}>
<Form>
<Input data-testid='uat' name='field' fast={fast} />
</Form>
</Formik>
)
}

describe('test initial value', () => {
it.each`
fast
${true}
${false}
`('should display initial value (fast=$fast)', async (fast: boolean) => {
const { findByTestId } = render(<Container fast={fast} />)
expect(await findByTestId('uat')).toHaveValue('initial value')
})
})

describe('should change', () => {
it.each`
fast
${true}
${false}
`('should change (fast=$fast)', async (fast: boolean) => {
const { findByTestId } = render(<Container fast={fast} />)
const uat = await findByTestId('uat')
await act(async () => {
fireEvent.change(uat, { target: { value: 'new value' } })
await waitForDomChange()
})
expect(await findByTestId('uat')).toHaveValue('new value')
})
})
28 changes: 26 additions & 2 deletions src/form-item/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
fireEvent,
waitForDomChange,
wait,
waitFor,
getAllByRole,
} from '@testing-library/react'
import FormItem from '.'
Expand Down Expand Up @@ -147,7 +148,7 @@ test('should not display help if no display is required', async () => {
})

test('handles changes on multiselect without prop-types error', async () => {
const { getByTestId, queryByText, baseElement, container } = render(
const { getByTestId, queryByText, baseElement } = render(
<Test>
<Select name='test' data-testid='input' mode='multiple' open={true}>
<Option value={1}>1</Option>
Expand All @@ -162,17 +163,40 @@ test('handles changes on multiselect without prop-types error', async () => {
await act(async () => {
fireEvent.click(uat)
})

// work around type error: cast to any
await wait(() => getAllByRole(baseElement as any, 'option'))
await waitFor(() => getAllByRole(baseElement as any, 'option'))
// work around type error: cast to any
const one = getAllByRole(baseElement as any, 'option')

fireEvent.click(one[0])

expect(console.error).not.toHaveBeenCalled()
//@ts-ignore
console.error.mockRestore()
})

test('handles changes on multiselect with array field error', async () => {
const validate = () => 'error'
const { getByTestId, queryByText } = render(
<Formik initialValues={{ test: [] }} onSubmit={() => {}}>
<Form>
<FormItem name='test' validate={validate}>
<Select name='test' data-testid='input' mode='multiple' open={true}>
<Option value={1}>1</Option>
<Option value={2}>2</Option>
</Select>
</FormItem>
<SubmitButton data-testid='submit' />
</Form>
</Formik>,
)
expect(queryByText('error')).not.toBeInTheDocument()
fireEvent.click(getByTestId('submit'))
await waitForDomChange()
expect(queryByText('error')).toBeInTheDocument()
})

test('displays validation result on nested input', async () => {
const validate = () => 'error'
const { getByTestId, queryByText } = render(
Expand Down
5 changes: 4 additions & 1 deletion src/form-item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ export const FormItem = ({
const initialError = getIn(initialErrors, name, undefined)
let isTouched = getIn(touched, name, false) as boolean | boolean[]
if (Array.isArray(isTouched)) {
isTouched = isTouched.reduce((acc, value) => acc || value, false)
isTouched =
isTouched.length === 0
? true
: isTouched.reduce((acc, value) => acc || value, false)
}
const hasError = error !== undefined && isTouched
const hasInitialError = initialError !== undefined
Expand Down

0 comments on commit 11269b2

Please sign in to comment.