diff --git a/packages/core/admin/ee/server/services/__tests__/review-workflows-validation.test.js b/packages/core/admin/ee/server/services/__tests__/review-workflows-validation.test.js new file mode 100644 index 0000000000..62993f5156 --- /dev/null +++ b/packages/core/admin/ee/server/services/__tests__/review-workflows-validation.test.js @@ -0,0 +1,92 @@ +'use strict'; + +jest.mock('@strapi/strapi/lib/utils/ee', () => { + const eeModule = () => true; + + Object.assign(eeModule, { + features: { + isEnabled() { + return true; + }, + getEnabled() { + return ['review-workflows']; + }, + }, + }); + + return eeModule; +}); + +jest.mock('../review-workflows/workflows/content-types', () => { + return jest.fn(() => ({ + migrate: jest.fn(), + })); +}); + +const validationServiceFactory = require('../review-workflows/validation'); +const { MAX_WORKFLOWS, MAX_STAGES_PER_WORKFLOW } = require('../../constants/workflows'); + +const workflowsServiceMock = { + count: jest.fn(() => 1), +}; + +const servicesMock = { + 'admin::workflows': workflowsServiceMock, +}; + +const strapiMock = { + service: jest.fn((serviceName) => console.log(serviceName) || servicesMock[serviceName]), +}; +let validationService; + +describe('Review workflows - Validation service', () => { + beforeEach(() => { + validationService = validationServiceFactory({ strapi: strapiMock }); + }); + afterEach(() => { + jest.clearAllMocks(); + }); + describe('register', () => { + test('Limits object should be frozen after register', () => { + validationService.register({ workflows: 2, stagesPerWorkflow: 10 }); + expect(validationService.limits.workflows).toEqual(2); + expect(validationService.limits.stagesPerWorkflow).toEqual(10); + expect(Object.isFrozen(validationService.limits)).toBe(true); + }); + test(`Limits object shouldn't be frozen before register`, () => { + expect(validationService.limits.workflows).toEqual(MAX_WORKFLOWS); + expect(validationService.limits.stagesPerWorkflow).toEqual(MAX_STAGES_PER_WORKFLOW); + expect(Object.isFrozen(validationService.limits)).toBe(false); + }); + test('Limits object should not be modified after first register', () => { + validationService.register({ workflows: 2, stagesPerWorkflow: 10 }); + expect(validationService.limits.workflows).toEqual(2); + expect(validationService.limits.stagesPerWorkflow).toEqual(10); + validationService.register({ workflows: 99, stagesPerWorkflow: 99 }); + expect(validationService.limits.workflows).toEqual(2); + expect(validationService.limits.stagesPerWorkflow).toEqual(10); + }); + }); + describe('validateWorkflowCount', () => { + test('Should not throw because limit is not reached', async () => { + validationService.register({ workflows: 2 }); + workflowsServiceMock.count.mockReturnValue(1); + await expect(validationService.validateWorkflowCount()).resolves.not.toThrowError(); + }); + test('Should throw because limit is reached', async () => { + validationService.register({ workflows: 2 }); + workflowsServiceMock.count.mockReturnValue(2); + await expect(validationService.validateWorkflowCount(1)).rejects.toThrowError(); + }); + }); + describe('validateWorkflowStages', () => { + test('Should not throw because limit is not reached and at least 1 stage', async () => { + validationService.register({ stagesPerWorkflow: 2 }); + expect(() => validationService.validateWorkflowStages([{}, {}])).not.toThrowError(); + }); + test('Should throw because limit is reached', async () => { + validationService.register({ stagesPerWorkflow: 2 }); + expect(() => validationService.validateWorkflowStages([{}, {}, {}])).toThrowError(); + }); + }); +}); diff --git a/packages/core/admin/ee/server/services/review-workflows/validation.js b/packages/core/admin/ee/server/services/review-workflows/validation.js index 900ca6cfa8..3e4f2f780c 100644 --- a/packages/core/admin/ee/server/services/review-workflows/validation.js +++ b/packages/core/admin/ee/server/services/review-workflows/validation.js @@ -6,19 +6,18 @@ const { ERRORS, MAX_WORKFLOWS, MAX_STAGES_PER_WORKFLOW } = require('../../consta const { clampMaxWorkflows, clampMaxStagesPerWorkflow } = require('../../utils/review-workflows'); module.exports = ({ strapi }) => { - const limits = { - workflows: MAX_WORKFLOWS, - stagesPerWorkflow: MAX_STAGES_PER_WORKFLOW, - }; - return { + limits: { + workflows: MAX_WORKFLOWS, + stagesPerWorkflow: MAX_STAGES_PER_WORKFLOW, + }, register({ workflows, stagesPerWorkflow }) { - if (!Object.isFrozen(limits)) { - limits.workflows = clampMaxWorkflows(workflows || limits.workflows); - limits.stagesPerWorkflow = clampMaxStagesPerWorkflow( - stagesPerWorkflow || limits.stagesPerWorkflow + if (!Object.isFrozen(this.limits)) { + this.limits.workflows = clampMaxWorkflows(workflows || this.limits.workflows); + this.limits.stagesPerWorkflow = clampMaxStagesPerWorkflow( + stagesPerWorkflow || this.limits.stagesPerWorkflow ); - Object.freeze(limits); + Object.freeze(this.limits); } }, /** @@ -30,7 +29,7 @@ module.exports = ({ strapi }) => { if (!stages || stages.length === 0) { throw new ValidationError(ERRORS.WORKFLOW_WITHOUT_STAGES); } - if (stages.length > limits.stagesPerWorkflow) { + if (stages.length > this.limits.stagesPerWorkflow) { throw new ValidationError(ERRORS.STAGES_LIMIT); } }, @@ -44,7 +43,7 @@ module.exports = ({ strapi }) => { async validateWorkflowCount(countAddedWorkflows = 0) { const workflowsService = getService('workflows', { strapi }); const countWorkflows = await workflowsService.count(); - if (countWorkflows + countAddedWorkflows > limits.workflows) { + if (countWorkflows + countAddedWorkflows > this.limits.workflows) { throw new ValidationError(ERRORS.WORKFLOWS_LIMIT); } },