Skip to content

Commit

Permalink
fix(Field.NationalIdentityNumber): validate on all digits(not only 11…
Browse files Browse the repository at this point in the history
… digits) (#4079)

Co-authored-by: Tobias Høegh <[email protected]>
  • Loading branch information
langz and tujoworker authored Oct 8, 2024
1 parent 7536752 commit 7c34fc9
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ You can provide your own validation function.

### Extend validation with custom validation function

You can [extend the existing validations](/uilib/extensions/forms/create-component/useFieldProps/info/#validators)(`dnrValidator` and `fnrValidator`) with your own validation function.
You can [extend the existing validations](/uilib/extensions/forms/create-component/useFieldProps/info/#validators)(`dnrValidator`, `fnrValidator`, and `dnrAndFnrValidator`) with your own validation function.

<Examples.ValidationExtendValidator />
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ import { NationalIdentityNumberProperties } from '@dnb/eufemia/src/extensions/fo

<PropertiesTable props={fieldProperties} />

## Validators

`Field.NationalIdentityNumber` expose the following validators through its `validator` and `onBlurValidator` property:

- `dnrValidator`: validates a d number.
- `fnrValidator`: validates a national identity number (fødselsnummer).
- `dnrAndFnrValidator`:
- validates the identification number as a d number when first digit is 4 or greater (because a d number has its first number increased by 4).
- validates the identification number as a national identity number (fødselsnummer) when first digit is 3 or less.

See the following [example](/uilib/extensions/forms/feature-fields/NationalIdentityNumber/#extend-validation-with-custom-validation-function) on how to extend validation using the exposed validators.

## Translations

<TranslationsTable localeKey={['NationalIdentityNumber', 'Field']} />
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,8 @@ function NationalIdentityNumber(props: Props) {

const fnrValidator = useCallback(
(value: string) => {
if (
new RegExp(validationPattern).test(value) &&
fnr(value).status === 'invalid'
) {
// have to check for undefined as @navikt/fnrvalidator does not support undefined
if (value === undefined || fnr(value).status === 'invalid') {
return Error(errorFnr)
}
},
Expand All @@ -58,11 +56,8 @@ function NationalIdentityNumber(props: Props) {

const dnrValidator = useCallback(
(value: string) => {
const validationPattern = '^[4-7]([0-9]{10}$)' // 1st num is increased by 4. i.e, if 01.01.1985, D number would be 410185.
if (
new RegExp(validationPattern).test(value) &&
dnr(value).status === 'invalid'
) {
// have to check for undefined as @navikt/fnrvalidator does not support undefined
if (value === undefined || dnr(value).status === 'invalid') {
return Error(errorDnr)
}
},
Expand All @@ -71,7 +66,12 @@ function NationalIdentityNumber(props: Props) {

const dnrAndFnrValidator = useCallback(
(value: string) => {
return dnrValidator(value) || fnrValidator(value)
const validationPattern = '^[4-9].*' // 1st num is increased by 4. i.e, if 01.01.1985, D number would be 410185.

if (new RegExp(validationPattern).test(value)) {
return dnrValidator(value)
}
return fnrValidator(value)
},
[dnrValidator, fnrValidator]
)
Expand All @@ -93,7 +93,7 @@ function NationalIdentityNumber(props: Props) {
onBlurValidator: validate
? props.onBlurValidator || dnrAndFnrValidator
: undefined,
exportValidators: { dnrValidator, fnrValidator },
exportValidators: { dnrValidator, fnrValidator, dnrAndFnrValidator },
}

return <StringField {...StringFieldProps} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,53 @@ describe('Field.NationalIdentityNumber', () => {
expect(screen.queryByRole('alert')).toBeInTheDocument()
})

it('should execute validateInitially if required', async () => {
const { rerender } = render(
<Field.NationalIdentityNumber required validateInitially />
it('should validate "required"', async () => {
render(<Field.NationalIdentityNumber required validateInitially />)

expect(screen.queryByRole('alert')).toBeInTheDocument()
expect(screen.queryByRole('alert')).toHaveTextContent(
nb.NationalIdentityNumber.errorRequired
)
})

it('should show "errorRequired" error message when "pattern" not matches', async () => {
render(<Field.NationalIdentityNumber validateInitially value="123" />)

expect(screen.queryByRole('alert')).toBeInTheDocument()
expect(screen.queryByRole('alert')).toHaveTextContent(
nb.NationalIdentityNumber.errorRequired
)
})

it('should validate internal validator', async () => {
const { rerender } = render(
<Field.NationalIdentityNumber
validateInitially
pattern=".*"
value="123"
/>
)

rerender(<Field.NationalIdentityNumber validateInitially />)
await waitFor(() => {
expect(screen.queryByRole('alert')).toBeInTheDocument()
expect(screen.queryByRole('alert')).toHaveTextContent(
nb.NationalIdentityNumber.errorFnr
)
})

rerender(
<Field.NationalIdentityNumber
validateInitially
pattern=".*"
value="456"
/>
)

await waitFor(() => {
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
expect(screen.queryByRole('alert')).toBeInTheDocument()
expect(screen.queryByRole('alert')).toHaveTextContent(
nb.NationalIdentityNumber.errorDnr
)
})
})

Expand Down Expand Up @@ -362,13 +398,13 @@ describe('Field.NationalIdentityNumber', () => {
: { status: 'invalid' }

const customValidator: Validator<string> = (value, { validators }) => {
const { dnrValidator, fnrValidator } = validators
const { dnrAndFnrValidator } = validators
const result = bornInApril(value)
if (result.status === 'invalid') {
return new Error('custom error')
}

return [dnrValidator, fnrValidator]
return [dnrAndFnrValidator]
}

it.each(validIds)('Valid identity number: %s', async (fnrNum) => {
Expand Down

0 comments on commit 7c34fc9

Please sign in to comment.