mirror of
https://github.com/strapi/strapi.git
synced 2026-01-04 11:16:32 +00:00
Entity validator tests
This commit is contained in:
parent
06923d2a49
commit
c4c570fe3b
@ -1,54 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
const strapiUtils = require('@strapi/utils');
|
||||
const {
|
||||
errors: { YupValidationError },
|
||||
} = require('@strapi/utils');
|
||||
const validators = require('../validators');
|
||||
import strapiUtils, { errors } from '@strapi/utils';
|
||||
import validators from '../validators';
|
||||
import type { Schema } from '../../../types';
|
||||
|
||||
describe('BigInteger validator', () => {
|
||||
const fakeModel: Schema.ContentType = {
|
||||
modelType: 'contentType',
|
||||
kind: 'collectionType',
|
||||
modelName: 'test-model',
|
||||
globalId: 'test-model',
|
||||
uid: 'api::test.test-uid',
|
||||
info: {
|
||||
displayName: 'Test model',
|
||||
singularName: 'test-model',
|
||||
pluralName: 'test-models',
|
||||
},
|
||||
options: {},
|
||||
attributes: {
|
||||
attrBigIntegerUnique: { type: 'biginteger', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
describe('unique', () => {
|
||||
const fakeFindOne = jest.fn();
|
||||
|
||||
global.strapi = {
|
||||
db: {
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
},
|
||||
};
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
fakeFindOne.mockReset();
|
||||
});
|
||||
|
||||
const fakeModel = {
|
||||
kind: 'contentType',
|
||||
modelName: 'test-model',
|
||||
uid: 'test-uid',
|
||||
options: {},
|
||||
attributes: {
|
||||
attrBigIntegerUnique: { type: 'biginteger', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
test('it does not validate the unique constraint if the attribute is not set as unique', async () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.biginteger(
|
||||
{
|
||||
attr: { type: 'biginteger' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 1,
|
||||
},
|
||||
entity: null,
|
||||
validators.biginteger({
|
||||
attr: { type: 'biginteger' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 1,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
await validator(1);
|
||||
@ -61,18 +59,15 @@ describe('BigInteger validator', () => {
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators
|
||||
.biginteger(
|
||||
{
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: null,
|
||||
},
|
||||
entity: null,
|
||||
.biginteger({
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
entity: null,
|
||||
})
|
||||
.nullable()
|
||||
);
|
||||
|
||||
@ -85,18 +80,15 @@ describe('BigInteger validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.biginteger(
|
||||
{
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 1,
|
||||
},
|
||||
entity: null,
|
||||
validators.biginteger({
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 1,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(1)).toBe(1);
|
||||
@ -107,24 +99,21 @@ describe('BigInteger validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrBigIntegerUnique: 2 });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.biginteger(
|
||||
{
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 2,
|
||||
},
|
||||
entity: null,
|
||||
validators.biginteger({
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 2,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator(2);
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
@ -132,18 +121,15 @@ describe('BigInteger validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrBigIntegerUnique: 3 });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.biginteger(
|
||||
{
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 3,
|
||||
},
|
||||
entity: { id: 1, attrBigIntegerUnique: 3 },
|
||||
validators.biginteger({
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 3,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
entity: { id: 1, attrBigIntegerUnique: 3 },
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(3)).toBe(3);
|
||||
@ -153,18 +139,15 @@ describe('BigInteger validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.biginteger(
|
||||
{
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 4,
|
||||
},
|
||||
entity: null,
|
||||
validators.biginteger({
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 4,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
await validator(4);
|
||||
@ -179,18 +162,15 @@ describe('BigInteger validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.biginteger(
|
||||
{
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 5,
|
||||
},
|
||||
entity: { id: 1, attrBigIntegerUnique: 42 },
|
||||
validators.biginteger({
|
||||
attr: { type: 'biginteger', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: {
|
||||
name: 'attrBigIntegerUnique',
|
||||
value: 5,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
entity: { id: 1, attrBigIntegerUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
await validator(5);
|
||||
@ -201,19 +181,4 @@ describe('BigInteger validator', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('min', () => {
|
||||
test('it does not validate the min constraint if the attribute min is not a number', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.biginteger(
|
||||
{
|
||||
attr: { type: 'biginteger', minLength: '123' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
expect(await validator(1)).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,51 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
const strapiUtils = require('@strapi/utils');
|
||||
const {
|
||||
errors: { YupValidationError },
|
||||
} = require('@strapi/utils');
|
||||
const validators = require('../validators');
|
||||
import strapiUtils, { errors } from '@strapi/utils';
|
||||
import validators from '../validators';
|
||||
import type { Schema } from '../../../types';
|
||||
|
||||
describe('Date validator', () => {
|
||||
const fakeModel: Schema.ContentType = {
|
||||
modelType: 'contentType',
|
||||
kind: 'collectionType',
|
||||
modelName: 'test-model',
|
||||
globalId: 'test-model',
|
||||
uid: 'api::test.test-uid',
|
||||
info: {
|
||||
displayName: 'Test model',
|
||||
singularName: 'test-model',
|
||||
pluralName: 'test-models',
|
||||
},
|
||||
options: {},
|
||||
attributes: {
|
||||
attrDateUnique: { type: 'date', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
describe('unique', () => {
|
||||
const fakeFindOne = jest.fn();
|
||||
|
||||
global.strapi = {
|
||||
db: {
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
},
|
||||
};
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
fakeFindOne.mockReset();
|
||||
});
|
||||
|
||||
const fakeModel = {
|
||||
kind: 'contentType',
|
||||
modelName: 'test-model',
|
||||
uid: 'test-uid',
|
||||
options: {},
|
||||
attributes: {
|
||||
attrDateUnique: { type: 'date', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
test('it does not validates the unique constraint if the attribute is not set as unique', async () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.date(
|
||||
{
|
||||
attr: { type: 'date' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.date({
|
||||
attr: { type: 'date' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
await validator('2021-11-29');
|
||||
@ -58,15 +56,12 @@ describe('Date validator', () => {
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators
|
||||
.date(
|
||||
{
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: null },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
.date({
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: null },
|
||||
entity: null,
|
||||
})
|
||||
.nullable()
|
||||
);
|
||||
|
||||
@ -78,15 +73,12 @@ describe('Date validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.date(
|
||||
{
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.date({
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator('2021-11-29')).toBe('2021-11-29');
|
||||
@ -97,21 +89,18 @@ describe('Date validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrDateUnique: '2021-11-29' });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.date(
|
||||
{
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.date({
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator('2021-11-29');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
@ -119,15 +108,12 @@ describe('Date validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrDateUnique: '2021-11-29' });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.date(
|
||||
{
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: { id: 1, attrDateUnique: '2021-11-29' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.date({
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: { id: 1, attrDateUnique: '2021-11-29' },
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator('2021-11-29')).toBe('2021-11-29');
|
||||
@ -137,15 +123,12 @@ describe('Date validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.date(
|
||||
{
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.date({
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
await validator('2021-11-29');
|
||||
@ -160,15 +143,12 @@ describe('Date validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.date(
|
||||
{
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: { id: 1, attrDateUnique: '2021-12-15' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.date({
|
||||
attr: { type: 'date', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateUnique', value: '2021-11-29' },
|
||||
entity: { id: 1, attrDateUnique: '2021-12-15' },
|
||||
})
|
||||
);
|
||||
|
||||
await validator('2021-11-29');
|
||||
@ -1,51 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
const strapiUtils = require('@strapi/utils');
|
||||
const {
|
||||
errors: { YupValidationError },
|
||||
} = require('@strapi/utils');
|
||||
const validators = require('../validators');
|
||||
import strapiUtils, { errors } from '@strapi/utils';
|
||||
import validators from '../validators';
|
||||
import type { Schema } from '../../../types';
|
||||
|
||||
describe('Datetime validator', () => {
|
||||
const fakeModel: Schema.ContentType = {
|
||||
modelType: 'contentType',
|
||||
kind: 'collectionType',
|
||||
modelName: 'test-model',
|
||||
globalId: 'test-model',
|
||||
uid: 'api::test.test-uid',
|
||||
info: {
|
||||
displayName: 'Test model',
|
||||
singularName: 'test-model',
|
||||
pluralName: 'test-models',
|
||||
},
|
||||
options: {},
|
||||
attributes: {
|
||||
attrDateTimeUnique: { type: 'datetime', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
describe('unique', () => {
|
||||
const fakeFindOne = jest.fn();
|
||||
|
||||
global.strapi = {
|
||||
db: {
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
},
|
||||
};
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
fakeFindOne.mockReset();
|
||||
});
|
||||
|
||||
const fakeModel = {
|
||||
kind: 'contentType',
|
||||
modelName: 'test-model',
|
||||
uid: 'test-uid',
|
||||
options: {},
|
||||
attributes: {
|
||||
attrDateTimeUnique: { type: 'datetime', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
test('it does not validates the unique constraint if the attribute is not set as unique', async () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.datetime(
|
||||
{
|
||||
attr: { type: 'datetime' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: { id: 1, attrDateTimeUnique: '2021-11-29T00:00:00.000Z' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.datetime({
|
||||
attr: { type: 'datetime' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: { id: 1, attrDateTimeUnique: '2021-11-29T00:00:00.000Z' },
|
||||
})
|
||||
);
|
||||
|
||||
await validator('2021-11-29T00:00:00.000Z');
|
||||
@ -58,15 +56,12 @@ describe('Datetime validator', () => {
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators
|
||||
.datetime(
|
||||
{
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: null },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
.datetime({
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: null },
|
||||
entity: null,
|
||||
})
|
||||
.nullable()
|
||||
);
|
||||
|
||||
@ -78,15 +73,12 @@ describe('Datetime validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.datetime(
|
||||
{
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.datetime({
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator('2021-11-29T00:00:00.000Z')).toBe('2021-11-29T00:00:00.000Z');
|
||||
@ -97,21 +89,18 @@ describe('Datetime validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrDateTimeUnique: '2021-11-29T00:00:00.000Z' });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.datetime(
|
||||
{
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.datetime({
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator('2021-11-29T00:00:00.000Z');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
@ -119,15 +108,12 @@ describe('Datetime validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrDateTimeUnique: '2021-11-29T00:00:00.000Z' });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.datetime(
|
||||
{
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: { id: 1, attrDateTimeUnique: '2021-11-29T00:00:00.000Z' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.datetime({
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: { id: 1, attrDateTimeUnique: '2021-11-29T00:00:00.000Z' },
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator('2021-11-29T00:00:00.000Z')).toBe('2021-11-29T00:00:00.000Z');
|
||||
@ -137,15 +123,12 @@ describe('Datetime validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.datetime(
|
||||
{
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.datetime({
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
await validator('2021-11-29T00:00:00.000Z');
|
||||
@ -160,15 +143,12 @@ describe('Datetime validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.datetime(
|
||||
{
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: { id: 1, attrDateTimeUnique: '2021-12-25T00:00:00.000Z' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.datetime({
|
||||
attr: { type: 'datetime', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrDateTimeUnique', value: '2021-11-29T00:00:00.000Z' },
|
||||
entity: { id: 1, attrDateTimeUnique: '2021-12-25T00:00:00.000Z' },
|
||||
})
|
||||
);
|
||||
|
||||
await validator('2021-11-29T00:00:00.000Z');
|
||||
@ -1,56 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const strapiUtils = require('@strapi/utils');
|
||||
const {
|
||||
errors: { YupValidationError },
|
||||
} = require('@strapi/utils');
|
||||
const validators = require('../validators');
|
||||
|
||||
describe('Email validator', () => {
|
||||
describe('email', () => {
|
||||
test('it fails the validation if the string is not a valid email', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.email(
|
||||
{
|
||||
attr: { type: 'email' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
await validator('invalid-email');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
test('it validates the email if it is valid', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.email(
|
||||
{
|
||||
attr: { type: 'email' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
expect(await validator('valid@email.com')).toBe('valid@email.com');
|
||||
});
|
||||
|
||||
test('it validates non-empty email required field', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.email({ attr: { type: 'email' } }, { isDraft: false })
|
||||
);
|
||||
|
||||
try {
|
||||
await validator('');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err.message).toBe('this cannot be empty');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,87 @@
|
||||
import strapiUtils, { errors } from '@strapi/utils';
|
||||
import validators from '../validators';
|
||||
import type { Schema } from '../../../types';
|
||||
|
||||
describe('Email validator', () => {
|
||||
const fakeModel: Schema.ContentType = {
|
||||
modelType: 'contentType',
|
||||
kind: 'collectionType',
|
||||
modelName: 'test-model',
|
||||
globalId: 'test-model',
|
||||
uid: 'api::test.test-uid',
|
||||
info: {
|
||||
displayName: 'Test model',
|
||||
singularName: 'test-model',
|
||||
pluralName: 'test-models',
|
||||
},
|
||||
options: {},
|
||||
attributes: {
|
||||
attrEmail: { type: 'email' },
|
||||
},
|
||||
};
|
||||
|
||||
describe('email', () => {
|
||||
test('it fails the validation if the string is not a valid email', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.email(
|
||||
{
|
||||
attr: { type: 'email' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrEmail', value: 1 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
await validator('invalid-email');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
test('it validates the email if it is valid', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.email(
|
||||
{
|
||||
attr: { type: 'email' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrEmail', value: 1 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
expect(await validator('valid@email.com')).toBe('valid@email.com');
|
||||
});
|
||||
|
||||
test('it validates non-empty email required field', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.email(
|
||||
{
|
||||
attr: { type: 'email' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrEmail', value: 1 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
expect.hasAssertions();
|
||||
|
||||
try {
|
||||
await validator('');
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
expect(err.message).toBe('this cannot be empty');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,43 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const strapiUtils = require('@strapi/utils');
|
||||
const {
|
||||
errors: { YupValidationError },
|
||||
} = require('@strapi/utils');
|
||||
const validators = require('../validators');
|
||||
|
||||
describe('Enumeration validator', () => {
|
||||
describe('oneOf', () => {
|
||||
test('it fails the validation if the value is not part of the allowed values', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.enumeration(
|
||||
{
|
||||
attr: { type: 'enum', enum: ['strapi', 'headless'] },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
await validator('invalid-vlue');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
test('it validates the value if it is part of the allowed values', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.enumeration(
|
||||
{
|
||||
attr: { type: 'enumeration', enum: ['strapi', 'headless'] },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
expect(await validator('strapi')).toBe('strapi');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,56 @@
|
||||
import strapiUtils, { errors } from '@strapi/utils';
|
||||
import validators from '../validators';
|
||||
import type { Schema } from '../../../types';
|
||||
|
||||
describe('Enumeration validator', () => {
|
||||
const fakeModel: Schema.ContentType = {
|
||||
modelType: 'contentType',
|
||||
kind: 'collectionType',
|
||||
modelName: 'test-model',
|
||||
globalId: 'test-model',
|
||||
uid: 'api::test.test-uid',
|
||||
info: {
|
||||
displayName: 'Test model',
|
||||
singularName: 'test-model',
|
||||
pluralName: 'test-models',
|
||||
},
|
||||
options: {},
|
||||
attributes: {
|
||||
attrEnumUnique: { type: 'float', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
describe('oneOf', () => {
|
||||
test('it fails the validation if the value is not part of the allowed values', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.enumeration({
|
||||
attr: { type: 'enumeration', enum: ['strapi', 'headless'] },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 1 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator('invalid-vlue');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
test('it validates the value if it is part of the allowed values', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.enumeration({
|
||||
attr: { type: 'enumeration', enum: ['strapi', 'headless'] },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrEnumUnique', value: 1 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator('strapi')).toBe('strapi');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,51 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
const strapiUtils = require('@strapi/utils');
|
||||
const {
|
||||
errors: { YupValidationError },
|
||||
} = require('@strapi/utils');
|
||||
const validators = require('../validators');
|
||||
import strapiUtils, { errors } from '@strapi/utils';
|
||||
import validators from '../validators';
|
||||
import type { Schema } from '../../../types';
|
||||
|
||||
describe('Float validator', () => {
|
||||
const fakeModel: Schema.ContentType = {
|
||||
modelType: 'contentType',
|
||||
kind: 'collectionType',
|
||||
modelName: 'test-model',
|
||||
globalId: 'test-model',
|
||||
uid: 'api::test.test-uid',
|
||||
info: {
|
||||
displayName: 'Test model',
|
||||
singularName: 'test-model',
|
||||
pluralName: 'test-models',
|
||||
},
|
||||
options: {},
|
||||
attributes: {
|
||||
attrFloatUnique: { type: 'float', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
describe('unique', () => {
|
||||
const fakeFindOne = jest.fn();
|
||||
|
||||
global.strapi = {
|
||||
db: {
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
},
|
||||
};
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
fakeFindOne.mockReset();
|
||||
});
|
||||
|
||||
const fakeModel = {
|
||||
kind: 'contentType',
|
||||
uid: 'test-uid',
|
||||
modelName: 'test-model',
|
||||
options: {},
|
||||
attributes: {
|
||||
attrFloatUnique: { type: 'float', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
test('it does not validates the unique constraint if the attribute is not set as unique', async () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 1 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 1 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
await validator(1);
|
||||
@ -58,15 +56,12 @@ describe('Float validator', () => {
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators
|
||||
.float(
|
||||
{
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: null },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
.float({
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: null },
|
||||
entity: null,
|
||||
})
|
||||
.nullable()
|
||||
);
|
||||
|
||||
@ -79,15 +74,12 @@ describe('Float validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 2 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 2 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(1)).toBe(1);
|
||||
@ -98,21 +90,18 @@ describe('Float validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrFloatUnique: 2 });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 2 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 2 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator(2);
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
@ -120,15 +109,12 @@ describe('Float validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrFloatUnique: 3 });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 3 },
|
||||
entity: { id: 1, attrFloatUnique: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 3 },
|
||||
entity: { id: 1, attrFloatUnique: 3 },
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(3)).toBe(3);
|
||||
@ -138,15 +124,12 @@ describe('Float validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 4 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 4 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
await validator(4);
|
||||
@ -161,15 +144,12 @@ describe('Float validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 5 },
|
||||
entity: { id: 1, attrFloatUnique: 42 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 5 },
|
||||
entity: { id: 1, attrFloatUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
await validator(5);
|
||||
@ -182,46 +162,33 @@ describe('Float validator', () => {
|
||||
});
|
||||
|
||||
describe('min', () => {
|
||||
test('it does not validates the min constraint if the attribute min is not a number', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', minLength: '123' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
expect(await validator(1)).toBe(1);
|
||||
});
|
||||
|
||||
test('it fails the validation if the float is lower than the define min', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', min: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float', min: 3 },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 5 },
|
||||
entity: { id: 1, attrFloatUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator(1);
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
test('it validates the min constraint if the float is higher than the define min', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', min: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float', min: 3 },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 5 },
|
||||
entity: { id: 1, attrFloatUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(4)).toBe(4);
|
||||
@ -229,46 +196,33 @@ describe('Float validator', () => {
|
||||
});
|
||||
|
||||
describe('max', () => {
|
||||
test('it does not validates the max constraint if the attribute max is not an float', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', maxLength: '123' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
expect(await validator(1)).toBe(1);
|
||||
});
|
||||
|
||||
test('it fails the validation if the number is float than the define max', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', max: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float', max: 3 },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 5 },
|
||||
entity: { id: 1, attrFloatUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator(4);
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
test('it validates the max constraint if the float is lower than the define max', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.float(
|
||||
{
|
||||
attr: { type: 'float', max: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.float({
|
||||
attr: { type: 'float', max: 3 },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrFloatUnique', value: 5 },
|
||||
entity: { id: 1, attrFloatUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(2)).toBe(2);
|
||||
@ -1,18 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
const entityValidator = require('..');
|
||||
import entityValidator from '..';
|
||||
import type { Schema } from '../../../types';
|
||||
|
||||
describe('Entity validator', () => {
|
||||
const modelBase = { uid: 'api::test.test' };
|
||||
const modelBase: Schema.ContentType = {
|
||||
modelType: 'contentType',
|
||||
uid: 'api::test.test',
|
||||
kind: 'collectionType',
|
||||
modelName: 'test',
|
||||
globalId: 'test',
|
||||
info: {
|
||||
displayName: 'Test',
|
||||
singularName: 'test',
|
||||
pluralName: 'tests',
|
||||
},
|
||||
options: {},
|
||||
attributes: {},
|
||||
};
|
||||
|
||||
describe('Published input', () => {
|
||||
describe('General Errors', () => {
|
||||
let model;
|
||||
let model: Schema.ContentType;
|
||||
global.strapi = {
|
||||
errors: {
|
||||
badRequest: jest.fn(),
|
||||
},
|
||||
getModel: () => model,
|
||||
};
|
||||
} as any;
|
||||
|
||||
it('Throws a badRequest error on invalid input', async () => {
|
||||
model = {
|
||||
@ -144,6 +157,7 @@ describe('Entity validator', () => {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
uuid: {
|
||||
// @ts-ignore
|
||||
type: 'uuid',
|
||||
},
|
||||
},
|
||||
@ -167,9 +181,9 @@ describe('Entity validator', () => {
|
||||
badRequest: jest.fn(),
|
||||
},
|
||||
getModel: () => model,
|
||||
};
|
||||
} as any;
|
||||
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -203,7 +217,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
test('Throws on max length not respected', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -237,7 +251,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
test('Allows empty strings even when required', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -256,7 +270,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
test('Assign default values', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -274,7 +288,7 @@ describe('Entity validator', () => {
|
||||
default: '2020-04-01T04:00:00.000Z',
|
||||
},
|
||||
testJSON: {
|
||||
type: 'date',
|
||||
type: 'json',
|
||||
required: true,
|
||||
default: {
|
||||
foo: 1,
|
||||
@ -296,7 +310,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
test("Don't assign default value if empty string", async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -332,9 +346,9 @@ describe('Entity validator', () => {
|
||||
badRequest: jest.fn(),
|
||||
},
|
||||
getModel: () => model,
|
||||
};
|
||||
} as any;
|
||||
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -367,7 +381,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
it('Returns data on valid input', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -385,7 +399,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
it('Returns casted data when possible', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -409,7 +423,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
test('Does not throws on required not respected', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -433,10 +447,11 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
it('Supports custom field types', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
uuid: {
|
||||
// @ts-ignore
|
||||
type: 'uuid',
|
||||
},
|
||||
},
|
||||
@ -455,7 +470,7 @@ describe('Entity validator', () => {
|
||||
|
||||
describe('String validator', () => {
|
||||
test('Does not throws on min length not respected', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -470,7 +485,7 @@ describe('Entity validator', () => {
|
||||
badRequest: jest.fn(),
|
||||
},
|
||||
getModel: () => model,
|
||||
};
|
||||
} as any;
|
||||
|
||||
const input = { title: 'tooSmall' };
|
||||
|
||||
@ -481,7 +496,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
test('Throws on max length not respected', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -515,7 +530,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
test('Allows empty strings even when required', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -533,7 +548,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
test('Assign default values', async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -551,7 +566,7 @@ describe('Entity validator', () => {
|
||||
default: '2020-04-01T04:00:00.000Z',
|
||||
},
|
||||
testJSON: {
|
||||
type: 'date',
|
||||
type: 'json',
|
||||
required: true,
|
||||
default: {
|
||||
foo: 1,
|
||||
@ -575,7 +590,7 @@ describe('Entity validator', () => {
|
||||
});
|
||||
|
||||
test("Don't assign default value if empty string", async () => {
|
||||
const model = {
|
||||
const model: Schema.ContentType = {
|
||||
...modelBase,
|
||||
attributes: {
|
||||
title: {
|
||||
@ -1,51 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
const strapiUtils = require('@strapi/utils');
|
||||
const {
|
||||
errors: { YupValidationError },
|
||||
} = require('@strapi/utils');
|
||||
const validators = require('../validators');
|
||||
import strapiUtils, { errors } from '@strapi/utils';
|
||||
import validators from '../validators';
|
||||
import type { Schema } from '../../../types';
|
||||
|
||||
describe('Integer validator', () => {
|
||||
const fakeModel: Schema.ContentType = {
|
||||
modelType: 'contentType',
|
||||
kind: 'collectionType',
|
||||
modelName: 'test-model',
|
||||
globalId: 'test-model',
|
||||
uid: 'api::test.test-uid',
|
||||
info: {
|
||||
displayName: 'Test model',
|
||||
singularName: 'test-model',
|
||||
pluralName: 'test-models',
|
||||
},
|
||||
options: {},
|
||||
attributes: {
|
||||
attrIntegerUnique: { type: 'integer', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
describe('unique', () => {
|
||||
const fakeFindOne = jest.fn();
|
||||
|
||||
global.strapi = {
|
||||
db: {
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
},
|
||||
};
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
fakeFindOne.mockReset();
|
||||
});
|
||||
|
||||
const fakeModel = {
|
||||
kind: 'contentType',
|
||||
uid: 'test-uid',
|
||||
modelName: 'test-model',
|
||||
options: {},
|
||||
attributes: {
|
||||
attrIntegerUnique: { type: 'integer', unique: true },
|
||||
},
|
||||
};
|
||||
|
||||
test('it does not validates the unique constraint if the attribute is not set as unique', async () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 1 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer' },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 1 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
await validator(1);
|
||||
@ -58,15 +56,12 @@ describe('Integer validator', () => {
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators
|
||||
.integer(
|
||||
{
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: null },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
.integer({
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: null },
|
||||
entity: null,
|
||||
})
|
||||
.nullable()
|
||||
);
|
||||
|
||||
@ -79,15 +74,12 @@ describe('Integer validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 2 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 2 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(1)).toBe(1);
|
||||
@ -98,21 +90,18 @@ describe('Integer validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrIntegerUnique: 2 });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 2 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 2 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator(2);
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
@ -120,15 +109,12 @@ describe('Integer validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce({ attrIntegerUnique: 3 });
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 3 },
|
||||
entity: { id: 1, attrIntegerUnique: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 3 },
|
||||
entity: { id: 1, attrIntegerUnique: 3 },
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(3)).toBe(3);
|
||||
@ -138,15 +124,12 @@ describe('Integer validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 4 },
|
||||
entity: null,
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 4 },
|
||||
entity: null,
|
||||
})
|
||||
);
|
||||
|
||||
await validator(4);
|
||||
@ -161,15 +144,12 @@ describe('Integer validator', () => {
|
||||
fakeFindOne.mockResolvedValueOnce(null);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 5 },
|
||||
entity: { id: 1, attrIntegerUnique: 42 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer', unique: true },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 5 },
|
||||
entity: { id: 1, attrIntegerUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
await validator(5);
|
||||
@ -182,46 +162,33 @@ describe('Integer validator', () => {
|
||||
});
|
||||
|
||||
describe('min', () => {
|
||||
test('it does not validates the min constraint if the attribute min is not a number', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', minLength: '123' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
expect(await validator(1)).toBe(1);
|
||||
});
|
||||
|
||||
test('it fails the validation if the integer is lower than the define min', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', min: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer', min: 3 },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 5 },
|
||||
entity: { id: 1, attrIntegerUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator(1);
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
test('it validates the min constraint if the integer is higher than the define min', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', min: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer', min: 3 },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 5 },
|
||||
entity: { id: 1, attrIntegerUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(4)).toBe(4);
|
||||
@ -229,46 +196,33 @@ describe('Integer validator', () => {
|
||||
});
|
||||
|
||||
describe('max', () => {
|
||||
test('it does not validates the max constraint if the attribute max is not an integer', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', maxLength: '123' },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
);
|
||||
|
||||
expect(await validator(1)).toBe(1);
|
||||
});
|
||||
|
||||
test('it fails the validation if the number is integer than the define max', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', max: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer', max: 3 },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 5 },
|
||||
entity: { id: 1, attrIntegerUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
try {
|
||||
await validator(4);
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(YupValidationError);
|
||||
expect(err).toBeInstanceOf(errors.YupValidationError);
|
||||
}
|
||||
});
|
||||
|
||||
test('it validates the max constraint if the integer is lower than the define max', async () => {
|
||||
const validator = strapiUtils.validateYupSchema(
|
||||
validators.integer(
|
||||
{
|
||||
attr: { type: 'integer', max: 3 },
|
||||
},
|
||||
{ isDraft: false }
|
||||
)
|
||||
validators.integer({
|
||||
attr: { type: 'integer', max: 3 },
|
||||
model: fakeModel,
|
||||
updatedAttribute: { name: 'attrIntegerUnique', value: 5 },
|
||||
entity: { id: 1, attrIntegerUnique: 42 },
|
||||
})
|
||||
);
|
||||
|
||||
expect(await validator(2)).toBe(2);
|
||||
@ -1,38 +1,36 @@
|
||||
'use strict';
|
||||
import { errors } from '@strapi/utils';
|
||||
|
||||
const { ValidationError } = require('@strapi/utils').errors;
|
||||
|
||||
const entityValidator = require('../..');
|
||||
const { models, existentIDs, nonExistentIds } = require('./utils/relations.testdata');
|
||||
import entityValidator from '../..';
|
||||
import { models, existentIDs, nonExistentIds } from './utils/relations.testdata';
|
||||
import type * as Types from '../../../entity-service/types';
|
||||
import type { Common } from '../../../../types';
|
||||
|
||||
/**
|
||||
* Test that relations can be successfully validated and non existent relations
|
||||
* can be detected at the Attribute level.
|
||||
*/
|
||||
describe('Entity validator | Relations | Attribute', () => {
|
||||
const strapi = {
|
||||
global.strapi = {
|
||||
components: {
|
||||
'basic.dev-compo': {},
|
||||
},
|
||||
db: {
|
||||
query() {
|
||||
return {
|
||||
count: ({
|
||||
where: {
|
||||
id: { $in },
|
||||
},
|
||||
}) => existentIDs.filter((value) => $in.includes(value)).length,
|
||||
};
|
||||
},
|
||||
query() {
|
||||
return {
|
||||
count: ({
|
||||
where: {
|
||||
id: { $in },
|
||||
},
|
||||
}: any) => existentIDs.filter((value) => $in.includes(value)).length,
|
||||
};
|
||||
},
|
||||
errors: {
|
||||
badRequest: jest.fn(),
|
||||
},
|
||||
getModel: (uid) => models.get(uid),
|
||||
};
|
||||
getModel: (uid: string) => models.get(uid),
|
||||
} as any;
|
||||
|
||||
describe('Success', () => {
|
||||
const testData = [
|
||||
const testData: Array<[string, Types.Params.Data.Input<Common.UID.ContentType>]> = [
|
||||
[
|
||||
'Connect',
|
||||
{
|
||||
@ -71,8 +69,8 @@ describe('Entity validator | Relations | Attribute', () => {
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
test.each(testData)('%s', async (__, input = {}) => {
|
||||
global.strapi = strapi;
|
||||
const res = entityValidator.validateEntityCreation(models.get('api::dev.dev'), input, {
|
||||
isDraft: true,
|
||||
});
|
||||
@ -81,10 +79,10 @@ describe('Entity validator | Relations | Attribute', () => {
|
||||
});
|
||||
|
||||
describe('Error', () => {
|
||||
const expectError = new ValidationError(
|
||||
const expectError = new errors.ValidationError(
|
||||
`2 relation(s) of type api::category.category associated with this entity do not exist`
|
||||
);
|
||||
const testData = [
|
||||
const testData: Array<[string, Types.Params.Data.Input<Common.UID.ContentType>]> = [
|
||||
[
|
||||
'Connect',
|
||||
{
|
||||
@ -113,7 +111,6 @@ describe('Entity validator | Relations | Attribute', () => {
|
||||
];
|
||||
|
||||
test.each(testData)('%s', async (__, input = {}) => {
|
||||
global.strapi = strapi;
|
||||
const res = entityValidator.validateEntityCreation(models.get('api::dev.dev'), input, {
|
||||
isDraft: true,
|
||||
});
|
||||
@ -1,35 +1,33 @@
|
||||
'use strict';
|
||||
import { errors } from '@strapi/utils';
|
||||
|
||||
const { ValidationError } = require('@strapi/utils').errors;
|
||||
|
||||
const entityValidator = require('../..');
|
||||
const { models, nonExistentIds, existentIDs } = require('./utils/relations.testdata');
|
||||
import entityValidator from '../..';
|
||||
import { models, existentIDs, nonExistentIds } from './utils/relations.testdata';
|
||||
|
||||
/**
|
||||
* Test that relations can be successfully validated and non existent relations
|
||||
* can be detected at the Component level.
|
||||
*/
|
||||
describe('Entity validator | Relations | Component Level', () => {
|
||||
const strapi = {
|
||||
global.strapi = {
|
||||
components: {
|
||||
'basic.dev-compo': {},
|
||||
},
|
||||
db: {
|
||||
query() {
|
||||
return {
|
||||
count: ({
|
||||
where: {
|
||||
id: { $in },
|
||||
},
|
||||
}) => existentIDs.filter((value) => $in.includes(value)).length,
|
||||
};
|
||||
},
|
||||
|
||||
query() {
|
||||
return {
|
||||
count: ({
|
||||
where: {
|
||||
id: { $in },
|
||||
},
|
||||
}: any) => existentIDs.filter((value) => $in.includes(value)).length,
|
||||
};
|
||||
},
|
||||
|
||||
errors: {
|
||||
badRequest: jest.fn(),
|
||||
},
|
||||
getModel: (uid) => models.get(uid),
|
||||
};
|
||||
getModel: (uid: string) => models.get(uid),
|
||||
} as any;
|
||||
|
||||
describe('Single Component', () => {
|
||||
describe('Success', () => {
|
||||
@ -82,7 +80,6 @@ describe('Entity validator | Relations | Component Level', () => {
|
||||
];
|
||||
|
||||
test.each(testData)('%s', async (__, input = {}) => {
|
||||
global.strapi = strapi;
|
||||
const res = entityValidator.validateEntityCreation(models.get('api::dev.dev'), input, {
|
||||
isDraft: true,
|
||||
});
|
||||
@ -91,7 +88,7 @@ describe('Entity validator | Relations | Component Level', () => {
|
||||
});
|
||||
|
||||
describe('Error', () => {
|
||||
const expectedError = new ValidationError(
|
||||
const expectedError = new errors.ValidationError(
|
||||
`1 relation(s) of type api::category.category associated with this entity do not exist`
|
||||
);
|
||||
const testData = [
|
||||
@ -218,7 +215,7 @@ describe('Entity validator | Relations | Component Level', () => {
|
||||
});
|
||||
|
||||
describe('Error', () => {
|
||||
const expectedError = new ValidationError(
|
||||
const expectedError = new errors.ValidationError(
|
||||
`4 relation(s) of type api::category.category associated with this entity do not exist`
|
||||
);
|
||||
const testData = [
|
||||
@ -264,7 +261,6 @@ describe('Entity validator | Relations | Component Level', () => {
|
||||
];
|
||||
|
||||
test.each(testData)('%s', async (__, input = {}) => {
|
||||
global.strapi = strapi;
|
||||
const res = entityValidator.validateEntityCreation(models.get('api::dev.dev'), input, {
|
||||
isDraft: true,
|
||||
});
|
||||
@ -1,35 +1,29 @@
|
||||
'use strict';
|
||||
import { errors } from '@strapi/utils';
|
||||
|
||||
const { ValidationError } = require('@strapi/utils').errors;
|
||||
|
||||
const entityValidator = require('../..');
|
||||
const { models, nonExistentIds, existentIDs } = require('./utils/relations.testdata');
|
||||
import entityValidator from '../..';
|
||||
import { models, existentIDs, nonExistentIds } from './utils/relations.testdata';
|
||||
|
||||
/**
|
||||
* Test that relations can be successfully validated and non existent relations
|
||||
* can be detected at the Dynamic Zone level.
|
||||
*/
|
||||
describe('Entity validator | Relations | Dynamic Zone', () => {
|
||||
const strapi = {
|
||||
global.strapi = {
|
||||
components: {
|
||||
'basic.dev-compo': {},
|
||||
},
|
||||
db: {
|
||||
query() {
|
||||
return {
|
||||
count: ({
|
||||
where: {
|
||||
id: { $in },
|
||||
},
|
||||
}) => existentIDs.filter((value) => $in.includes(value)).length,
|
||||
};
|
||||
},
|
||||
query() {
|
||||
return {
|
||||
count: ({
|
||||
where: {
|
||||
id: { $in },
|
||||
},
|
||||
}: any) => existentIDs.filter((value) => $in.includes(value)).length,
|
||||
};
|
||||
},
|
||||
errors: {
|
||||
badRequest: jest.fn(),
|
||||
},
|
||||
getModel: (uid) => models.get(uid),
|
||||
};
|
||||
errors: { badRequest: jest.fn() },
|
||||
getModel: (uid: string) => models.get(uid),
|
||||
} as any;
|
||||
|
||||
describe('Success', () => {
|
||||
const testData = [
|
||||
@ -89,7 +83,6 @@ describe('Entity validator | Relations | Dynamic Zone', () => {
|
||||
];
|
||||
|
||||
test.each(testData)('%s', async (__, input = {}) => {
|
||||
global.strapi = strapi;
|
||||
const res = entityValidator.validateEntityCreation(models.get('api::dev.dev'), input, {
|
||||
isDraft: true,
|
||||
});
|
||||
@ -98,7 +91,7 @@ describe('Entity validator | Relations | Dynamic Zone', () => {
|
||||
});
|
||||
|
||||
describe('Error', () => {
|
||||
const expectedError = new ValidationError(
|
||||
const expectedError = new errors.ValidationError(
|
||||
`2 relation(s) of type api::category.category associated with this entity do not exist`
|
||||
);
|
||||
const testData = [
|
||||
@ -149,7 +142,6 @@ describe('Entity validator | Relations | Dynamic Zone', () => {
|
||||
];
|
||||
|
||||
test.each(testData)('%s', async (__, input = {}) => {
|
||||
global.strapi = strapi;
|
||||
const res = entityValidator.validateEntityCreation(models.get('api::dev.dev'), input, {
|
||||
isDraft: true,
|
||||
});
|
||||
@ -1,38 +1,33 @@
|
||||
'use strict';
|
||||
import { errors } from '@strapi/utils';
|
||||
|
||||
const { ValidationError } = require('@strapi/utils').errors;
|
||||
|
||||
const entityValidator = require('../..');
|
||||
const { models, existentIDs, nonExistentIds } = require('./utils/relations.testdata');
|
||||
import entityValidator from '../..';
|
||||
import { models, existentIDs, nonExistentIds } from './utils/relations.testdata';
|
||||
|
||||
/**
|
||||
* Test that relations can be successfully validated and non existent relations
|
||||
* can be detected at the Media level.
|
||||
*/
|
||||
describe('Entity validator | Relations | Media', () => {
|
||||
const strapi = {
|
||||
global.strapi = {
|
||||
components: {
|
||||
'basic.dev-compo': {},
|
||||
},
|
||||
db: {
|
||||
query() {
|
||||
return {
|
||||
count: ({
|
||||
where: {
|
||||
id: { $in },
|
||||
},
|
||||
}) => existentIDs.filter((value) => $in.includes(value)).length,
|
||||
};
|
||||
},
|
||||
query() {
|
||||
return {
|
||||
count: ({
|
||||
where: {
|
||||
id: { $in },
|
||||
},
|
||||
}: any) => existentIDs.filter((value) => $in.includes(value)).length,
|
||||
};
|
||||
},
|
||||
errors: {
|
||||
badRequest: jest.fn(),
|
||||
},
|
||||
getModel: (uid) => models.get(uid),
|
||||
};
|
||||
getModel: (uid: string) => models.get(uid),
|
||||
} as any;
|
||||
|
||||
it('Success', async () => {
|
||||
global.strapi = strapi;
|
||||
const input = {
|
||||
media: [
|
||||
{
|
||||
@ -49,8 +44,7 @@ describe('Entity validator | Relations | Media', () => {
|
||||
});
|
||||
|
||||
it('Error', async () => {
|
||||
global.strapi = strapi;
|
||||
const expectedError = new ValidationError(
|
||||
const expectedError = new errors.ValidationError(
|
||||
`1 relation(s) of type plugin::upload.file associated with this entity do not exist`
|
||||
);
|
||||
const input = {
|
||||
@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
export const models = new Map();
|
||||
|
||||
const models = new Map();
|
||||
models.set('api::dev.dev', {
|
||||
kind: 'collectionType',
|
||||
collectionName: 'devs',
|
||||
@ -146,8 +145,5 @@ models.set('plugin::upload.file', {
|
||||
globalId: 'UploadFile',
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
models,
|
||||
existentIDs: [1, 2, 3, 4, 5, 6],
|
||||
nonExistentIds: [10, 11, 12, 13, 14, 15, 16],
|
||||
};
|
||||
export const existentIDs = [1, 2, 3, 4, 5, 6];
|
||||
export const nonExistentIds = [10, 11, 12, 13, 14, 15, 16];
|
||||
@ -26,7 +26,7 @@ describe('String validator', () => {
|
||||
global.strapi = {
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})) as any,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@ -9,7 +9,7 @@ describe('Time validator', () => {
|
||||
global.strapi = {
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})) as any,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@ -10,7 +10,7 @@ describe('Time validator', () => {
|
||||
global.strapi = {
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})) as any,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@ -9,7 +9,7 @@ describe('UID validator', () => {
|
||||
global.strapi = {
|
||||
query: jest.fn(() => ({
|
||||
findOne: fakeFindOne,
|
||||
})) as any,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
*/
|
||||
|
||||
import { uniqBy, castArray, isNil, isArray, mergeWith } from 'lodash';
|
||||
import { has, assoc, prop, isObject, isEmpty } from 'lodash/fp';
|
||||
import { has, prop, isObject, isEmpty } from 'lodash/fp';
|
||||
import strapiUtils from '@strapi/utils';
|
||||
import * as validators from './validators';
|
||||
import validators from './validators';
|
||||
import { Common, Schema, Attribute, UID, Shared } from '../../types';
|
||||
import * as Types from '../entity-service/types';
|
||||
import type * as Types from '../entity-service/types';
|
||||
|
||||
type CreateOrUpdate = 'creation' | 'update';
|
||||
|
||||
@ -27,7 +27,7 @@ type RelationSource = string | number | ID;
|
||||
|
||||
interface ValidatorMeta<TAttribute = Attribute.Any> {
|
||||
attr: TAttribute;
|
||||
updatedAttribute: { name: string; value: unknown };
|
||||
updatedAttribute: { name: string; value: any };
|
||||
}
|
||||
|
||||
interface ValidatorContext {
|
||||
@ -79,6 +79,7 @@ const addRequiredValidation = (createOrUpdate: CreateOrUpdate) => {
|
||||
{ attr: { required } }: ValidatorMeta<Partial<Attribute.Any & Attribute.RequiredOption>>
|
||||
): T => {
|
||||
let nextValidator = validator;
|
||||
|
||||
if (required) {
|
||||
if (createOrUpdate === 'creation') {
|
||||
nextValidator = nextValidator.notNil();
|
||||
@ -152,9 +153,10 @@ const createComponentValidator =
|
||||
}
|
||||
|
||||
// FIXME: v4 was broken
|
||||
let validator = yup.lazy((item) =>
|
||||
createModelValidator(createOrUpdate)({ model, data: item }, { isDraft })
|
||||
) as any;
|
||||
let validator = createModelValidator(createOrUpdate)(
|
||||
{ model, data: updatedAttribute.value },
|
||||
{ isDraft }
|
||||
);
|
||||
|
||||
validator = addRequiredValidation(createOrUpdate)(validator, {
|
||||
attr: { required: !isDraft && attr.required },
|
||||
@ -239,7 +241,7 @@ const createScalarAttributeValidator =
|
||||
const createAttributeValidator =
|
||||
(createOrUpdate: CreateOrUpdate) =>
|
||||
(metas: AttributeValidatorMetas, options: ValidatorContext) => {
|
||||
let validator: strapiUtils.yup.BaseSchema = yup.mixed();
|
||||
let validator = yup.mixed();
|
||||
|
||||
if (isMediaAttribute(metas.attr)) {
|
||||
validator = yup.mixed();
|
||||
@ -277,17 +279,18 @@ const createModelValidator =
|
||||
const writableAttributes = model ? getWritableAttributes(model) : [];
|
||||
|
||||
const schema = writableAttributes.reduce((validators, attributeName) => {
|
||||
const validator = createAttributeValidator(createOrUpdate)(
|
||||
{
|
||||
attr: model.attributes[attributeName],
|
||||
updatedAttribute: { name: attributeName, value: prop(attributeName, data) },
|
||||
model,
|
||||
entity,
|
||||
},
|
||||
options
|
||||
);
|
||||
const metas = {
|
||||
attr: model.attributes[attributeName],
|
||||
updatedAttribute: { name: attributeName, value: prop(attributeName, data) },
|
||||
model,
|
||||
entity,
|
||||
};
|
||||
|
||||
return assoc(attributeName, validator)(validators);
|
||||
const validator = createAttributeValidator(createOrUpdate)(metas, options);
|
||||
|
||||
validators[attributeName] = validator;
|
||||
|
||||
return validators;
|
||||
}, {} as Record<string, strapiUtils.yup.BaseSchema>);
|
||||
|
||||
return yup.object().shape(schema);
|
||||
@ -384,9 +387,13 @@ const buildRelationsStore = ({
|
||||
if (Array.isArray(value)) {
|
||||
source = value;
|
||||
} else if (isObject(value)) {
|
||||
source = castArray(
|
||||
('connect' in value && value.connect) ?? ('set' in value && value.set) ?? []
|
||||
) as RelationSource[];
|
||||
if ('connect' in value && !isNil(value.connect)) {
|
||||
source = value.connect as RelationSource[];
|
||||
} else if ('set' in value && !isNil(value.set)) {
|
||||
source = value.set as RelationSource[];
|
||||
} else {
|
||||
source = [];
|
||||
}
|
||||
} else {
|
||||
source = castArray(value as RelationSource);
|
||||
}
|
||||
|
||||
@ -8,7 +8,8 @@ export type BigInteger = Attribute.OfType<'biginteger'> &
|
||||
Attribute.PrivateOption &
|
||||
Attribute.RequiredOption &
|
||||
Attribute.WritableOption &
|
||||
Attribute.VisibleOption;
|
||||
Attribute.VisibleOption &
|
||||
Attribute.UniqueOption;
|
||||
|
||||
export type BigIntegerValue = string;
|
||||
|
||||
|
||||
@ -8,7 +8,8 @@ export type Decimal = Attribute.OfType<'decimal'> &
|
||||
Attribute.PrivateOption &
|
||||
Attribute.RequiredOption &
|
||||
Attribute.WritableOption &
|
||||
Attribute.VisibleOption;
|
||||
Attribute.VisibleOption &
|
||||
Attribute.UniqueOption;
|
||||
|
||||
export type DecimalValue = number;
|
||||
|
||||
|
||||
@ -8,7 +8,8 @@ export type Float = Attribute.OfType<'float'> &
|
||||
Attribute.PrivateOption &
|
||||
Attribute.RequiredOption &
|
||||
Attribute.WritableOption &
|
||||
Attribute.VisibleOption;
|
||||
Attribute.VisibleOption &
|
||||
Attribute.UniqueOption;
|
||||
|
||||
export type FloatValue = number;
|
||||
|
||||
|
||||
@ -8,7 +8,8 @@ export type Integer = Attribute.OfType<'integer'> &
|
||||
Attribute.PrivateOption &
|
||||
Attribute.RequiredOption &
|
||||
Attribute.WritableOption &
|
||||
Attribute.VisibleOption;
|
||||
Attribute.VisibleOption &
|
||||
Attribute.UniqueOption;
|
||||
|
||||
export type IntegerValue = number;
|
||||
|
||||
|
||||
@ -6,7 +6,8 @@ export type JSON = Attribute.OfType<'json'> &
|
||||
Attribute.RequiredOption &
|
||||
Attribute.PrivateOption &
|
||||
Attribute.WritableOption &
|
||||
Attribute.VisibleOption;
|
||||
Attribute.VisibleOption &
|
||||
Attribute.DefaultOption<JsonValue>;
|
||||
|
||||
export type JsonValue<T extends object = object> = T;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user