Skip to content

Commit

Permalink
Fix: bad validation with zod in some fields (#861)
Browse files Browse the repository at this point in the history
* review validation with zod

* fix tests

* details
  • Loading branch information
PierreVasseur authored Jul 19, 2024
1 parent 6c8ebbe commit 0cdf1c3
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 131 deletions.
2 changes: 1 addition & 1 deletion src/js/applications/codelists/i18n/dictionary.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ const dictionary = {
},
validCharactersProperty: {
fr: (propertyName) =>
`La propriété <strong>${propertyName}</strong> possède des caractères invalid.`,
`La propriété <strong>${propertyName}</strong> possède des caractères invalides.`,
en: (propertyName) =>
`The property <strong>${propertyName}</strong> has invalid characters.`,
},
Expand Down
140 changes: 95 additions & 45 deletions src/js/applications/codelists/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,48 @@ export const formatLabel = (component) => {
};

const CodesList = z.object({
lastListUriSegment: z.string({
required_error: D.mandatoryProperty(D.lastListUriSegmentTitle),
}),
lastCodeUriSegment: z.string({
required_error: D.mandatoryProperty(D.lastCodeUriSegmentTitle),
}),
lastClassUriSegment: z.string({
required_error: D.mandatoryProperty(D.lastClassUriSegmentTitle),
}),
id: z.string({ required_error: D.mandatoryProperty(D.idTitle) }),
labelLg1: z.string({ required_error: D.mandatoryProperty(D1.labelTitle) }),
labelLg2: z.string({ required_error: D.mandatoryProperty(D2.labelTitle) }),
creator: z.string({ required_error: D.mandatoryProperty(D.creator) }),
disseminationStatus: z.string({
required_error: D.mandatoryProperty(
MainDictionary.disseminationStatusTitle
),
}),
lastListUriSegment: z
.string({
required_error: D.mandatoryProperty(D.lastListUriSegmentTitle),
})
.trim()
.min(1, { message: D.mandatoryProperty(D.lastListUriSegmentTitle) }),
lastCodeUriSegment: z
.string({
required_error: D.mandatoryProperty(D.lastCodeUriSegmentTitle),
})
.trim()
.min(1, { message: D.mandatoryProperty(D.lastCodeUriSegmentTitle) }),
lastClassUriSegment: z
.string({
required_error: D.mandatoryProperty(D.lastClassUriSegmentTitle),
})
.trim()
.min(1, { message: D.mandatoryProperty(D.lastClassUriSegmentTitle) }),
id: z
.string({ required_error: D.mandatoryProperty(D.idTitle) })
.trim()
.min(1, { message: D.mandatoryProperty(D.idTitle) }),
labelLg1: z
.string({ required_error: D.mandatoryProperty(D1.labelTitle) })
.trim()
.min(1, { message: D.mandatoryProperty(D1.labelTitle) }),
labelLg2: z
.string({ required_error: D.mandatoryProperty(D2.labelTitle) })
.trim()
.min(1, { message: D.mandatoryProperty(D2.labelTitle) }),
creator: z
.string({ required_error: D.mandatoryProperty(D.creator) })
.min(1, { message: D.mandatoryProperty(D.creator) }),
disseminationStatus: z
.string({
required_error: D.mandatoryProperty(
MainDictionary.disseminationStatusTitle
),
})
.min(1, {
message: D.mandatoryProperty(MainDictionary.disseminationStatusTitle),
}),
});
export const validateCodelist = (codelist) =>
formatValidation(CodesList)(codelist);
Expand All @@ -36,40 +60,66 @@ const PartialCodesList = z.object({
.string({
required_error: D.mandatoryProperty(D.idTitle),
})
.trim()
.min(1, { message: D.mandatoryProperty(D.idTitle) })
.regex(/^[a-zA-Z0-9_]*$/, D.validCharactersProperty(D1.idTitle)),
parentCode: z.string({
required_error: D.mandatoryProperty(D.parentCodelist),
}),
labelLg1: z.string({
required_error: D.mandatoryProperty(D1.labelTitle),
}),
labelLg2: z.string({
required_error: D.mandatoryProperty(D2.labelTitle),
}),
creator: z.string({
required_error: D.mandatoryProperty(D.creator),
}),
disseminationStatus: z.string({
required_error: D.mandatoryProperty(
MainDictionary.disseminationStatusTitle
),
}),
parentCode: z
.string({
required_error: D.mandatoryProperty(D.parentCodelist),
})
.min(1, { message: D.mandatoryProperty(D.parentCodelist) }),
labelLg1: z
.string({
required_error: D.mandatoryProperty(D1.labelTitle),
})
.trim()
.min(1, { message: D.mandatoryProperty(D1.labelTitle) }),
labelLg2: z
.string({
required_error: D.mandatoryProperty(D2.labelTitle),
})
.trim()
.min(1, { message: D.mandatoryProperty(D2.labelTitle) }),
creator: z
.string({
required_error: D.mandatoryProperty(D.creator),
})
.min(1, { message: D.mandatoryProperty(D.creator) }),
disseminationStatus: z
.string({
required_error: D.mandatoryProperty(
MainDictionary.disseminationStatusTitle
),
})
.min(1, {
message: D.mandatoryProperty(MainDictionary.disseminationStatusTitle),
}),
});
export const validatePartialCodelist = (codelist) =>
formatValidation(PartialCodesList)(codelist);

const Code = (shouldCheckDuplicate, codes) =>
z.object({
code: z.string({ required_error: D.mandatoryProperty(D.idTitle) }).refine(
(value) => {
return !shouldCheckDuplicate || !codes.find((c) => c.code === value);
},
{
message: D.ErrorDoubleCode,
}
),
labelLg1: z.string({ required_error: D.mandatoryProperty(D1.labelTitle) }),
labelLg2: z.string({ required_error: D.mandatoryProperty(D2.labelTitle) }),
code: z
.string({ required_error: D.mandatoryProperty(D.idTitle) })
.trim()
.min(1, { message: D.mandatoryProperty(D.idTitle) })
.refine(
(value) => {
return !shouldCheckDuplicate || !codes.find((c) => c.code === value);
},
{
message: D.ErrorDoubleCode,
}
),
labelLg1: z
.string({ required_error: D.mandatoryProperty(D1.labelTitle) })
.trim()
.min(1, { message: D.mandatoryProperty(D1.labelTitle) }),
labelLg2: z
.string({ required_error: D.mandatoryProperty(D2.labelTitle) })
.trim()
.min(1, { message: D.mandatoryProperty(D2.labelTitle) }),
});

export const validateCode = (code, codes, updateMode) => {
Expand Down
22 changes: 15 additions & 7 deletions src/js/applications/datasets/datasets/edit/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ import { formatValidation } from '../../../../new-architecture/utils/validation'
const Dataset = z.object({
labelLg1: z
.string({ required_error: D.mandatoryProperty(D1.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D1.title) }),
labelLg2: z
.string({ required_error: D.mandatoryProperty(D2.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D2.title) }),
altIdentifier: z
.string()
.regex(/^[a-zA-Z0-9-_]+$/, { message: D.altIdError })
.optional()
.or(z.literal('')),
creator: z.string({ required_error: D.mandatoryProperty(D1.creatorTitle) }),
.or(z.string().trim().length(0))
.optional(),
creator: z
.string({ required_error: D.mandatoryProperty(D1.creatorTitle) })
.min(1, { message: D.mandatoryProperty(D1.creatorTitle) }),
contributor: z
.string({
required_error: D.mandatoryProperty(D1.contributorTitle),
Expand All @@ -23,10 +27,14 @@ const Dataset = z.object({
.nonempty({
message: D.mandatoryProperty(D1.contributorTitle),
}),
disseminationStatus: z.string({
required_error: D.mandatoryProperty(D1.disseminationStatusTitle),
}),
idSerie: z.string({ required_error: D.mandatoryProperty(D1.generatedBy) }),
disseminationStatus: z
.string({
required_error: D.mandatoryProperty(D1.disseminationStatusTitle),
})
.min(1, { message: D.mandatoryProperty(D1.disseminationStatusTitle) }),
idSerie: z
.string({ required_error: D.mandatoryProperty(D1.generatedBy) })
.min(1, { message: D.mandatoryProperty(D1.generatedBy) }),
});

export const validate = ({ catalogRecord, ...otherFields }) =>
Expand Down
6 changes: 5 additions & 1 deletion src/js/applications/datasets/distributions/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ import { z } from 'zod';
import { formatValidation } from '../../../new-architecture/utils/validation';

const Distribution = z.object({
idDataset: z
.string({ required_error: D.mandatoryProperty(D1.datasetTitle) })
.min(1, { message: D.mandatoryProperty(D1.datasetTitle) }),
labelLg1: z
.string({ required_error: D.mandatoryProperty(D1.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D1.title) }),
labelLg2: z
.string({ required_error: D.mandatoryProperty(D2.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D2.title) }),
idDataset: z.string({ required_error: D.mandatoryProperty(D1.datasetTitle) }),
});

export const validate = formatValidation(Distribution);
24 changes: 18 additions & 6 deletions src/js/applications/operations/document/edition/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ import { z } from 'zod';
import { formatValidation } from '../../../../new-architecture/utils/validation';

const Base = z.object({
labelLg1: z.string().min(1, { message: D.mandatoryProperty(D1.title) }),
labelLg2: z.string().min(1, { message: D.mandatoryProperty(D2.title) }),
lang: z.string().min(1, { message: D.requiredLang }),
labelLg1: z
.string({ required_error: D.mandatoryProperty(D1.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D1.title) }),
labelLg2: z
.string({ required_error: D.mandatoryProperty(D2.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D2.title) }),
lang: z
.string({ required_error: D.requiredLang })
.min(1, { message: D.requiredLang }),
});

const Link = Base.extend({
Expand All @@ -29,9 +37,13 @@ const File = z.object({
});

const Document = Base.extend({
updatedDate: z.string({
required_error: D.requiredUpdatedDate,
}),
updatedDate: z
.string({
required_error: D.requiredUpdatedDate,
})
.min(1, { message: D.requiredUpdatedDate })
.nullable()
.refine((value) => value !== null, { message: D.requiredUpdatedDate }),
files: z.array(File).nonempty({
message: D.requiredFile,
}),
Expand Down
10 changes: 8 additions & 2 deletions src/js/applications/operations/families/edition/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import { z } from 'zod';
import { formatValidation } from '../../../../new-architecture/utils/validation';

const Family = z.object({
prefLabelLg1: z.string().min(1, { message: D.mandatoryProperty(D1.title) }),
prefLabelLg2: z.string().min(1, { message: D.mandatoryProperty(D2.title) }),
prefLabelLg1: z
.string({ required_error: D.mandatoryProperty(D1.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D1.title) }),
prefLabelLg2: z
.string({ required_error: D.mandatoryProperty(D2.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D2.title) }),
});

export const validate = formatValidation(Family);
10 changes: 8 additions & 2 deletions src/js/applications/operations/indicators/edition/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import { z } from 'zod';
import { formatValidation } from '../../../../new-architecture/utils/validation';

const Indicator = z.object({
prefLabelLg1: z.string().min(1, { message: D.mandatoryProperty(D1.title) }),
prefLabelLg2: z.string().min(1, { message: D.mandatoryProperty(D2.title) }),
prefLabelLg1: z
.string({ required_error: D.mandatoryProperty(D1.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D1.title) }),
prefLabelLg2: z
.string({ required_error: D.mandatoryProperty(D2.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D2.title) }),
creators: z
.string({
required_error: D.mandatoryProperty(D.creatorTitle),
Expand Down
10 changes: 8 additions & 2 deletions src/js/applications/operations/operations/edition/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { z } from 'zod';
import { formatValidation } from '../../../../new-architecture/utils/validation';

const Operation = z.object({
prefLabelLg1: z.string().min(1, { message: D.mandatoryProperty(D1.title) }),
prefLabelLg2: z.string().min(1, { message: D.mandatoryProperty(D2.title) }),
series: z.object(
{
id: z.string(),
Expand All @@ -13,6 +11,14 @@ const Operation = z.object({
required_error: D.mandatoryProperty(D1.seriesTitle),
}
),
prefLabelLg1: z
.string({ required_error: D.mandatoryProperty(D1.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D1.title) }),
prefLabelLg2: z
.string({ required_error: D.mandatoryProperty(D2.title) })
.trim()
.min(1, { message: D.mandatoryProperty(D2.title) }),
});

export const validate = formatValidation(Operation);
Loading

0 comments on commit 0cdf1c3

Please sign in to comment.