Merge pull request #5345 from strapi/fix/enum-duplicate

Add validations for duplicate enums
This commit is contained in:
Alexandre BODIN 2020-02-27 18:47:38 +01:00 committed by GitHub
commit c39447c8b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 20 deletions

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import getTrad from '../../../utils/getTrad'
import getTrad from '../../../utils/getTrad';
import OptionsWrapper from './wrapper';
import Option from './Option';
import OptionsTitle from './OptionsTitle';

View File

@ -215,6 +215,15 @@ const forms = {
.array()
.of(yup.string())
.min(1, errorsTrads.min)
.test({
name: 'areEnumValuesUnique',
message: getTrad('error.validation.enum-duplicate'),
test: values => {
const filtered = [...new Set(values)];
return filtered.length === values.length;
},
})
.matchesEnumRegex(errorsTrads.regex)
.hasNotEmptyValues('Empty strings are not allowed', dataToValidate.enum),
enumName: yup.string().nullable(),

View File

@ -48,6 +48,7 @@
"contentType.kind.change.warning": "You just changed the kind of a content type: API will be reset (routes, controllers, and services will be overwritten).",
"contentType.UID.description": "The UID is used to generate the API routes and databases tables/collections",
"error.contentTypeName.reserved-name": "This name cannot be used in your project as it might break other functionalities",
"error.validation.enum-duplicate": "Duplicate values are not allowed",
"error.validation.minSupMax": "Can't be superior",
"error.validation.relation.targetAttribute-taken": "This name exists in the target",
"form.attribute.component.option.add": "Add a component",

View File

@ -64,9 +64,19 @@ const isValidEnum = {
test: val => val === '' || ENUM_REGEX.test(val),
};
const areEnumValuesUnique = {
name: 'areEnumValuesUnique',
message: '${path} cannot contain duplicate values',
test: values => {
const filtered = [...new Set(values)];
return filtered.length === values.length;
},
};
module.exports = {
validators,
areEnumValuesUnique,
isValidCollectionName,
isValidCategoryName,
isValidName,

View File

@ -5,6 +5,7 @@ const yup = require('yup');
const {
validators,
areEnumValuesUnique,
isValidName,
isValidEnum,
isValidUID,
@ -17,11 +18,7 @@ const maxLengthIsGreaterThanOrEqualToMinLength = {
message: 'maxLength must be greater or equal to minLength',
test: function(value) {
const { minLength } = this.parent;
if (
!_.isUndefined(minLength) &&
!_.isUndefined(value) &&
value < minLength
) {
if (!_.isUndefined(minLength) && !_.isUndefined(value) && value < minLength) {
return false;
}
@ -82,9 +79,7 @@ const getTypeShape = (attribute, { modelType, attributes } = {}) => {
)
.test(isValidUID),
minLength: validators.minLength,
maxLength: validators.maxLength
.max(256)
.test(maxLengthIsGreaterThanOrEqualToMinLength),
maxLength: validators.maxLength.max(256).test(maxLengthIsGreaterThanOrEqualToMinLength),
};
}
@ -126,10 +121,9 @@ const getTypeShape = (attribute, { modelType, attributes } = {}) => {
.required()
)
.min(1)
.test(areEnumValuesUnique)
.required(),
default: yup
.string()
.when('enum', enumVal => yup.string().oneOf(enumVal)),
default: yup.string().when('enum', enumVal => yup.string().oneOf(enumVal)),
enumName: yup.string().test(isValidName),
required: validators.required,
unique: validators.unique,
@ -225,10 +219,7 @@ const getTypeShape = (attribute, { modelType, attributes } = {}) => {
const targetCompo = strapi.components[compoUID];
if (!targetCompo) return true; // ignore this error as it will fail beforehand
if (
modelType === modelTypes.COMPONENT &&
hasComponent(targetCompo)
) {
if (modelType === modelTypes.COMPONENT && hasComponent(targetCompo)) {
return this.createError({
path: this.path,
message: `${targetCompo.modelName} already as a nested compoent. You cannot have more than one level of nesting inside your components.`,
@ -249,9 +240,7 @@ const getTypeShape = (attribute, { modelType, attributes } = {}) => {
components: yup
.array()
.of(yup.string().required())
.test('isArray', '${path} must be an array', value =>
Array.isArray(value)
),
.test('isArray', '${path} must be an array', value => Array.isArray(value)),
min: yup.number(),
max: yup.number(),
};