mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 07:03:38 +00:00
Apply feedbacks
Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
parent
25d541c2d9
commit
04c85dd218
@ -4,7 +4,7 @@ const createContext = require('../../../../test/helpers/create-context');
|
||||
const singleTypes = require('../single-types');
|
||||
|
||||
describe('Single Types', () => {
|
||||
test('find', async () => {
|
||||
test('Successfull find', async () => {
|
||||
const state = {
|
||||
userAbility: {
|
||||
can: jest.fn(),
|
||||
@ -73,4 +73,390 @@ describe('Single Types', () => {
|
||||
expect(permissionChecker.cannot.create).toHaveBeenCalled();
|
||||
expect(notFound).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Successfull create', async () => {
|
||||
const modelUid = 'test-uid';
|
||||
|
||||
const state = {
|
||||
userAbility: {
|
||||
can: jest.fn(),
|
||||
cannot: jest.fn(() => false),
|
||||
},
|
||||
user: {
|
||||
id: 1,
|
||||
},
|
||||
};
|
||||
|
||||
const createPermissionsManager = jest.fn(() => ({
|
||||
ability: state.userAbility,
|
||||
}));
|
||||
|
||||
const permissionChecker = {
|
||||
cannot: {
|
||||
update: jest.fn(() => false),
|
||||
create: jest.fn(() => false),
|
||||
},
|
||||
sanitizeCreateInput: obj => obj,
|
||||
sanitizeOutput: obj => obj,
|
||||
};
|
||||
|
||||
const createFn = jest.fn(() => ({}));
|
||||
const sendTelemetry = jest.fn(() => ({}));
|
||||
|
||||
global.strapi = {
|
||||
admin: {
|
||||
services: {
|
||||
permission: {
|
||||
createPermissionsManager,
|
||||
},
|
||||
},
|
||||
},
|
||||
getModel() {
|
||||
return {
|
||||
options: {
|
||||
draftAndPublish: true,
|
||||
},
|
||||
attributes: {
|
||||
title: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
plugins: {
|
||||
'content-manager': {
|
||||
services: {
|
||||
'entity-manager': {
|
||||
find() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
assocCreatorRoles(enitty) {
|
||||
return enitty;
|
||||
},
|
||||
create: createFn,
|
||||
},
|
||||
'permission-checker': {
|
||||
create() {
|
||||
return permissionChecker;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
entityService: {
|
||||
find: jest.fn(),
|
||||
},
|
||||
telemetry: {
|
||||
send: sendTelemetry,
|
||||
},
|
||||
};
|
||||
|
||||
const ctx = createContext(
|
||||
{
|
||||
params: {
|
||||
model: modelUid,
|
||||
},
|
||||
body: {
|
||||
title: 'test',
|
||||
},
|
||||
},
|
||||
{ state }
|
||||
);
|
||||
|
||||
await singleTypes.createOrUpdate(ctx);
|
||||
|
||||
expect(permissionChecker.cannot.create).toHaveBeenCalled();
|
||||
|
||||
expect(createFn).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
title: 'test',
|
||||
created_by: 1,
|
||||
updated_by: 1,
|
||||
}),
|
||||
modelUid
|
||||
);
|
||||
|
||||
expect(sendTelemetry).toHaveBeenCalledWith('didCreateFirstContentTypeEntry', {
|
||||
model: modelUid,
|
||||
});
|
||||
});
|
||||
|
||||
test('Successfull delete', async () => {
|
||||
const modelUid = 'test-uid';
|
||||
|
||||
const entity = {
|
||||
id: 1,
|
||||
title: 'entityTitle',
|
||||
};
|
||||
|
||||
const state = {
|
||||
userAbility: {
|
||||
can: jest.fn(),
|
||||
cannot: jest.fn(() => false),
|
||||
},
|
||||
user: {
|
||||
id: 1,
|
||||
},
|
||||
};
|
||||
|
||||
const createPermissionsManager = jest.fn(() => ({
|
||||
ability: state.userAbility,
|
||||
}));
|
||||
|
||||
const permissionChecker = {
|
||||
cannot: {
|
||||
delete: jest.fn(() => false),
|
||||
},
|
||||
sanitizeOutput: jest.fn(obj => obj),
|
||||
};
|
||||
|
||||
const deleteFn = jest.fn(() => ({}));
|
||||
|
||||
global.strapi = {
|
||||
admin: {
|
||||
services: {
|
||||
permission: {
|
||||
createPermissionsManager,
|
||||
},
|
||||
},
|
||||
},
|
||||
getModel() {
|
||||
return {
|
||||
options: {
|
||||
draftAndPublish: true,
|
||||
},
|
||||
attributes: {
|
||||
title: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
plugins: {
|
||||
'content-manager': {
|
||||
services: {
|
||||
'entity-manager': {
|
||||
find() {
|
||||
return Promise.resolve(entity);
|
||||
},
|
||||
assocCreatorRoles(enitty) {
|
||||
return enitty;
|
||||
},
|
||||
delete: deleteFn,
|
||||
},
|
||||
'permission-checker': {
|
||||
create() {
|
||||
return permissionChecker;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
entityService: {
|
||||
find: jest.fn(),
|
||||
},
|
||||
};
|
||||
|
||||
const ctx = createContext(
|
||||
{
|
||||
params: {
|
||||
id: entity.id,
|
||||
model: modelUid,
|
||||
},
|
||||
},
|
||||
{ state }
|
||||
);
|
||||
|
||||
await singleTypes.delete(ctx);
|
||||
|
||||
expect(deleteFn).toHaveBeenCalledWith(entity, modelUid);
|
||||
expect(permissionChecker.cannot.delete).toHaveBeenCalledWith(entity);
|
||||
expect(permissionChecker.sanitizeOutput).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Successfull publish', async () => {
|
||||
const modelUid = 'test-uid';
|
||||
|
||||
const entity = {
|
||||
id: 1,
|
||||
title: 'entityTitle',
|
||||
};
|
||||
|
||||
const state = {
|
||||
userAbility: {
|
||||
can: jest.fn(),
|
||||
cannot: jest.fn(() => false),
|
||||
},
|
||||
user: {
|
||||
id: 1,
|
||||
},
|
||||
};
|
||||
|
||||
const createPermissionsManager = jest.fn(() => ({
|
||||
ability: state.userAbility,
|
||||
}));
|
||||
|
||||
const permissionChecker = {
|
||||
cannot: {
|
||||
publish: jest.fn(() => false),
|
||||
},
|
||||
sanitizeOutput: jest.fn(obj => obj),
|
||||
};
|
||||
|
||||
const publishFn = jest.fn(() => ({}));
|
||||
|
||||
global.strapi = {
|
||||
admin: {
|
||||
services: {
|
||||
permission: {
|
||||
createPermissionsManager,
|
||||
},
|
||||
},
|
||||
},
|
||||
getModel() {
|
||||
return {
|
||||
options: {
|
||||
draftAndPublish: true,
|
||||
},
|
||||
attributes: {
|
||||
title: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
plugins: {
|
||||
'content-manager': {
|
||||
services: {
|
||||
'entity-manager': {
|
||||
find() {
|
||||
return Promise.resolve(entity);
|
||||
},
|
||||
assocCreatorRoles(enitty) {
|
||||
return enitty;
|
||||
},
|
||||
publish: publishFn,
|
||||
},
|
||||
'permission-checker': {
|
||||
create() {
|
||||
return permissionChecker;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
entityService: {
|
||||
find: jest.fn(),
|
||||
},
|
||||
};
|
||||
|
||||
const ctx = createContext(
|
||||
{
|
||||
params: {
|
||||
id: entity.id,
|
||||
model: modelUid,
|
||||
},
|
||||
},
|
||||
{ state }
|
||||
);
|
||||
|
||||
await singleTypes.publish(ctx);
|
||||
|
||||
expect(publishFn).toHaveBeenCalledWith(entity, modelUid);
|
||||
expect(permissionChecker.cannot.publish).toHaveBeenCalledWith(entity);
|
||||
expect(permissionChecker.sanitizeOutput).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Successfull unpublish', async () => {
|
||||
const modelUid = 'test-uid';
|
||||
|
||||
const entity = {
|
||||
id: 1,
|
||||
title: 'entityTitle',
|
||||
};
|
||||
|
||||
const state = {
|
||||
userAbility: {
|
||||
can: jest.fn(),
|
||||
cannot: jest.fn(() => false),
|
||||
},
|
||||
user: {
|
||||
id: 1,
|
||||
},
|
||||
};
|
||||
|
||||
const createPermissionsManager = jest.fn(() => ({
|
||||
ability: state.userAbility,
|
||||
}));
|
||||
|
||||
const permissionChecker = {
|
||||
cannot: {
|
||||
unpublish: jest.fn(() => false),
|
||||
},
|
||||
sanitizeOutput: jest.fn(obj => obj),
|
||||
};
|
||||
|
||||
const unpublishFn = jest.fn(() => ({}));
|
||||
|
||||
global.strapi = {
|
||||
admin: {
|
||||
services: {
|
||||
permission: {
|
||||
createPermissionsManager,
|
||||
},
|
||||
},
|
||||
},
|
||||
getModel() {
|
||||
return {
|
||||
options: {
|
||||
draftAndPublish: true,
|
||||
},
|
||||
attributes: {
|
||||
title: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
plugins: {
|
||||
'content-manager': {
|
||||
services: {
|
||||
'entity-manager': {
|
||||
find() {
|
||||
return Promise.resolve(entity);
|
||||
},
|
||||
assocCreatorRoles(enitty) {
|
||||
return enitty;
|
||||
},
|
||||
unpublish: unpublishFn,
|
||||
},
|
||||
'permission-checker': {
|
||||
create() {
|
||||
return permissionChecker;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
entityService: {
|
||||
find: jest.fn(),
|
||||
},
|
||||
};
|
||||
|
||||
const ctx = createContext(
|
||||
{
|
||||
params: {
|
||||
id: entity.id,
|
||||
model: modelUid,
|
||||
},
|
||||
},
|
||||
{ state }
|
||||
);
|
||||
|
||||
await singleTypes.unpublish(ctx);
|
||||
|
||||
expect(unpublishFn).toHaveBeenCalledWith(entity, modelUid);
|
||||
expect(permissionChecker.cannot.unpublish).toHaveBeenCalledWith(entity);
|
||||
expect(permissionChecker.sanitizeOutput).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@ -8,6 +8,7 @@ const {
|
||||
setCreatorFields,
|
||||
pickWritableAttributes,
|
||||
} = require('../utils');
|
||||
const { validateBulkDeleteInput } = require('./validation');
|
||||
|
||||
module.exports = {
|
||||
async find(ctx) {
|
||||
@ -203,6 +204,8 @@ module.exports = {
|
||||
const { query, body } = ctx.request;
|
||||
const { ids } = body;
|
||||
|
||||
await validateBulkDeleteInput(body);
|
||||
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
@ -214,7 +217,6 @@ module.exports = {
|
||||
|
||||
const idsWhereClause = { [`id_in`]: ids };
|
||||
const params = {
|
||||
_limit: 100,
|
||||
...permissionQuery,
|
||||
_where: [idsWhereClause].concat(permissionQuery._where || {}),
|
||||
};
|
||||
|
||||
@ -7,6 +7,10 @@ const createModelConfigurationSchema = require('./model-configuration');
|
||||
|
||||
const TYPES = ['singleType', 'collectionType'];
|
||||
|
||||
const handleError = error => {
|
||||
throw strapi.errors.badRequest('ValidationError', formatYupErrors(error));
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates type kind
|
||||
*/
|
||||
@ -19,6 +23,23 @@ const validateKind = kind => {
|
||||
.catch(error => Promise.reject(formatYupErrors(error)));
|
||||
};
|
||||
|
||||
const validateBulkDeleteInput = (data = {}) => {
|
||||
return yup
|
||||
.object({
|
||||
ids: yup
|
||||
.array()
|
||||
.of(yup.strapiID())
|
||||
.min(1)
|
||||
.required(),
|
||||
})
|
||||
.required()
|
||||
.validate(data, {
|
||||
strict: true,
|
||||
abortEarly: false,
|
||||
})
|
||||
.catch(handleError);
|
||||
};
|
||||
|
||||
const validateGenerateUIDInput = data => {
|
||||
return yup
|
||||
.object({
|
||||
@ -30,9 +51,7 @@ const validateGenerateUIDInput = data => {
|
||||
strict: true,
|
||||
abortEarly: false,
|
||||
})
|
||||
.catch(error => {
|
||||
throw strapi.errors.badRequest('ValidationError', formatYupErrors(error));
|
||||
});
|
||||
.catch(handleError);
|
||||
};
|
||||
|
||||
const validateCheckUIDAvailabilityInput = data => {
|
||||
@ -49,9 +68,7 @@ const validateCheckUIDAvailabilityInput = data => {
|
||||
strict: true,
|
||||
abortEarly: false,
|
||||
})
|
||||
.catch(error => {
|
||||
throw strapi.errors.badRequest('ValidationError', formatYupErrors(error));
|
||||
});
|
||||
.catch(handleError);
|
||||
};
|
||||
|
||||
const validateUIDField = (contentTypeUID, field) => {
|
||||
@ -74,6 +91,7 @@ const validateUIDField = (contentTypeUID, field) => {
|
||||
module.exports = {
|
||||
createModelConfigurationSchema,
|
||||
validateKind,
|
||||
validateBulkDeleteInput,
|
||||
validateGenerateUIDInput,
|
||||
validateCheckUIDAvailabilityInput,
|
||||
validateUIDField,
|
||||
|
||||
@ -60,7 +60,7 @@ module.exports = ({ isComponent, prefix, storeUtils, getModels }) => {
|
||||
const contentTypesToAdd = difference(currentUIDS, DBUIDs);
|
||||
const contentTypesToDelete = difference(DBUIDs, currentUIDS);
|
||||
|
||||
// delette old schemas
|
||||
// delete old schemas
|
||||
await Promise.all(contentTypesToDelete.map(uid => deleteConfiguration(uid)));
|
||||
|
||||
// create new schemas
|
||||
|
||||
@ -250,8 +250,6 @@ describe('Core API - Basic + dz', () => {
|
||||
body: product,
|
||||
});
|
||||
|
||||
console.log(res.body.data);
|
||||
|
||||
expect(res.statusCode).toBe(400);
|
||||
expect(_.get(res.body.data, ['errors', 'dz[0].__component', '0'])).toBe(
|
||||
'dz[0].__component is a required field'
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = fn => async () => {
|
||||
module.exports = fn => async (...args) => {
|
||||
try {
|
||||
await fn();
|
||||
await fn(...args);
|
||||
} catch (error) {
|
||||
if (strapi.errors.isBoom(error)) {
|
||||
throw error;
|
||||
|
||||
@ -18,26 +18,6 @@ let data;
|
||||
let rq;
|
||||
let modelsUtils;
|
||||
|
||||
const deleteFixtures = async () => {
|
||||
for (const [name, modelName] of [
|
||||
['references', 'reference'],
|
||||
['tags', 'tag'],
|
||||
['products', 'product'],
|
||||
['categories', 'category'],
|
||||
['articles', 'article'],
|
||||
]) {
|
||||
const uid = `application::${modelName}.${modelName}`;
|
||||
|
||||
await rq({
|
||||
method: 'POST',
|
||||
url: `/content-manager/collection-types/${uid}/actions/bulkDelete`,
|
||||
body: {
|
||||
ids: (data[name] || []).map(({ id }) => id),
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
describe('Create Strapi API End to End', () => {
|
||||
beforeAll(async () => {
|
||||
const token = await registerAndLogin();
|
||||
@ -52,9 +32,12 @@ describe('Create Strapi API End to End', () => {
|
||||
form.reference,
|
||||
form.product,
|
||||
]);
|
||||
|
||||
await modelsUtils.cleanupContentTypes(['article', 'tag', 'category', 'reference', 'product']);
|
||||
}, 60000);
|
||||
|
||||
afterAll(async () => {
|
||||
await modelsUtils.cleanupContentTypes(['article', 'tag', 'category', 'reference', 'product']);
|
||||
await modelsUtils.deleteContentTypes(['article', 'tag', 'category', 'reference', 'product']);
|
||||
}, 60000);
|
||||
|
||||
@ -67,7 +50,7 @@ describe('Create Strapi API End to End', () => {
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteFixtures();
|
||||
await modelsUtils.cleanupContentTypes(['article', 'tag']);
|
||||
});
|
||||
|
||||
test('Create tag1', async () => {
|
||||
@ -260,7 +243,7 @@ describe('Create Strapi API End to End', () => {
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteFixtures();
|
||||
await modelsUtils.cleanupContentTypes(['article', 'category']);
|
||||
});
|
||||
|
||||
test('Create cat1', async () => {
|
||||
@ -483,7 +466,7 @@ describe('Create Strapi API End to End', () => {
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteFixtures();
|
||||
await modelsUtils.cleanupContentTypes(['article', 'reference']);
|
||||
});
|
||||
|
||||
test('Create ref1', async () => {
|
||||
@ -572,7 +555,7 @@ describe('Create Strapi API End to End', () => {
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteFixtures();
|
||||
await modelsUtils.cleanupContentTypes(['reference', 'tag']);
|
||||
});
|
||||
|
||||
test('Attach Tag to a Reference', async () => {
|
||||
|
||||
@ -95,15 +95,6 @@ async function createFixtures() {
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteFixtures() {
|
||||
for (let product of data.products) {
|
||||
await rq({
|
||||
method: 'DELETE',
|
||||
url: `/products/${product.id}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
describe('Filtering API', () => {
|
||||
beforeAll(async () => {
|
||||
const token = await registerAndLogin();
|
||||
@ -111,12 +102,12 @@ describe('Filtering API', () => {
|
||||
|
||||
modelsUtils = createModelsUtils({ rq });
|
||||
await modelsUtils.createContentTypes([product]);
|
||||
await modelsUtils.cleanupContentTypes([product]);
|
||||
await modelsUtils.cleanupContentTypes(['product']);
|
||||
await createFixtures();
|
||||
}, 60000);
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteFixtures();
|
||||
await modelsUtils.cleanupContentTypes(['product']);
|
||||
await modelsUtils.deleteContentTypes(['product']);
|
||||
}, 60000);
|
||||
|
||||
|
||||
@ -168,24 +168,6 @@ const createFixtures = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const deleteFixtures = async () => {
|
||||
for (const [name, modelName] of [
|
||||
['countries', 'country'],
|
||||
['categories', 'category'],
|
||||
['products', 'product'],
|
||||
]) {
|
||||
const uid = `application::${modelName}.${modelName}`;
|
||||
|
||||
await rq({
|
||||
method: 'POST',
|
||||
url: `/content-manager/collection-types/${uid}/actions/bulkDelete`,
|
||||
body: {
|
||||
ids: data.api[name].map(({ id }) => id),
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
describe('Publication State', () => {
|
||||
beforeAll(async () => {
|
||||
const token = await registerAndLogin();
|
||||
@ -201,8 +183,6 @@ describe('Publication State', () => {
|
||||
}, 60000);
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteFixtures();
|
||||
|
||||
await modelsUtils.cleanupContentTypes(['product', 'category', 'country']);
|
||||
await modelsUtils.deleteComponent('comp');
|
||||
await modelsUtils.deleteContentTypes(['product', 'category', 'country']);
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
// required first because it loads env files.
|
||||
|
||||
const http = require('http');
|
||||
const path = require('path');
|
||||
const fse = require('fs-extra');
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
// required first because it loads env files.
|
||||
|
||||
const { green } = require('chalk');
|
||||
|
||||
// eslint-disable-next-line node/no-extraneous-require
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
// required first because it loads env files.
|
||||
|
||||
const path = require('path');
|
||||
const cluster = require('cluster');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
// required first because it loads env files.
|
||||
|
||||
// eslint-disable-next-line node/no-extraneous-require
|
||||
const strapiAdmin = require('strapi-admin');
|
||||
const { getConfigUrls, getAbsoluteServerUrl } = require('strapi-utils');
|
||||
|
||||
@ -122,16 +122,21 @@ module.exports = ({ rq }) => {
|
||||
|
||||
async function cleanupContentType(model) {
|
||||
const { body } = await rq({
|
||||
url: `/content-manager/collections-types/application::${model}.${model}`,
|
||||
url: `/content-manager/collection-types/application::${model}.${model}`,
|
||||
qs: {
|
||||
pageSize: 1000,
|
||||
},
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
if (Array.isArray(body) && body.length > 0) {
|
||||
console.log(body);
|
||||
|
||||
if (Array.isArray(body.results) && body.results.length > 0) {
|
||||
await rq({
|
||||
url: `/content-manager/collection-types/application::${model}.${model}/actions/bulkDelete`,
|
||||
method: 'POST',
|
||||
body: {
|
||||
ids: body.map(({ id }) => id),
|
||||
ids: body.results.map(({ id }) => id),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user