mirror of
https://github.com/strapi/strapi.git
synced 2025-11-01 10:23:34 +00:00
feat(review-workflows): add update route on entity for stages
This commit is contained in:
parent
782009fded
commit
1cf3da856c
@ -1,7 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const { ApplicationError } = require('@strapi/utils/lib/errors');
|
||||
const { getService } = require('../../../utils');
|
||||
const { validateUpdateStages } = require('../../../validation/review-workflows');
|
||||
const {
|
||||
validateUpdateStages,
|
||||
validateUpdateStageOnEntity,
|
||||
} = require('../../../validation/review-workflows');
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
@ -54,4 +58,24 @@ module.exports = {
|
||||
|
||||
ctx.body = { data };
|
||||
},
|
||||
|
||||
async updateEntity(ctx) {
|
||||
const stagesService = getService('stages');
|
||||
const reviewWorkflowsService = getService('review-workflows');
|
||||
const { model_uid: modelUID, id: entityId } = ctx.params;
|
||||
|
||||
const { id: stageId } = await validateUpdateStageOnEntity(
|
||||
ctx.request?.body?.data,
|
||||
'You shall pass an id to the body of the put request.'
|
||||
);
|
||||
|
||||
if (!reviewWorkflowsService.isReviewWorkflowEnabled({ strapi }, modelUID)) {
|
||||
throw new ApplicationError(`Review workflows is not activated on ${modelUID}.`);
|
||||
}
|
||||
|
||||
// TODO When multiple workflows are possible, check if the stage is part of the right one
|
||||
// Didn't need this today as their can only be one workflow
|
||||
|
||||
ctx.body = await stagesService.updateEntity({ id: entityId, modelUID }, stageId);
|
||||
},
|
||||
};
|
||||
|
||||
@ -209,4 +209,21 @@ module.exports = [
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
method: 'PUT',
|
||||
path: '/content-manager/(collection|single)-types/:model_uid/:id/stage',
|
||||
handler: 'stages.updateEntity',
|
||||
config: {
|
||||
middlewares: [enableFeatureMiddleware('review-workflows')],
|
||||
policies: [
|
||||
'admin::isAuthenticatedAdmin',
|
||||
{
|
||||
name: 'admin::hasPermissions',
|
||||
config: {
|
||||
actions: ['admin::review-workflows.read'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@ -11,7 +11,7 @@ const { ENTITY_STAGE_ATTRIBUTE } = require('../../constants/workflows');
|
||||
const {
|
||||
disableOnContentTypes: disableReviewWorkflows,
|
||||
} = require('../../migrations/review-workflows');
|
||||
const { getDefaultWorkflow } = require('../../utils/review-workflows');
|
||||
const { getDefaultWorkflow, hasRWEnabled } = require('../../utils/review-workflows');
|
||||
|
||||
const getContentTypeUIDsWithActivatedReviewWorkflows = pipe([
|
||||
// Pick only content-types with reviewWorkflows options set to true
|
||||
@ -170,5 +170,9 @@ module.exports = ({ strapi }) => {
|
||||
strapi.hook('strapi::content-types.afterSync').register(enableReviewWorkflow({ strapi }));
|
||||
strapi.hook('strapi::content-types.afterSync').register(disableReviewWorkflows);
|
||||
},
|
||||
isReviewWorkflowEnabled({ strapi }, modelUID) {
|
||||
const contentType = strapi.container.get('content-types').get(modelUID);
|
||||
return hasRWEnabled(contentType);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@ -5,7 +5,7 @@ const {
|
||||
errors: { ApplicationError },
|
||||
} = require('@strapi/utils');
|
||||
|
||||
const { STAGE_MODEL_UID } = require('../../constants/workflows');
|
||||
const { STAGE_MODEL_UID, ENTITY_STAGE_ATTRIBUTE } = require('../../constants/workflows');
|
||||
const { getService } = require('../../utils');
|
||||
|
||||
module.exports = ({ strapi }) => {
|
||||
@ -69,6 +69,21 @@ module.exports = ({ strapi }) => {
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the stage of an entity
|
||||
*
|
||||
* @param {object} entityInfo
|
||||
* @param {string} entityInfo.id - Entity id
|
||||
* @param {string} entityInfo.modelUID - the content-type of the entity
|
||||
* @param {string} stageId - The id of the stage to assign to the entity
|
||||
*/
|
||||
updateEntity(entityInfo, stageId) {
|
||||
return strapi.entityService.update(entityInfo.modelUID, entityInfo.id, {
|
||||
data: { [ENTITY_STAGE_ATTRIBUTE]: Number(stageId) },
|
||||
populate: [ENTITY_STAGE_ATTRIBUTE],
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -101,6 +101,20 @@ describeOnCondition(edition === 'EE')('Review workflows', () => {
|
||||
await builder.cleanup();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
testWorkflow = await strapi.query(WORKFLOW_MODEL_UID).update({
|
||||
where: { id: testWorkflow.id },
|
||||
data: {
|
||||
uid: 'workflow',
|
||||
stages: [defaultStage.id, secondStage.id],
|
||||
},
|
||||
});
|
||||
await updateContentType(productUID, {
|
||||
components: [],
|
||||
contentType: model,
|
||||
});
|
||||
});
|
||||
|
||||
describe('Get workflows', () => {
|
||||
test("It shouldn't be available for public", async () => {
|
||||
const res = await requests.public.get('/admin/review-workflows/workflows');
|
||||
@ -328,8 +342,6 @@ describeOnCondition(edition === 'EE')('Review workflows', () => {
|
||||
});
|
||||
|
||||
describe('Enabling/Disabling review workflows on a content type', () => {
|
||||
let response;
|
||||
|
||||
beforeAll(async () => {
|
||||
await createEntry(productUID, { name: 'Product' });
|
||||
await createEntry(productUID, { name: 'Product 1' });
|
||||
@ -343,18 +355,18 @@ describeOnCondition(edition === 'EE')('Review workflows', () => {
|
||||
});
|
||||
await restart();
|
||||
|
||||
response = await requests.admin({
|
||||
const response = await requests.admin({
|
||||
method: 'GET',
|
||||
url: `/content-type-builder/content-types/api::product.product`,
|
||||
});
|
||||
|
||||
expect(response.body.data.schema.reviewWorkflows).toBeTruthy();
|
||||
|
||||
response = await getRWMorphTableResults(strapi.db.getConnection());
|
||||
const morphTableResults = await getRWMorphTableResults(strapi.db.getConnection());
|
||||
|
||||
expect(response.length).toEqual(3);
|
||||
for (let i = 0; i < response.length; i += 1) {
|
||||
const entry = response[i];
|
||||
expect(morphTableResults.length).toEqual(3);
|
||||
for (let i = 0; i < morphTableResults.length; i += 1) {
|
||||
const entry = morphTableResults[i];
|
||||
expect(entry.related_id).toEqual(i + 1);
|
||||
expect(entry.order).toEqual(1);
|
||||
}
|
||||
@ -368,14 +380,66 @@ describeOnCondition(edition === 'EE')('Review workflows', () => {
|
||||
|
||||
await restart();
|
||||
|
||||
response = await requests.admin({
|
||||
const response = await requests.admin({
|
||||
method: 'GET',
|
||||
url: `/content-type-builder/content-types/api::product.product`,
|
||||
});
|
||||
expect(response.body.data.schema.reviewWorkflows).toBeFalsy();
|
||||
|
||||
response = await getRWMorphTableResults(strapi.db.getConnection());
|
||||
expect(response.length).toEqual(0);
|
||||
const morphTableResults = await getRWMorphTableResults(strapi.db.getConnection());
|
||||
expect(morphTableResults.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update a stage on an entity', () => {
|
||||
describe('Review Workflow is enabled', () => {
|
||||
beforeAll(async () => {
|
||||
await updateContentType(productUID, {
|
||||
components: [],
|
||||
contentType: { ...model, reviewWorkflows: true },
|
||||
});
|
||||
await restart();
|
||||
});
|
||||
test('Should update the accordingly on an entity', async () => {
|
||||
const entry = await createEntry(productUID, { name: 'Product' });
|
||||
|
||||
const response = await requests.admin({
|
||||
method: 'PUT',
|
||||
url: `/admin/content-manager/collection-types/${productUID}/${entry.id}/stage`,
|
||||
body: {
|
||||
data: { id: secondStage.id },
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body[ENTITY_STAGE_ATTRIBUTE]).toEqual(
|
||||
expect.objectContaining({ id: secondStage.id })
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('Review Workflow is disabled', () => {
|
||||
beforeAll(async () => {
|
||||
await updateContentType(productUID, {
|
||||
components: [],
|
||||
contentType: { ...model, reviewWorkflows: false },
|
||||
});
|
||||
await restart();
|
||||
});
|
||||
test('Should not update the entity', async () => {
|
||||
const entry = await createEntry(productUID, { name: 'Product' });
|
||||
|
||||
const response = await requests.admin({
|
||||
method: 'PUT',
|
||||
url: `/admin/content-manager/collection-types/${productUID}/${entry.id}/stage`,
|
||||
body: {
|
||||
data: { id: secondStage.id },
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(400);
|
||||
expect(response.body.error).toBeDefined();
|
||||
expect(response.body.error.name).toBe('ApplicationError');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -8,10 +8,17 @@ const stageObject = yup.object().shape({
|
||||
});
|
||||
|
||||
const validateUpdateStagesSchema = yup.array().of(stageObject).required();
|
||||
const validateUpdateStageOnEntity = yup
|
||||
.object()
|
||||
.shape({
|
||||
id: yup.number().integer().min(1).required(),
|
||||
})
|
||||
.required();
|
||||
|
||||
module.exports = {
|
||||
validateUpdateStages: validateYupSchema(validateUpdateStagesSchema, {
|
||||
strict: false,
|
||||
stripUnknown: true,
|
||||
}),
|
||||
validateUpdateStageOnEntity: validateYupSchema(validateUpdateStageOnEntity),
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user