diff --git a/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/WorkflowAPITest.java b/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/WorkflowAPITest.java index 532e7f219034..d7fc4548fffa 100644 --- a/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/WorkflowAPITest.java +++ b/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/WorkflowAPITest.java @@ -13,14 +13,7 @@ import com.dotcms.contenttype.model.type.ContentType; import com.dotcms.contenttype.model.type.ContentTypeBuilder; import com.dotcms.contenttype.transform.contenttype.StructureTransformer; -import com.dotcms.datagen.ContentTypeDataGen; -import com.dotcms.datagen.ContentletDataGen; -import com.dotcms.datagen.FieldDataGen; -import com.dotcms.datagen.LanguageDataGen; -import com.dotcms.datagen.TestDataUtils; -import com.dotcms.datagen.TestUserUtils; -import com.dotcms.datagen.TestWorkflowUtils; -import com.dotcms.datagen.UserDataGen; +import com.dotcms.datagen.*; import com.dotcms.system.event.local.model.EventSubscriber; import com.dotcms.util.CollectionsUtils; import com.dotcms.util.IntegrationTestInitService; @@ -75,6 +68,9 @@ import com.dotmarketing.util.WebKeys; import com.liferay.portal.model.User; import com.liferay.util.StringPool; +import io.vavr.Tuple; +import io.vavr.Tuple2; +import io.vavr.Tuple3; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -84,19 +80,13 @@ import java.time.LocalDate; import java.time.Month; import java.time.ZoneId; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import static com.dotmarketing.portlets.workflows.business.BaseWorkflowIntegrationTest.createContentTypeAndAssignPermissions; +import static com.dotmarketing.portlets.workflows.model.WorkflowState.*; +import static com.dotmarketing.portlets.workflows.model.WorkflowState.UNPUBLISHED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; @@ -4197,4 +4187,80 @@ private Field createRelationshipField(final String relationshipName, final Strin return fieldAPI.save(field, user); } + + /** + * Method to test: {@link WorkflowFactoryImpl#countAllSchemasSteps()} + * When: create a new Workflow with 5 steps + * Should: the count must be 5 more than before + * + * @throws DotDataException + */ + @Test + public void countAllWorkflowSteps() throws DotDataException, DotSecurityException { + + final long firstCount = APILocator.getWorkflowAPI().countAllSchemasSteps(APILocator.systemUser()); + + final List>>>> workflowStepsAndActions_1 = getStepsAndActions(); + + final WorkflowScheme workflow_1= new WorkflowDataGen().name("Testing") + .stepAndAction(workflowStepsAndActions_1).nextPersistedWithStepsAndActions(); + + final long secondCount = APILocator.getWorkflowAPI().countAllSchemasSteps(APILocator.systemUser()); + assertEquals(firstCount + 5, secondCount); + + final List>>>> workflowStepsAndActions_2 = getStepsAndActions(); + + final WorkflowScheme workflow_2 = new WorkflowDataGen().name("Testing") + .stepAndAction(workflowStepsAndActions_2).nextPersistedWithStepsAndActions(); + + final long thirdCount = APILocator.getWorkflowAPI().countAllSchemasSteps(APILocator.systemUser()); + assertEquals(secondCount + 5, thirdCount); + } + + + /** + * Method to test: {@link WorkflowFactoryImpl#countAllSchemasSteps()} + * When: Try to count Steos with limited USer + * Should: throw a {@link DotSecurityException} + * + * @throws DotDataException + */ + @Test(expected = DotSecurityException.class) + public void countSteosWithLimitedUser() throws DotDataException, DotSecurityException { + final User user = new UserDataGen().nextPersisted(); + APILocator.getWorkflowAPI().countAllSchemasSteps(user); + } + + private static List>>>> getStepsAndActions() { + final List>>>> workflowStepsAndActions = Arrays + .asList( + Tuple.of("Editing", + Arrays.asList( + Tuple.of("Save as Draft", "Current Step", EnumSet.of(EDITING, UNLOCKED, LOCKED, NEW, PUBLISHED, UNPUBLISHED)) + ) + ), + Tuple.of("Review", + Arrays.asList( + Tuple.of("Save as Draft", "Current Step", EnumSet.of(EDITING, LOCKED, NEW, PUBLISHED, UNPUBLISHED)) + ) + ), + Tuple.of("Legal Approval", + Arrays.asList( + Tuple.of("Save as Draft", "Current Step", EnumSet.of(EDITING, LOCKED, NEW, PUBLISHED, UNPUBLISHED)) + ) + ), + Tuple.of("Published", + Arrays.asList( + Tuple.of("Republish", "Published", EnumSet.of(EDITING, LOCKED, UNLOCKED, PUBLISHED, ARCHIVED)) + )) + , + Tuple.of("Archived", + Arrays.asList( + Tuple.of("Full Delete", "Archived", EnumSet.of(EDITING, LISTING, LOCKED, UNLOCKED, ARCHIVED)) + ) + + ) + ); + return workflowStepsAndActions; + } } diff --git a/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/WorkflowFactoryTest.java b/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/WorkflowFactoryTest.java index 7ab2586925d3..9c6aa5fa7f18 100644 --- a/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/WorkflowFactoryTest.java +++ b/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/WorkflowFactoryTest.java @@ -9,6 +9,7 @@ import com.dotcms.contenttype.model.type.ContentType; import com.dotcms.contenttype.model.type.ContentTypeBuilder; import com.dotcms.contenttype.transform.contenttype.StructureTransformer; +import com.dotcms.datagen.WorkflowDataGen; import com.dotcms.util.IntegrationTestInitService; import com.dotmarketing.beans.Host; import com.dotmarketing.business.APILocator; @@ -21,15 +22,20 @@ import com.dotmarketing.portlets.folders.business.FolderAPI; import com.dotmarketing.portlets.workflows.actionlet.SaveContentActionlet; import com.dotmarketing.portlets.workflows.model.WorkflowScheme; +import com.dotmarketing.portlets.workflows.model.WorkflowState; import com.dotmarketing.util.UUIDGenerator; +import io.vavr.Tuple; +import io.vavr.Tuple2; +import io.vavr.Tuple3; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; + +import static com.dotmarketing.portlets.workflows.model.WorkflowState.*; +import static org.junit.Assert.assertEquals; public class WorkflowFactoryTest extends BaseWorkflowIntegrationTest { @@ -142,4 +148,92 @@ public void force_workflow_scheme_delete_without_license_delete_success_Test() t Assert.assertNotNull(workflowSchemesAfterForceDelete); Assert.assertTrue(workflowSchemesAfterForceDelete.size() == 0); } + + /** + * Method to test: {@link WorkflowFactoryImpl#countAllSchemasSteps()} + * When: create a new Workflow with 5 steps + * Should: the count must be 5 more than before + * + * @throws DotDataException + */ + @Test + public void countAllWorkflowSteps() throws DotDataException { + + final long firstCount = FactoryLocator.getWorkFlowFactory().countAllSchemasSteps(); + + final List>>>> workflowStepsAndActions_1 = getStepsAndActions(); + + final WorkflowScheme workflow_1= new WorkflowDataGen().name("Testing") + .stepAndAction(workflowStepsAndActions_1).nextPersistedWithStepsAndActions(); + + final long secondCount = FactoryLocator.getWorkFlowFactory().countAllSchemasSteps(); + assertEquals(firstCount + 5, secondCount); + + final List>>>> workflowStepsAndActions_2 = getStepsAndActions(); + + final WorkflowScheme workflow_2 = new WorkflowDataGen().name("Testing") + .stepAndAction(workflowStepsAndActions_2).nextPersistedWithStepsAndActions(); + + final long thirdCount = FactoryLocator.getWorkFlowFactory().countAllSchemasSteps(); + assertEquals(secondCount + 5, thirdCount); + } + + /** + * Method to test: {@link WorkflowFactoryImpl#countAllSchemasSteps()} + * When: create a new Workflow with 5 steps, and later archive it + * Should: not take account the archived Schema + * + * @throws DotDataException + */ + @Test + public void notCountStepsFromArchivedSchema() throws DotDataException, DotSecurityException, AlreadyExistException { + + final long firstCount = FactoryLocator.getWorkFlowFactory().countAllSchemasSteps(); + + final List>>>> workflowStepsAndActions_1 = getStepsAndActions(); + + final WorkflowScheme workflow_1= new WorkflowDataGen().name("Testing") + .stepAndAction(workflowStepsAndActions_1).nextPersistedWithStepsAndActions(); + + final long secondCount = FactoryLocator.getWorkFlowFactory().countAllSchemasSteps(); + assertEquals(firstCount + 5, secondCount); + + APILocator.getWorkflowAPI().archive(workflow_1, APILocator.systemUser()); + + final long thirdCount = FactoryLocator.getWorkFlowFactory().countAllSchemasSteps(); + assertEquals(firstCount, thirdCount); + } + + private static List>>>> getStepsAndActions() { + final List>>>> workflowStepsAndActions = Arrays + .asList( + Tuple.of("Editing", + Arrays.asList( + Tuple.of("Save as Draft", "Current Step", EnumSet.of(EDITING, UNLOCKED, LOCKED, NEW, PUBLISHED, UNPUBLISHED)) + ) + ), + Tuple.of("Review", + Arrays.asList( + Tuple.of("Save as Draft", "Current Step", EnumSet.of(EDITING, LOCKED, NEW, PUBLISHED, UNPUBLISHED)) + ) + ), + Tuple.of("Legal Approval", + Arrays.asList( + Tuple.of("Save as Draft", "Current Step", EnumSet.of(EDITING, LOCKED, NEW, PUBLISHED, UNPUBLISHED)) + ) + ), + Tuple.of("Published", + Arrays.asList( + Tuple.of("Republish", "Published", EnumSet.of(EDITING, LOCKED, UNLOCKED, PUBLISHED, ARCHIVED)) + )) + , + Tuple.of("Archived", + Arrays.asList( + Tuple.of("Full Delete", "Archived", EnumSet.of(EDITING, LISTING, LOCKED, UNLOCKED, ARCHIVED)) + ) + + ) + ); + return workflowStepsAndActions; + } } diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkFlowFactory.java b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkFlowFactory.java index 16b81d6e475a..cd696e4dcecf 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkFlowFactory.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkFlowFactory.java @@ -486,4 +486,11 @@ public void saveSchemesForStruct(String contentTypeInode, List s * @param language {@link Language} */ void deleteWorkflowTaskByLanguage(Language language) throws DotDataException; + + /** + * Return the count of Steps in all Schemas + * + * @return + */ + long countAllSchemasSteps() throws DotDataException; } diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPI.java b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPI.java index 1dd0bb7dbafa..1aa4a9d5cce8 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPI.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPI.java @@ -1088,6 +1088,13 @@ SystemActionWorkflowActionMapping mapSystemActionToWorkflowActionForWorkflowSche */ boolean hasDestroyActionlet(final WorkflowAction action); + /** + * Return the count of Steps in all Schemas + * + * @return + */ + long countAllSchemasSteps(User user) throws DotDataException, DotSecurityException; + /** * This method creates a WorkflowTask (does not persists it) based on the information on the contentlet (id + lang), * user (role to assign, and created by), workflowStep (status 'current step'), title and description diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java index 27ec5790577f..0a5d0883921f 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java @@ -4364,6 +4364,17 @@ public boolean hasDestroyActionlet(final WorkflowAction action) { return this.hasActionlet(action, Actionlet::destroy); } + @Override + public long countAllSchemasSteps(final User user) throws DotDataException, DotSecurityException { + try { + this.isUserAllowToModifiedWorkflow(user); + } catch (WorkflowPortletAccessException | InvalidLicenseException e) { + throw new DotSecurityException(e.getMessage(), e); + } + + return workFlowFactory.countAllSchemasSteps(); + } + @Override public WorkflowTask createWorkflowTask(final Contentlet contentlet, final User user, final WorkflowStep workflowStep, final String title, String description) throws DotDataException { diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowFactoryImpl.java b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowFactoryImpl.java index 9b7a44e63ffe..c70c83337720 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowFactoryImpl.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowFactoryImpl.java @@ -590,6 +590,17 @@ public void deleteWorkflowTaskByContentletIdAndLanguage(final String webAsset, } + public long countAllSchemasSteps() throws DotDataException { + final DotConnect db = new DotConnect(); + db.setSQL("SELECT COUNT(*) FROM workflow_step " + + "INNER JOIN workflow_scheme ON workflow_scheme.id=workflow_step.scheme_id " + + "WHERE archived = false"); + final Map results = (Map) db.loadResults().get(0); + + return Long.parseLong((String) results.get("count")); + + } + @Override public void deleteWorkflowTaskByLanguage(final Language language) throws DotDataException {