Skip to content

Commit

Permalink
fix(Forms): ensure onBlurValidator gets called when `validateInitia…
Browse files Browse the repository at this point in the history
…lly` is true (#4069)

- Relies on #4068
- Fixes #4066

At least hope it will fix it. 

**NB:** When using this code:

```tsx
<Field.OrganizationNumber
  onBlurValidator={myValidator}
  validateInitially
/>
```

it will not show the error. This is simply because internally we check
if there is a value/pattern that matches. And only if it matches, the
validator will run.

Therefore this particular field needs a `value` or `defaultValue` to run
a validator, not matter if it is an `onBlurValidator` or not.

```tsx
<Field.OrganizationNumber
  onBlurValidator={myValidator}
  validateInitially
  defaultValue="123 331 231"
/>
```
  • Loading branch information
tujoworker authored Oct 7, 2024
1 parent cab6d01 commit 59cf6c5
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -663,10 +663,10 @@ describe('Field.String', () => {
render(<Field.String value="abc" onChange={onChange} />)
const input = document.querySelector('input')
await userEvent.type(input, 'def')
expect(onChange.mock.calls).toHaveLength(3)
expect(onChange.mock.calls[0][0]).toEqual('abcd')
expect(onChange.mock.calls[1][0]).toEqual('abcde')
expect(onChange.mock.calls[2][0]).toEqual('abcdef')
expect(onChange).toHaveBeenCalledTimes(3)
expect(onChange).toHaveBeenNthCalledWith(1, 'abcd')
expect(onChange).toHaveBeenNthCalledWith(2, 'abcde')
expect(onChange).toHaveBeenNthCalledWith(3, 'abcdef')
})

it('calls onFocus with current value', () => {
Expand All @@ -676,8 +676,8 @@ describe('Field.String', () => {
act(() => {
input.focus()
})
expect(onFocus.mock.calls).toHaveLength(1)
expect(onFocus.mock.calls[0][0]).toEqual('blah')
expect(onFocus).toHaveBeenCalledTimes(1)
expect(onFocus).toHaveBeenNthCalledWith(1, 'blah')
})

it('calls onBlur with current value', async () => {
Expand All @@ -687,12 +687,12 @@ describe('Field.String', () => {
input.focus()
fireEvent.blur(input)
await wait(0)
expect(onBlur.mock.calls).toHaveLength(1)
expect(onBlur.mock.calls[0][0]).toEqual('song2')
expect(onBlur).toHaveBeenCalledTimes(1)
expect(onBlur).toHaveBeenNthCalledWith(1, 'song2')
await userEvent.type(input, '345')
fireEvent.blur(input)
expect(onBlur.mock.calls).toHaveLength(2)
expect(onBlur.mock.calls[1][0]).toEqual('song2345')
expect(onBlur).toHaveBeenCalledTimes(2)
expect(onBlur).toHaveBeenNthCalledWith(2, 'song2345')
})
})

Expand Down Expand Up @@ -881,8 +881,12 @@ describe('Field.String', () => {
)
await waitFor(() => {
// Wait for since external validators are processed asynchronously
expect(validator.mock.calls).toHaveLength(1)
expect((validator.mock.calls[0] as unknown[])[0]).toEqual('abc')
expect(validator).toHaveBeenCalledTimes(1)
expect(validator).toHaveBeenNthCalledWith(
1,
'abc',
expect.anything()
)
expect(
screen.getByText('I think this is wrong')
).toBeInTheDocument()
Expand All @@ -893,13 +897,21 @@ describe('Field.String', () => {
fireEvent.blur(input)

await waitFor(() => {
expect(validator.mock.calls).toHaveLength(4)
expect((validator.mock.calls[1] as unknown[])[0]).toEqual('abcd')
expect((validator.mock.calls[2] as unknown[])[0]).toEqual(
'abcde'
expect(validator).toHaveBeenCalledTimes(4)
expect(validator).toHaveBeenNthCalledWith(
2,
'abcd',
expect.anything()
)
expect(validator).toHaveBeenNthCalledWith(
3,
'abcde',
expect.anything()
)
expect((validator.mock.calls[3] as unknown[])[0]).toEqual(
'abcdef'
expect(validator).toHaveBeenNthCalledWith(
4,
'abcdef',
expect.anything()
)
expect(
screen.getByText('I think this is wrong')
Expand Down Expand Up @@ -935,8 +947,12 @@ describe('Field.String', () => {
)
await waitFor(() => {
// Wait for since external validators are processed asynchronously
expect(validator.mock.calls).toHaveLength(1)
expect((validator.mock.calls[0] as unknown[])[0]).toEqual('abc')
expect(validator).toHaveBeenCalledTimes(1)
expect(validator).toHaveBeenNthCalledWith(
1,
'abc',
expect.anything()
)
expect(
screen.getByText('Whats left when nothing is right?')
).toBeInTheDocument()
Expand All @@ -949,10 +965,22 @@ describe('Field.String', () => {
fireEvent.blur(input)
})

expect(validator.mock.calls).toHaveLength(4)
expect((validator.mock.calls[1] as unknown[])[0]).toEqual('abcd')
expect((validator.mock.calls[2] as unknown[])[0]).toEqual('abcde')
expect((validator.mock.calls[3] as unknown[])[0]).toEqual('abcdef')
expect(validator).toHaveBeenCalledTimes(4)
expect(validator).toHaveBeenNthCalledWith(
2,
'abcd',
expect.anything()
)
expect(validator).toHaveBeenNthCalledWith(
3,
'abcde',
expect.anything()
)
expect(validator).toHaveBeenNthCalledWith(
4,
'abcdef',
expect.anything()
)
expect(
screen.getByText('Whats left when nothing is right?')
).toBeInTheDocument()
Expand Down Expand Up @@ -988,18 +1016,25 @@ describe('Field.String', () => {

await waitFor(() => {
// Wait for since external validators are processed asynchronously
expect(validator.mock.calls).toHaveLength(0)
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
expect(validator).toHaveBeenCalledTimes(1)
expect(screen.queryByRole('alert')).toBeInTheDocument()
})
const input = document.querySelector('input')
await userEvent.type(input, 'def')
fireEvent.blur(input)

await waitFor(() => {
// Wait for since external validators are processed asynchronously
expect(validator.mock.calls).toHaveLength(1)
expect((validator.mock.calls[0] as unknown[])[0]).toEqual(
'abcdef'
expect(validator).toHaveBeenCalledTimes(2)
expect(validator).toHaveBeenNthCalledWith(
1,
'abc',
expect.anything()
)
expect(validator).toHaveBeenNthCalledWith(
2,
'abcdef',
expect.anything()
)

expect(
Expand Down Expand Up @@ -1040,18 +1075,25 @@ describe('Field.String', () => {

await waitFor(() => {
// Wait for since external validators are processed asynchronously
expect(validator.mock.calls).toHaveLength(0)
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
expect(validator).toHaveBeenCalledTimes(1)
expect(screen.queryByRole('alert')).toBeInTheDocument()
})
const input = document.querySelector('input')
await userEvent.type(input, 'def')
fireEvent.blur(input)

await waitFor(() => {
// Wait for since external validators are processed asynchronously
expect(validator.mock.calls).toHaveLength(1)
expect((validator.mock.calls[0] as unknown[])[0]).toEqual(
'abcdef'
expect(validator).toHaveBeenCalledTimes(2)
expect(validator).toHaveBeenNthCalledWith(
1,
'abc',
expect.anything()
)
expect(validator).toHaveBeenNthCalledWith(
2,
'abcdef',
expect.anything()
)

expect(
Expand Down Expand Up @@ -1153,29 +1195,36 @@ describe('Field.String', () => {
await userEvent.type(input, 'O!')

await waitFor(() => {
expect(inputOnChange.mock.calls).toHaveLength(2)
expect(inputOnChange.mock.calls[0][0]).toEqual('FOOO')
expect(inputOnChange.mock.calls[1][0]).toEqual('FOOO!')

expect(dataContextOnChange.mock.calls).toHaveLength(2)
expect(dataContextOnChange.mock.calls[0][0]).toEqual({
foo: 'FOOO',
bar: 'BAAAR',
})
expect(dataContextOnChange.mock.calls[1][0]).toEqual({
foo: 'FOOO!',
bar: 'BAAAR',
})
expect(inputOnChange).toHaveBeenNthCalledWith(1, 'FOOO')
expect(inputOnChange).toHaveBeenNthCalledWith(2, 'FOOO!')

expect(dataContextOnPathChange.mock.calls).toHaveLength(2)
expect(dataContextOnPathChange.mock.calls[0]).toEqual([
expect(dataContextOnChange).toHaveBeenNthCalledWith(
1,
{
foo: 'FOOO',
bar: 'BAAAR',
},
expect.anything()
)
expect(dataContextOnChange).toHaveBeenNthCalledWith(
2,
{
foo: 'FOOO!',
bar: 'BAAAR',
},
expect.anything()
)

expect(dataContextOnPathChange).toHaveBeenNthCalledWith(
1,
'/foo',
'FOOO',
])
expect(dataContextOnPathChange.mock.calls[1]).toEqual([
'FOOO'
)
expect(dataContextOnPathChange).toHaveBeenNthCalledWith(
2,
'/foo',
'FOOO!',
])
'FOOO!'
)
})
})
})
Expand Down
Loading

0 comments on commit 59cf6c5

Please sign in to comment.