Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Forms): don't call internal exportValidators when they not are exported as an array #4113

Merged
merged 2 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3372,7 +3372,7 @@ describe('useFieldProps', () => {
})
})

describe('exportValidators', () => {
describe('validators given as an array', () => {
it('should call all validators returned as an array', async () => {
const fooValidator = jest.fn((value) => {
if (value.includes('foo')) {
Expand Down Expand Up @@ -3470,7 +3470,9 @@ describe('useFieldProps', () => {
expect(fooValidator).toHaveBeenCalledTimes(5)
expect(barValidator).toHaveBeenCalledTimes(4)
})
})

describe('exportValidators', () => {
it('should call exported validators from mock component', async () => {
let internalValidators, fooValidator, barValidator, bazValidator

Expand Down Expand Up @@ -3589,13 +3591,13 @@ describe('useFieldProps', () => {
await userEvent.type(input, '123')
fireEvent.blur(input)

expect(onBlurValidator).toHaveBeenCalledTimes(2)
expect(onBlurValidator).toHaveBeenCalledTimes(1)
expect(document.querySelector('.dnb-form-status')).toBeNull()

await userEvent.type(input, '4')
fireEvent.blur(input)

expect(onBlurValidator).toHaveBeenCalledTimes(3)
expect(onBlurValidator).toHaveBeenCalledTimes(2)
await waitFor(() => {
expect(
document.querySelector('.dnb-form-status')
Expand Down Expand Up @@ -3843,7 +3845,36 @@ describe('useFieldProps', () => {
})
})

it('should call internal validates when they are not returned in the publicValidator', async () => {
it('should not run exported internal validators when a validator is given', async () => {
const exportedValidator = jest.fn(() => {
return undefined
})

const myValidator = jest.fn(() => {
return undefined
})

const MockComponent = (props) => {
return (
<Field.String
label="Label"
validator={props.validator}
exportValidators={{ exportedValidator }}
validateInitially
/>
)
}

render(<MockComponent validator={myValidator} />)

await expect(() => {
expect(
document.querySelector('.dnb-form-status')
).toBeInTheDocument()
}).neverToResolve()
})

it('should not call internal validators when they are not returned in the publicValidator', async () => {
let internalValidators, barValidator, bazValidator

const MockComponent = (props) => {
Expand Down Expand Up @@ -3911,25 +3942,25 @@ describe('useFieldProps', () => {
document.querySelector('input'),
'{Backspace}bar'
)
await waitFor(() => {
expect(screen.queryByRole('alert')).toHaveTextContent('bar')
})
await expect(() => {
expect(screen.queryByRole('alert')).toBeInTheDocument()
}).neverToResolve()
expect(publicValidator).toHaveBeenCalledTimes(5)
expect(barValidator).toHaveBeenCalledTimes(4)
expect(bazValidator).toHaveBeenCalledTimes(3)
expect(barValidator).toHaveBeenCalledTimes(0)
expect(bazValidator).toHaveBeenCalledTimes(0)
expect(internalValidators).toHaveBeenCalledTimes(0)

await userEvent.type(
document.querySelector('input'),
'{Backspace}baz'
)

await waitFor(() => {
expect(screen.queryByRole('alert')).toHaveTextContent('baz')
})
await expect(() => {
expect(screen.queryByRole('alert')).toBeInTheDocument()
}).neverToResolve()
expect(publicValidator).toHaveBeenCalledTimes(9)
expect(barValidator).toHaveBeenCalledTimes(8)
expect(bazValidator).toHaveBeenCalledTimes(7)
expect(barValidator).toHaveBeenCalledTimes(0)
expect(bazValidator).toHaveBeenCalledTimes(0)
expect(internalValidators).toHaveBeenCalledTimes(0)
})
})
Expand Down
37 changes: 4 additions & 33 deletions packages/dnb-eufemia/src/extensions/forms/hooks/useFieldProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,24 +533,6 @@ export default function useFieldProps<Value, EmptyValue, Props>(

return args
}, [contextErrorMessages, getValueByPath, setFieldEventListener])
const extendWithExportedValidators = useCallback(
(
validator: Validator<Value>,
result: ReturnType<Validator<Value>>
) => {
if (
exportValidatorsRef.current &&
!result &&
(validator === onChangeValidatorRef.current ||
validator === onBlurValidatorRef.current)
) {
return Object.values(exportValidatorsRef.current)
}

return result
},
[]
)

const callStackRef = useRef<Array<Validator<Value>>>([])
const hasBeenCalledRef = useCallback((validator: Validator<Value>) => {
Expand All @@ -568,10 +550,7 @@ export default function useFieldProps<Value, EmptyValue, Props>(
return
}

const result = extendWithExportedValidators(
validator,
await validator(value, additionalArgs)
)
const result = await validator(value, additionalArgs)

if (Array.isArray(result)) {
for (const validator of result) {
Expand All @@ -589,7 +568,7 @@ export default function useFieldProps<Value, EmptyValue, Props>(
return result
}
},
[additionalArgs, extendWithExportedValidators, hasBeenCalledRef]
[additionalArgs, hasBeenCalledRef]
)

const callValidatorFnSync = useCallback(
Expand All @@ -601,10 +580,7 @@ export default function useFieldProps<Value, EmptyValue, Props>(
return // stop here
}

const result = extendWithExportedValidators(
validator,
validator(value, additionalArgs)
)
const result = validator(value, additionalArgs)

if (Array.isArray(result)) {
const hasAsyncValidator = result.some((validator) =>
Expand Down Expand Up @@ -633,12 +609,7 @@ export default function useFieldProps<Value, EmptyValue, Props>(
return result
}
},
[
additionalArgs,
callValidatorFnAsync,
extendWithExportedValidators,
hasBeenCalledRef,
]
[additionalArgs, callValidatorFnAsync, hasBeenCalledRef]
)

/**
Expand Down
Loading