diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/CreateRulesTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/CreateRulesTests.java index 2e0cba0710..ccb3e2cdf1 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/CreateRulesTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/CreateRulesTests.java @@ -140,8 +140,7 @@ public class CreateRulesTests extends RestTest @Test (groups = { TestGroup.REST_API, TestGroup.RULES }) public void createRuleWithEmptyName() { - RestRuleModel ruleModel = new RestRuleModel(); - ruleModel.setName(""); + RestRuleModel ruleModel = createRuleModel(""); restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel); @@ -260,7 +259,7 @@ public class CreateRulesTests extends RestTest { STEP("Try to create a three rules but the middle one has an error."); RestRuleModel ruleA = createRuleModel("ruleA"); - RestRuleModel ruleB = new RestRuleModel(); + RestRuleModel ruleB = createRuleModel(""); // Don't set a name for Rule B. RestRuleModel ruleC = createRuleModel("ruleC"); List ruleModels = List.of(ruleA, ruleB, ruleC); diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/RulesTestsUtils.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/RulesTestsUtils.java index 87b8cd7f08..aa2d8f723f 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/RulesTestsUtils.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/RulesTestsUtils.java @@ -96,7 +96,7 @@ public class RulesTestsUtils { RestActionBodyExecTemplateModel restActionModel = new RestActionBodyExecTemplateModel(); restActionModel.setActionDefinitionId("add-features"); - restActionModel.setParams(Map.of("aspect-name", "{http://www.alfresco.org/model/audio/1.0}audio", "actionContext", "rule")); + restActionModel.setParams(Map.of("aspect-name", "cm:audio")); return restActionModel; } diff --git a/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java b/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java index 9ad634fcfb..57919bce45 100644 --- a/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java +++ b/remote-api/src/main/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java @@ -78,7 +78,7 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript private static final String RULE_OUTBOUND = "outbound"; private static final String ACTION_CHECK_OUT = "check-out"; - private static final String CANNOT_CREATE_RULE = "cannot.create.rule.checkout.outbound"; + public static final String CANNOT_CREATE_RULE = "cannot.create.rule.checkout.outbound"; protected NodeService nodeService; protected RuleService ruleService; diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/ActionParameterConverter.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/ActionParameterConverter.java new file mode 100644 index 0000000000..b138b0301d --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/ActionParameterConverter.java @@ -0,0 +1,132 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rest.api.impl.rules; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; +import org.alfresco.rest.framework.core.exceptions.NotFoundException; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.ActionService; +import org.alfresco.service.cmr.action.ParameterDefinition; +import org.alfresco.service.cmr.action.ParameterizedItemDefinition; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryException; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.json.JSONArray; +import org.json.JSONException; + +@Experimental +public class ActionParameterConverter +{ + private final DictionaryService dictionaryService; + private final ActionService actionService; + private final NamespaceService namespaceService; + + public ActionParameterConverter(DictionaryService dictionaryService, ActionService actionService, + NamespaceService namespaceService) + { + this.dictionaryService = dictionaryService; + this.actionService = actionService; + this.namespaceService = namespaceService; + } + + Map getConvertedParams(Map params, String name) { + final Map parameters = new HashMap<>(params.size()); + final ParameterizedItemDefinition definition = actionService.getActionDefinition(name); + if (definition == null) + { + throw new NotFoundException(NotFoundException.DEFAULT_MESSAGE_ID, new String[]{name}); + } + + for (Map.Entry param : params.entrySet()) + { + final ParameterDefinition paramDef = definition.getParameterDefintion(param.getKey()); + if (paramDef == null && !definition.getAdhocPropertiesAllowed()) + { + throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, new String[]{param.getKey(), name}); + } + if (paramDef != null) + { + final QName typeQName = paramDef.getType(); + parameters.put(param.getKey(), convertValue(typeQName, param.getValue())); + } else + { + parameters.put(param.getKey(), param.getValue().toString()); + } + } + return parameters; + } + + private Serializable convertValue(QName typeQName, Object propertyValue) throws JSONException + { + Serializable value; + + final DataTypeDefinition typeDef = dictionaryService.getDataType(typeQName); + if (typeDef == null) + { + throw new NotFoundException(NotFoundException.DEFAULT_MESSAGE_ID, new String[]{typeQName.toPrefixString()}); + } + + if (propertyValue instanceof JSONArray) + { + final String javaClassName = typeDef.getJavaClassName(); + try + { + Class.forName(javaClassName); + } catch (ClassNotFoundException e) + { + throw new DictionaryException("Java class " + javaClassName + " of property type " + typeDef.getName() + " is invalid", e); + } + + final int length = ((JSONArray) propertyValue).length(); + final List list = new ArrayList<>(length); + for (int i = 0; i < length; i++) + { + list.add(convertValue(typeQName, ((JSONArray) propertyValue).get(i))); + } + value = (Serializable) list; + } else + { + if (typeQName.equals(DataTypeDefinition.QNAME) && typeQName.toString().contains(":")) + { + value = QName.createQName(propertyValue.toString(), namespaceService); + } else + { + value = (Serializable) DefaultTypeConverter.INSTANCE.convert(dictionaryService.getDataType(typeQName), propertyValue); + } + } + return value; + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/ActionPermissionValidator.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/ActionPermissionValidator.java new file mode 100644 index 0000000000..d17efe05e5 --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/ActionPermissionValidator.java @@ -0,0 +1,85 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rest.api.impl.rules; + +import static org.alfresco.repo.web.scripts.rule.AbstractRuleWebScript.CANNOT_CREATE_RULE; +import static org.alfresco.service.cmr.rule.RuleType.OUTBOUND; + +import java.util.Collections; +import java.util.List; + +import org.alfresco.repo.action.CompositeActionImpl; +import org.alfresco.repo.action.RuntimeActionService; +import org.alfresco.repo.action.access.ActionAccessRestriction; +import org.alfresco.repo.action.executer.CheckOutActionExecuter; +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.rule.Rule; +import org.apache.commons.collections.CollectionUtils; + +@Experimental +public class ActionPermissionValidator +{ + private final RuntimeActionService runtimeActionService; + + public ActionPermissionValidator(RuntimeActionService runtimeActionService) + { + this.runtimeActionService = runtimeActionService; + } + + Rule validateRulePermissions(Rule rule) + { + final List actions = ((CompositeActionImpl) rule.getAction()).getActions(); + + checkRestrictedAccessActions(actions); + checkRuleOutboundHasNoCheckOutAction(rule, actions); + return rule; + } + + private void checkRestrictedAccessActions(List actions) { + actions.forEach(action -> { + ActionAccessRestriction.setActionContext(action, ActionAccessRestriction.RULE_ACTION_CONTEXT); + runtimeActionService.verifyActionAccessRestrictions(action); + }); + } + + private void checkRuleOutboundHasNoCheckOutAction(Rule rule, List actions) { + //TODO: rule types should never be empty in final implementation + if (CollectionUtils.isNotEmpty(rule.getRuleTypes()) && rule.getRuleTypes().contains(OUTBOUND)) + { + for (Action action : actions) + { + if (action.getActionDefinitionName().equalsIgnoreCase(CheckOutActionExecuter.NAME)) + { + throw new InvalidArgumentException(CANNOT_CREATE_RULE); + } + } + } + } + +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RulesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RulesImpl.java index bde57033f5..81a3c141ee 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RulesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RulesImpl.java @@ -37,6 +37,7 @@ import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.ListPage; import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.CompositeAction; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.rule.RuleService; import org.slf4j.Logger; @@ -51,6 +52,8 @@ public class RulesImpl implements Rules private RuleService ruleService; private NodeValidator validator; private RuleLoader ruleLoader; + private ActionParameterConverter actionParameterConverter; + private ActionPermissionValidator actionPermissionValidator; @Override public CollectionWithPagingInfo getRules(final String folderNodeId, @@ -62,8 +65,8 @@ public class RulesImpl implements Rules validator.validateRuleSetNode(ruleSetId, folderNodeRef); final List rules = ruleService.getRules(folderNodeRef).stream() - .map(ruleModel -> ruleLoader.loadRule(ruleModel, includes)) - .collect(Collectors.toList()); + .map(ruleModel -> ruleLoader.loadRule(ruleModel, includes)) + .collect(Collectors.toList()); return ListPage.of(rules, paging); } @@ -89,10 +92,10 @@ public class RulesImpl implements Rules } return rules.stream() - .map(rule -> rule.toServiceModel(nodes)) - .map(rule -> ruleService.saveRule(folderNodeRef, rule)) - .map(rule -> ruleLoader.loadRule(rule, includes)) - .collect(Collectors.toList()); + .map(this::mapToServiceModelAndValidateActions) + .map(rule -> ruleService.saveRule(folderNodeRef, rule)) + .map(rule -> ruleLoader.loadRule(rule, includes)) + .collect(Collectors.toList()); } @Override @@ -117,6 +120,16 @@ public class RulesImpl implements Rules ruleService.removeRule(folderNodeRef, rule); } + private org.alfresco.service.cmr.rule.Rule mapToServiceModelAndValidateActions(Rule rule) + { + final org.alfresco.service.cmr.rule.Rule serviceModelRule = rule.toServiceModel(nodes); + final CompositeAction compositeAction = (CompositeAction) serviceModelRule.getAction(); + compositeAction.getActions().forEach(action -> action.setParameterValues( + actionParameterConverter.getConvertedParams(action.getParameterValues(), action.getActionDefinitionName()))); + + return actionPermissionValidator.validateRulePermissions(serviceModelRule); + } + public void setNodes(Nodes nodes) { this.nodes = nodes; @@ -136,4 +149,14 @@ public class RulesImpl implements Rules { this.ruleLoader = ruleLoader; } + + public void setActionParameterConverter(ActionParameterConverter actionParameterConverter) + { + this.actionParameterConverter = actionParameterConverter; + } + + public void setActionPermissionValidator(ActionPermissionValidator actionPermissionValidator) + { + this.actionPermissionValidator = actionPermissionValidator; + } } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/Action.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/Action.java index d7d6ca0e0e..7aea6c560f 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/Action.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/Action.java @@ -34,7 +34,6 @@ import java.util.Objects; import org.alfresco.repo.action.ActionImpl; import org.alfresco.repo.action.CompositeActionImpl; -import org.alfresco.repo.action.executer.SetPropertyValueActionExecuter; import org.alfresco.service.Experimental; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.util.GUID; @@ -75,7 +74,7 @@ public class Action */ public org.alfresco.service.cmr.action.Action toServiceModel(final NodeRef nodeRef) { - return new ActionImpl(nodeRef, GUID.generate(), SetPropertyValueActionExecuter.NAME, params); + return new ActionImpl(nodeRef, GUID.generate(), this.actionDefinitionId, params); } /** diff --git a/remote-api/src/main/resources/alfresco/public-rest-context.xml b/remote-api/src/main/resources/alfresco/public-rest-context.xml index 074af5be3b..f00f9bf063 100644 --- a/remote-api/src/main/resources/alfresco/public-rest-context.xml +++ b/remote-api/src/main/resources/alfresco/public-rest-context.xml @@ -891,11 +891,23 @@ + + + + + + + + + + - + + + diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionParameterConverterTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionParameterConverterTest.java new file mode 100644 index 0000000000..0b7be657d8 --- /dev/null +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionParameterConverterTest.java @@ -0,0 +1,563 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rest.api.impl.rules; + +import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.times; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.repo.action.executer.AddFeaturesActionExecuter; +import org.alfresco.repo.action.executer.CheckInActionExecuter; +import org.alfresco.repo.action.executer.CheckOutActionExecuter; +import org.alfresco.repo.action.executer.CopyActionExecuter; +import org.alfresco.repo.action.executer.LinkCategoryActionExecuter; +import org.alfresco.repo.action.executer.MoveActionExecuter; +import org.alfresco.repo.action.executer.RemoveFeaturesActionExecuter; +import org.alfresco.repo.action.executer.ScriptActionExecuter; +import org.alfresco.repo.action.executer.SetPropertyValueActionExecuter; +import org.alfresco.repo.action.executer.SimpleWorkflowActionExecuter; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.ActionDefinition; +import org.alfresco.service.cmr.action.ActionService; +import org.alfresco.service.cmr.action.ParameterDefinition; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@Experimental +@RunWith(MockitoJUnitRunner.class) +public class ActionParameterConverterTest +{ + private static final String VERSIONABLE = "versionable"; + private static final String VERSIONABLE_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + VERSIONABLE; + private static final String CHECKOUT = "checkout"; + private static final String CHECKOUT_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + CHECKOUT; + private static final String CONTAINS = "contains"; + private static final String CONTAINS_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + CONTAINS; + private static final String CLASSIFIABLE = "generalclassifiable"; + private static final String CLASSIFIABLE_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + CLASSIFIABLE; + private static final String IDENTIFIER = "identifier"; + private static final String IDENTIFIER_ASPECT = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + IDENTIFIER; + + private static final String DUMMY_FOLDER_NODE_ID = "dummy-folder-node"; + private static final String DUMMY_FOLDER_NODE_REF = STORE_REF_WORKSPACE_SPACESSTORE + "/" + DUMMY_FOLDER_NODE_ID; + private static final String DUMMY_SCRIPT_NODE_ID = "dummy-script-ref"; + private static final String DUMMY_SCRIPT_NODE_REF = STORE_REF_WORKSPACE_SPACESSTORE + "/" + DUMMY_SCRIPT_NODE_ID; + + + @Mock + private DictionaryService dictionaryService; + @Mock + private ActionService actionService; + @Mock + private NamespaceService namespaceService; + + @Mock + private ActionDefinition actionDefinition; + @Mock + private ParameterDefinition actionDefinitionParam1; + @Mock + private ParameterDefinition actionDefinitionParam2; + @Mock + private ParameterDefinition actionDefinitionParam3; + @Mock + private DataTypeDefinition dataTypeDefinition1; + @Mock + private DataTypeDefinition dataTypeDefinition2; + @Mock + private DataTypeDefinition dataTypeDefinition3; + + @InjectMocks + private ActionParameterConverter objectUnderTest; + + @Test + public void testAddAspectConversion() + { + final String name = AddFeaturesActionExecuter.NAME; + final String aspectNameKey = AddFeaturesActionExecuter.PARAM_ASPECT_NAME; + final Map params = Map.of(aspectNameKey, VERSIONABLE_ASPECT); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(aspectNameKey)).willReturn(actionDefinitionParam1); + final QName qname = DataTypeDefinition.QNAME; + given(actionDefinitionParam1.getType()).willReturn(qname); + given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition1); + given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(aspectNameKey); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should().getDataType(qname); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).should().getNamespaceURI(any()); + then(namespaceService).shouldHaveNoMoreInteractions(); + + final Serializable convertedParam = convertedParams.get(aspectNameKey); + assertTrue(convertedParam instanceof QName); + assertEquals(VERSIONABLE, ((QName) convertedParam).getLocalName()); + assertEquals(VERSIONABLE_ASPECT, ((QName) convertedParam).getPrefixString()); + assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedParam).getNamespaceURI()); + } + + @Test + public void testCopyConversion() + { + final String name = CopyActionExecuter.NAME; + final String destinationFolderKey = CopyActionExecuter.PARAM_DESTINATION_FOLDER; + final String deepCopyKey = CopyActionExecuter.PARAM_DEEP_COPY; + final Map params = Map.of(destinationFolderKey, DUMMY_FOLDER_NODE_REF, deepCopyKey, true); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(destinationFolderKey)).willReturn(actionDefinitionParam1); + given(actionDefinition.getParameterDefintion(deepCopyKey)).willReturn(actionDefinitionParam2); + final QName nodeRef = DataTypeDefinition.NODE_REF; + given(actionDefinitionParam1.getType()).willReturn(nodeRef); + final QName bool = DataTypeDefinition.BOOLEAN; + given(actionDefinitionParam2.getType()).willReturn(bool); + + given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1); + given(dataTypeDefinition1.getJavaClassName()).willReturn(NodeRef.class.getName()); + given(dictionaryService.getDataType(bool)).willReturn(dataTypeDefinition2); + given(dataTypeDefinition2.getJavaClassName()).willReturn(Boolean.class.getName()); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(destinationFolderKey); + then(actionDefinition).should().getParameterDefintion(deepCopyKey); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should(times(2)).getDataType(bool); + then(dictionaryService).should(times(2)).getDataType(nodeRef); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).shouldHaveNoInteractions(); + + final Serializable convertedCopyParam = convertedParams.get(destinationFolderKey); + assertTrue(convertedCopyParam instanceof NodeRef); + assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedCopyParam).getStoreRef()); + assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedCopyParam).getId()); + final Serializable convertedDeepCopyParam = convertedParams.get(deepCopyKey); + assertThat(convertedDeepCopyParam instanceof Boolean).isTrue(); + assertTrue(((Boolean) convertedDeepCopyParam)); + } + + @Test + public void testExecuteScriptConversion() + { + final String name = ScriptActionExecuter.NAME; + final String executeScriptKey = ScriptActionExecuter.PARAM_SCRIPTREF; + final Map params = Map.of(executeScriptKey, DUMMY_SCRIPT_NODE_REF); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(executeScriptKey)).willReturn(actionDefinitionParam1); + final QName scriptNodeRef = DataTypeDefinition.NODE_REF; + given(actionDefinitionParam1.getType()).willReturn(scriptNodeRef); + + given(dictionaryService.getDataType(scriptNodeRef)).willReturn(dataTypeDefinition1); + given(dataTypeDefinition1.getJavaClassName()).willReturn(NodeRef.class.getName()); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(executeScriptKey); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should(times(2)).getDataType(scriptNodeRef); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).shouldHaveNoInteractions(); + + final Serializable convertedCopyParam = convertedParams.get(executeScriptKey); + assertTrue(convertedCopyParam instanceof NodeRef); + assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedCopyParam).getStoreRef()); + assertEquals(DUMMY_SCRIPT_NODE_ID, ((NodeRef) convertedCopyParam).getId()); + } + + @Test + public void testMoveConversion() + { + final String name = MoveActionExecuter.NAME; + final String destinationFolderKey = MoveActionExecuter.PARAM_DESTINATION_FOLDER; + final Map params = Map.of(destinationFolderKey, DUMMY_FOLDER_NODE_REF); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(destinationFolderKey)).willReturn(actionDefinitionParam1); + final QName nodeRef = DataTypeDefinition.NODE_REF; + given(actionDefinitionParam1.getType()).willReturn(nodeRef); + + given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1); + given(dataTypeDefinition1.getJavaClassName()).willReturn(NodeRef.class.getName()); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(destinationFolderKey); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should(times(2)).getDataType(nodeRef); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).shouldHaveNoInteractions(); + + final Serializable convertedCopyParam = convertedParams.get(destinationFolderKey); + assertTrue(convertedCopyParam instanceof NodeRef); + assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedCopyParam).getStoreRef()); + assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedCopyParam).getId()); + } + + @Test + public void testCheckInConversion() + { + final String name = CheckInActionExecuter.NAME; + final String descriptionKey = CheckInActionExecuter.PARAM_DESCRIPTION; + final String minorChangeKey = CheckInActionExecuter.PARAM_MINOR_CHANGE; + String description = "dummy description"; + final Map params = Map.of(descriptionKey, description, minorChangeKey, true); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(descriptionKey)).willReturn(actionDefinitionParam1); + given(actionDefinition.getParameterDefintion(minorChangeKey)).willReturn(actionDefinitionParam2); + final QName text = DataTypeDefinition.TEXT; + given(actionDefinitionParam1.getType()).willReturn(text); + final QName bool = DataTypeDefinition.BOOLEAN; + given(actionDefinitionParam2.getType()).willReturn(bool); + + given(dictionaryService.getDataType(text)).willReturn(dataTypeDefinition1); + given(dataTypeDefinition1.getJavaClassName()).willReturn(String.class.getName()); + given(dictionaryService.getDataType(bool)).willReturn(dataTypeDefinition2); + given(dataTypeDefinition2.getJavaClassName()).willReturn(Boolean.class.getName()); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(descriptionKey); + then(actionDefinition).should().getParameterDefintion(minorChangeKey); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should(times(2)).getDataType(bool); + then(dictionaryService).should(times(2)).getDataType(text); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).shouldHaveNoInteractions(); + + final Serializable convertedDescriptionParam = convertedParams.get(descriptionKey); + assertTrue(convertedDescriptionParam instanceof String); + assertEquals(description, convertedDescriptionParam); + final Serializable convertedMinorChangeParam = convertedParams.get(minorChangeKey); + assertTrue(convertedMinorChangeParam instanceof Boolean); + assertTrue((Boolean) convertedMinorChangeParam); + } + + @Test + public void testCheckOutConversion() + { + final String name = CheckOutActionExecuter.NAME; + final String destinationFolderKey = CheckOutActionExecuter.PARAM_DESTINATION_FOLDER; + final String assocNameKey = CheckOutActionExecuter.PARAM_ASSOC_QNAME; + final String assocTypeKey = CheckOutActionExecuter.PARAM_ASSOC_TYPE_QNAME; + final Map params = + Map.of(destinationFolderKey, DUMMY_FOLDER_NODE_REF, assocNameKey, CHECKOUT_ASPECT, assocTypeKey, CONTAINS_ASPECT); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(destinationFolderKey)).willReturn(actionDefinitionParam1); + final QName nodeRef = DataTypeDefinition.NODE_REF; + given(actionDefinitionParam1.getType()).willReturn(nodeRef); + given(actionDefinition.getParameterDefintion(assocNameKey)).willReturn(actionDefinitionParam2); + final QName qname = DataTypeDefinition.QNAME; + given(actionDefinitionParam2.getType()).willReturn(qname); + given(actionDefinition.getParameterDefintion(assocTypeKey)).willReturn(actionDefinitionParam3); + given(actionDefinitionParam3.getType()).willReturn(qname); + + given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1); + given(dataTypeDefinition1.getJavaClassName()).willReturn(NodeRef.class.getName()); + given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition2); + given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(destinationFolderKey); + then(actionDefinition).should().getParameterDefintion(assocNameKey); + then(actionDefinition).should().getParameterDefintion(assocTypeKey); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should(times(2)).getDataType(qname); + then(dictionaryService).should(times(2)).getDataType(nodeRef); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).should(times(2)).getNamespaceURI(any()); + then(namespaceService).shouldHaveNoMoreInteractions(); + + final Serializable convertedDestinationParam = convertedParams.get(destinationFolderKey); + assertTrue(convertedDestinationParam instanceof NodeRef); + assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedDestinationParam).getStoreRef()); + assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedDestinationParam).getId()); + final Serializable convertedAssocNameParam = convertedParams.get(assocNameKey); + assertTrue(convertedAssocNameParam instanceof QName); + assertEquals(CHECKOUT, ((QName) convertedAssocNameParam).getLocalName()); + assertEquals(CHECKOUT_ASPECT, ((QName) convertedAssocNameParam).getPrefixString()); + assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedAssocNameParam).getNamespaceURI()); + final Serializable convertedAssocTypeParam = convertedParams.get(assocTypeKey); + assertTrue(convertedAssocTypeParam instanceof QName); + assertEquals(CONTAINS, ((QName) convertedAssocTypeParam).getLocalName()); + assertEquals(CONTAINS_ASPECT, ((QName) convertedAssocTypeParam).getPrefixString()); + assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedAssocTypeParam).getNamespaceURI()); + } + + @Test + public void testCategoryLinkConversion() + { + final String name = LinkCategoryActionExecuter.NAME; + final String categoryAspectKey = LinkCategoryActionExecuter.PARAM_CATEGORY_ASPECT; + final String categoryValueKey = LinkCategoryActionExecuter.PARAM_CATEGORY_VALUE; + final Map params = Map.of(categoryAspectKey, CLASSIFIABLE_ASPECT, categoryValueKey, DUMMY_FOLDER_NODE_REF); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(categoryAspectKey)).willReturn(actionDefinitionParam1); + final QName qname = DataTypeDefinition.QNAME; + given(actionDefinitionParam1.getType()).willReturn(qname); + given(actionDefinition.getParameterDefintion(categoryValueKey)).willReturn(actionDefinitionParam2); + final QName nodeRef = DataTypeDefinition.NODE_REF; + given(actionDefinitionParam2.getType()).willReturn(nodeRef); + + given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1); + given(dataTypeDefinition1.getJavaClassName()).willReturn(NodeRef.class.getName()); + given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition2); + given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(categoryAspectKey); + then(actionDefinition).should().getParameterDefintion(categoryValueKey); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should().getDataType(qname); + then(dictionaryService).should(times(2)).getDataType(nodeRef); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).should().getNamespaceURI(any()); + then(namespaceService).shouldHaveNoMoreInteractions(); + + final Serializable convertedCatValueParam = convertedParams.get(categoryAspectKey); + assertTrue(convertedCatValueParam instanceof QName); + assertEquals(CLASSIFIABLE, ((QName) convertedCatValueParam).getLocalName()); + assertEquals(CLASSIFIABLE_ASPECT, ((QName) convertedCatValueParam).getPrefixString()); + assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedCatValueParam).getNamespaceURI()); + final Serializable convertedDestinationParam = convertedParams.get(categoryValueKey); + assertTrue(convertedDestinationParam instanceof NodeRef); + assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedDestinationParam).getStoreRef()); + assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedDestinationParam).getId()); + } + + @Test + public void testRemoveAspectConversion() + { + final String name = RemoveFeaturesActionExecuter.NAME; + final String aspectNameKey = RemoveFeaturesActionExecuter.PARAM_ASPECT_NAME; + final Map params = Map.of(aspectNameKey, VERSIONABLE_ASPECT); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(aspectNameKey)).willReturn(actionDefinitionParam1); + final QName qname = DataTypeDefinition.QNAME; + given(actionDefinitionParam1.getType()).willReturn(qname); + given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition1); + given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(aspectNameKey); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should().getDataType(qname); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).should().getNamespaceURI(any()); + then(namespaceService).shouldHaveNoMoreInteractions(); + + final Serializable convertedParam = convertedParams.get(aspectNameKey); + assertTrue(convertedParam instanceof QName); + assertEquals(VERSIONABLE, ((QName) convertedParam).getLocalName()); + assertEquals(VERSIONABLE_ASPECT, ((QName) convertedParam).getPrefixString()); + assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedParam).getNamespaceURI()); + } + + @Test + public void testAddWorkflowConversion() + { + final String name = SimpleWorkflowActionExecuter.NAME; + final String approveStepKey = SimpleWorkflowActionExecuter.PARAM_APPROVE_STEP; + final String approveFolderKey = SimpleWorkflowActionExecuter.PARAM_APPROVE_FOLDER; + final String approveMoveKey = SimpleWorkflowActionExecuter.PARAM_APPROVE_MOVE; + final String rejectStepKey = SimpleWorkflowActionExecuter.PARAM_REJECT_STEP; + final String rejectFolderKey = SimpleWorkflowActionExecuter.PARAM_REJECT_FOLDER; + final String rejectMoveKey = SimpleWorkflowActionExecuter.PARAM_REJECT_MOVE; + final String approve = "Approve"; + final String reject = "Reject"; + final Map params = + Map.of(approveStepKey, approve, approveFolderKey, DUMMY_FOLDER_NODE_REF, approveMoveKey, true, + rejectStepKey, reject, rejectFolderKey, DUMMY_FOLDER_NODE_REF, rejectMoveKey, true); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(rejectStepKey)).willReturn(actionDefinitionParam1); + given(actionDefinition.getParameterDefintion(approveStepKey)).willReturn(actionDefinitionParam1); + final QName text = DataTypeDefinition.TEXT; + given(actionDefinitionParam1.getType()).willReturn(text, text); + given(actionDefinition.getParameterDefintion(rejectFolderKey)).willReturn(actionDefinitionParam2); + given(actionDefinition.getParameterDefintion(approveFolderKey)).willReturn(actionDefinitionParam2); + final QName nodeRef = DataTypeDefinition.NODE_REF; + given(actionDefinitionParam2.getType()).willReturn(nodeRef, nodeRef); + given(actionDefinition.getParameterDefintion(rejectMoveKey)).willReturn(actionDefinitionParam3); + given(actionDefinition.getParameterDefintion(approveMoveKey)).willReturn(actionDefinitionParam3); + final QName bool = DataTypeDefinition.BOOLEAN; + given(actionDefinitionParam3.getType()).willReturn(bool, bool); + + given(dictionaryService.getDataType(nodeRef)).willReturn(dataTypeDefinition1); + given(dataTypeDefinition1.getJavaClassName()).willReturn(NodeRef.class.getName()); + given(dictionaryService.getDataType(text)).willReturn(dataTypeDefinition2); + given(dataTypeDefinition2.getJavaClassName()).willReturn(String.class.getName()); + given(dictionaryService.getDataType(bool)).willReturn(dataTypeDefinition3); + given(dataTypeDefinition3.getJavaClassName()).willReturn(Boolean.class.getName()); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(approveStepKey); + then(actionDefinition).should().getParameterDefintion(approveFolderKey); + then(actionDefinition).should().getParameterDefintion(approveMoveKey); + then(actionDefinition).should().getParameterDefintion(rejectStepKey); + then(actionDefinition).should().getParameterDefintion(rejectFolderKey); + then(actionDefinition).should().getParameterDefintion(rejectMoveKey); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should(times(4)).getDataType(text); + then(dictionaryService).should(times(4)).getDataType(nodeRef); + then(dictionaryService).should(times(4)).getDataType(bool); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).shouldHaveNoInteractions(); + + final Serializable convertedApproveStepParam = convertedParams.get(approveStepKey); + assertTrue(convertedApproveStepParam instanceof String); + assertEquals(approve, convertedApproveStepParam); + final Serializable convertedRejectStepParam = convertedParams.get(rejectStepKey); + assertTrue(convertedRejectStepParam instanceof String); + assertEquals(reject, convertedRejectStepParam); + final Serializable convertedApproveFolderParam = convertedParams.get(approveFolderKey); + assertTrue(convertedApproveFolderParam instanceof NodeRef); + assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedApproveFolderParam).getStoreRef()); + assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedApproveFolderParam).getId()); + final Serializable convertedRejectFolderParam = convertedParams.get(rejectFolderKey); + assertTrue(convertedRejectFolderParam instanceof NodeRef); + assertEquals(STORE_REF_WORKSPACE_SPACESSTORE, ((NodeRef) convertedRejectFolderParam).getStoreRef()); + assertEquals(DUMMY_FOLDER_NODE_ID, ((NodeRef) convertedRejectFolderParam).getId()); + final Serializable convertedApproveMoveParam = convertedParams.get(approveMoveKey); + assertTrue(convertedApproveMoveParam instanceof Boolean); + assertTrue((Boolean) convertedApproveMoveParam); + final Serializable convertedRejectMoveParam = convertedParams.get(rejectMoveKey); + assertTrue(convertedRejectMoveParam instanceof Boolean); + assertTrue((Boolean) convertedRejectMoveParam); + } + + @Test + public void testSetPropertyConversion() + { + final String name = SetPropertyValueActionExecuter.NAME; + final String propertyNameKey = SetPropertyValueActionExecuter.PARAM_PROPERTY; + final String propertyValueKey = SetPropertyValueActionExecuter.PARAM_VALUE; + final String propertyTypeKey = "prop_type"; + final String dummy_key_value = "dummy_key_value"; + final String propType = "d:text"; + final Map params = + Map.of(propertyNameKey, IDENTIFIER_ASPECT, propertyValueKey, dummy_key_value, propertyTypeKey, propType); + + given(actionService.getActionDefinition(name)).willReturn(actionDefinition); + given(actionDefinition.getParameterDefintion(propertyNameKey)).willReturn(actionDefinitionParam1); + final QName qname = DataTypeDefinition.QNAME; + given(actionDefinitionParam1.getType()).willReturn(qname); + given(actionDefinition.getParameterDefintion(propertyValueKey)).willReturn(actionDefinitionParam2); + final QName any = DataTypeDefinition.ANY; + given(actionDefinitionParam2.getType()).willReturn(any); + given(actionDefinition.getParameterDefintion(propertyTypeKey)).willReturn(null); + given(actionDefinition.getAdhocPropertiesAllowed()).willReturn(true); + + given(dictionaryService.getDataType(qname)).willReturn(dataTypeDefinition1); + given(dictionaryService.getDataType(any)).willReturn(dataTypeDefinition2); + given(dataTypeDefinition2.getJavaClassName()).willReturn(Object.class.getName()); + given(namespaceService.getNamespaceURI(any())).willReturn(NamespaceService.DICTIONARY_MODEL_1_0_URI); + + //when + final Map convertedParams = objectUnderTest.getConvertedParams(params, name); + + then(actionService).should().getActionDefinition(name); + then(actionService).shouldHaveNoMoreInteractions(); + then(actionDefinition).should().getParameterDefintion(propertyNameKey); + then(actionDefinition).should().getParameterDefintion(propertyValueKey); + then(actionDefinition).should().getParameterDefintion(propertyTypeKey); + then(actionDefinition).should().getAdhocPropertiesAllowed(); + then(actionDefinition).shouldHaveNoMoreInteractions(); + then(dictionaryService).should().getDataType(qname); + then(dictionaryService).should(times(2)).getDataType(any); + then(dictionaryService).shouldHaveNoMoreInteractions(); + then(namespaceService).should().getNamespaceURI(any()); + then(namespaceService).shouldHaveNoMoreInteractions(); + + final Serializable convertedPropNameParam = convertedParams.get(propertyNameKey); + assertTrue(convertedPropNameParam instanceof QName); + assertEquals(IDENTIFIER, ((QName) convertedPropNameParam).getLocalName()); + assertEquals(IDENTIFIER_ASPECT, ((QName) convertedPropNameParam).getPrefixString()); + assertEquals(NamespaceService.DICTIONARY_MODEL_1_0_URI, ((QName) convertedPropNameParam).getNamespaceURI()); + + final Serializable convertedPropValParam = convertedParams.get(propertyValueKey); + assertTrue(convertedPropValParam instanceof String); + assertEquals(dummy_key_value, convertedPropValParam); + final Serializable convertedPropTypeParam = convertedParams.get(propertyTypeKey); + assertTrue(convertedPropTypeParam instanceof String); + assertEquals(propType, convertedPropTypeParam); + } +} diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionPermissionValidatorTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionPermissionValidatorTest.java new file mode 100644 index 0000000000..12be2eba6d --- /dev/null +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionPermissionValidatorTest.java @@ -0,0 +1,84 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rest.api.impl.rules; + +import static org.mockito.BDDMockito.then; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; +import org.alfresco.repo.action.ActionImpl; +import org.alfresco.repo.action.CompositeActionImpl; +import org.alfresco.repo.action.RuntimeActionService; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.rule.Rule; +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@Experimental +@RunWith(MockitoJUnitRunner.class) +public class ActionPermissionValidatorTest extends TestCase +{ + private static final String DUMMY_NODE_ID = "dummy-node-id"; + @Mock + private RuntimeActionService runtimeActionService; + + @InjectMocks + private ActionPermissionValidator objectUnderTest; + + @Test + public void testPositiveRulePermissionValidation() { + //given + final CompositeActionImpl compositeAction = new CompositeActionImpl(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID), "composite-id"); + final Action action1 = new ActionImpl(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID), "id-1", "actionDef-1"); + compositeAction.addAction(action1); + final Action action2 = new ActionImpl(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID), "id-2", "actionDef-2"); + compositeAction.addAction(action2); + final Rule inputRule = new Rule(); + inputRule.setAction(compositeAction); + + //when + final Rule validatedRule = objectUnderTest.validateRulePermissions(inputRule); + + then(runtimeActionService).should().verifyActionAccessRestrictions(action1); + then(runtimeActionService).should().verifyActionAccessRestrictions(action2); + then(runtimeActionService).shouldHaveNoMoreInteractions(); + + ((CompositeActionImpl) validatedRule.getAction()).getActions() + .forEach(action -> Assertions.assertThat(action.getParameterValue("actionContext")).isEqualTo("rule")); + } + + //TODO: when Rule mappings are done - we need to add negative test(s) here +} diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RulesImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RulesImplTest.java index 0af930be76..4300376fb4 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RulesImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RulesImplTest.java @@ -36,13 +36,18 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.stream.IntStream; import junit.framework.TestCase; +import org.alfresco.repo.action.ActionImpl; +import org.alfresco.repo.action.CompositeActionImpl; import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.model.rules.Rule; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; @@ -52,6 +57,7 @@ import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundE import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.CompositeAction; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.rule.RuleService; @@ -61,7 +67,6 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnitRunner; @Experimental @@ -76,6 +81,8 @@ public class RulesImplTest extends TestCase private static final NodeRef RULE_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID); private static final Paging PAGING = Paging.DEFAULT; private static final List INCLUDE = emptyList(); + private static final String ACTION_DEFINITION_NAME = "actionDefinitionName"; + private static final Map DUMMY_PARAMS = Map.of("dummy-key", "dummy-value"); @Mock private Nodes nodesMock; @@ -85,17 +92,24 @@ public class RulesImplTest extends TestCase private RuleService ruleServiceMock; @Mock private RuleLoader ruleLoaderMock; - @InjectMocks - private RulesImpl rules; + @Mock + private ActionParameterConverter actionParameterConverterMock; + @Mock + private ActionPermissionValidator actionPermissionValidatorMock; + @Mock + private org.alfresco.service.cmr.rule.Rule serviceRuleMock; @Mock private Rule ruleMock; private org.alfresco.service.cmr.rule.Rule ruleModel = createRule(RULE_ID); + private CompositeAction compositeAction = new CompositeActionImpl(RULE_NODE_REF, "compositeActionId"); + + @InjectMocks + private RulesImpl rules; @Before @Override public void setUp() throws Exception { - MockitoAnnotations.openMocks(this); given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(FOLDER_NODE_REF); given(nodeValidatorMock.validateRuleSetNode(any(), any())).willReturn(RULE_SET_NODE_REF); given(nodeValidatorMock.validateRuleNode(any(), any())).willReturn(RULE_NODE_REF); @@ -104,6 +118,8 @@ public class RulesImplTest extends TestCase given(ruleServiceMock.getRules(FOLDER_NODE_REF)).willReturn(List.of(ruleModel)); given(ruleLoaderMock.loadRule(ruleModel, INCLUDE)).willReturn(ruleMock); + + compositeAction.addAction(new ActionImpl(FOLDER_NODE_REF, "actionId", ACTION_DEFINITION_NAME, DUMMY_PARAMS)); } @Test @@ -119,9 +135,9 @@ public class RulesImplTest extends TestCase then(ruleServiceMock).shouldHaveNoMoreInteractions(); assertThat(rulesPage) .isNotNull() - .extracting(CollectionWithPagingInfo::getCollection) + .extracting(CollectionWithPagingInfo::getCollection) .isNotNull() - .extracting(Collection::size) + .extracting(Collection::size) .isEqualTo(1); assertThat(rulesPage.getCollection().stream().findFirst().get()).isEqualTo(ruleMock); } @@ -137,11 +153,11 @@ public class RulesImplTest extends TestCase then(ruleServiceMock).should().getRules(FOLDER_NODE_REF); then(ruleServiceMock).shouldHaveNoMoreInteractions(); assertThat(rulesPage) - .isNotNull() - .extracting(CollectionWithPagingInfo::getCollection) - .isNotNull() - .extracting(Collection::isEmpty) - .isEqualTo(true); + .isNotNull() + .extracting(CollectionWithPagingInfo::getCollection) + .isNotNull() + .extracting(Collection::isEmpty) + .isEqualTo(true); } @Test @@ -154,7 +170,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING)); + () -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false); then(nodeValidatorMock).shouldHaveNoMoreInteractions(); @@ -173,7 +189,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING)); + () -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false); then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF); @@ -208,7 +224,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID, INCLUDE)); + () -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID, INCLUDE)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false); then(nodeValidatorMock).shouldHaveNoMoreInteractions(); @@ -227,7 +243,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID, INCLUDE)); + () -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID, INCLUDE)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false); then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF); @@ -248,7 +264,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID, INCLUDE)); + () -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID, INCLUDE)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false); then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF); @@ -258,17 +274,18 @@ public class RulesImplTest extends TestCase } } - /** Create a single rule. */ + /** + * Create a single rule. + */ @Test public void testCreateRules() { - Rule ruleBody = mock(Rule.class); - List ruleList = List.of(ruleBody); - org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class); - given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody); - org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class); - given(ruleServiceMock.saveRule(FOLDER_NODE_REF, serviceRuleBody)).willReturn(serviceRule); - given(ruleLoaderMock.loadRule(serviceRule, INCLUDE)).willReturn(ruleMock); + List ruleList = List.of(ruleMock); + given(ruleMock.toServiceModel(nodesMock)).willReturn(serviceRuleMock); + given(serviceRuleMock.getAction()).willReturn(compositeAction); + given(ruleServiceMock.saveRule(FOLDER_NODE_REF, serviceRuleMock)).willAnswer(arg -> arg.getArguments()[1]); + given(ruleLoaderMock.loadRule(serviceRuleMock, INCLUDE)).willReturn(ruleMock); + given(actionPermissionValidatorMock.validateRulePermissions(any())).willAnswer(arg -> arg.getArguments()[0]); // when List actual = rules.createRules(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), ruleList, INCLUDE); @@ -276,32 +293,42 @@ public class RulesImplTest extends TestCase then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF); then(nodeValidatorMock).shouldHaveNoMoreInteractions(); - then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleBody.toServiceModel(nodesMock)); + then(actionParameterConverterMock).should().getConvertedParams(DUMMY_PARAMS, ACTION_DEFINITION_NAME); + then(actionParameterConverterMock).shouldHaveNoMoreInteractions(); + then(actionPermissionValidatorMock).should().validateRulePermissions(serviceRuleMock); + then(actionPermissionValidatorMock).shouldHaveNoMoreInteractions(); + then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleMock.toServiceModel(nodesMock)); then(ruleServiceMock).shouldHaveNoMoreInteractions(); List expected = List.of(ruleMock); assertThat(actual).isEqualTo(expected); } - /** Check that when passing the default rule set then we don't perform any validation around the rule set node. */ + /** + * Check that when passing the default rule set then we don't perform any validation around the rule set node. + */ @Test public void testCreateRules_defaultRuleSet() { - Rule ruleBody = mock(Rule.class); - List ruleList = List.of(ruleBody); - org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class); - given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody); - org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class); - given(ruleServiceMock.saveRule(FOLDER_NODE_REF, serviceRuleBody)).willReturn(serviceRule); - given(ruleLoaderMock.loadRule(serviceRule, INCLUDE)).willReturn(ruleMock); + List ruleList = List.of(ruleMock); + given(ruleMock.toServiceModel(nodesMock)).willReturn(serviceRuleMock); + given(ruleServiceMock.saveRule(FOLDER_NODE_REF, serviceRuleMock)).willAnswer(arg -> arg.getArguments()[1]); + given(ruleLoaderMock.loadRule(serviceRuleMock, INCLUDE)).willReturn(ruleMock); + given(serviceRuleMock.getAction()).willReturn(compositeAction); + given(actionPermissionValidatorMock.validateRulePermissions(any())).willAnswer(arg -> arg.getArguments()[0]); // when List actual = rules.createRules(FOLDER_NODE_REF.getId(), DEFAULT_ID, ruleList, INCLUDE); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).shouldHaveNoMoreInteractions(); - then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleBody.toServiceModel(nodesMock)); + then(actionParameterConverterMock).should().getConvertedParams(DUMMY_PARAMS, ACTION_DEFINITION_NAME); + then(actionParameterConverterMock).shouldHaveNoMoreInteractions(); + then(actionPermissionValidatorMock).should().validateRulePermissions(serviceRuleMock); + then(actionPermissionValidatorMock).shouldHaveNoMoreInteractions(); + then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleMock.toServiceModel(nodesMock)); then(ruleServiceMock).shouldHaveNoMoreInteractions(); - assertThat(actual).isEqualTo(List.of(ruleMock)); + List expected = List.of(ruleMock); + assertThat(actual).isEqualTo(expected); } @Test @@ -316,22 +343,27 @@ public class RulesImplTest extends TestCase assertThat(actual).isEqualTo(emptyList()); } - /** Create three rules in a single call and check they are all passed to the RuleService. */ + /** + * Create three rules in a single call and check they are all passed to the RuleService. + */ @Test public void testCreateRules_createMultipleRules() { List ruleBodyList = new ArrayList<>(); List expected = new ArrayList<>(); IntStream.range(0, 3).forEach(i -> { - Rule ruleBody = mock(Rule.class); - ruleBodyList.add(ruleBody); - org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class); - given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody); - org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class); - given(ruleServiceMock.saveRule(FOLDER_NODE_REF, serviceRuleBody)).willReturn(serviceRule); - Rule ruleMock = mock(Rule.class); - given(ruleLoaderMock.loadRule(serviceRule, INCLUDE)).willReturn(ruleMock); - expected.add(ruleMock); + Rule ruleBodyMock = mock(Rule.class); + ruleBodyList.add(ruleBodyMock); + org.alfresco.service.cmr.rule.Rule serviceRuleMockInner = mock(org.alfresco.service.cmr.rule.Rule.class); + given(ruleBodyMock.toServiceModel(nodesMock)).willReturn(serviceRuleMockInner); + final CompositeAction compositeActionInner = new CompositeActionImpl(RULE_NODE_REF, "compositeActionInnerId"); + compositeActionInner.addAction(new ActionImpl(FOLDER_NODE_REF, "actionInnerId", ACTION_DEFINITION_NAME, DUMMY_PARAMS)); + given(serviceRuleMockInner.getAction()).willReturn(compositeActionInner); + given(ruleServiceMock.saveRule(FOLDER_NODE_REF, serviceRuleMockInner)).willAnswer(arg -> arg.getArguments()[1]); + Rule ruleMockInner = mock(Rule.class); + given(ruleLoaderMock.loadRule(serviceRuleMockInner, INCLUDE)).willReturn(ruleMockInner); + expected.add(ruleMockInner); + given(actionPermissionValidatorMock.validateRulePermissions(any())).willAnswer(arg -> arg.getArguments()[0]); }); // when @@ -342,8 +374,12 @@ public class RulesImplTest extends TestCase then(nodeValidatorMock).shouldHaveNoMoreInteractions(); for (Rule ruleBody : ruleBodyList) { + then(actionPermissionValidatorMock).should().validateRulePermissions(ruleBody.toServiceModel(nodesMock)); then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleBody.toServiceModel(nodesMock)); } + then(actionParameterConverterMock).should(times(3)).getConvertedParams(DUMMY_PARAMS, ACTION_DEFINITION_NAME); + then(actionParameterConverterMock).shouldHaveNoMoreInteractions(); + then(actionPermissionValidatorMock).shouldHaveNoMoreInteractions(); then(ruleServiceMock).shouldHaveNoMoreInteractions(); assertThat(actual).isEqualTo(expected); } @@ -358,7 +394,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.createRules(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), emptyList(), INCLUDE)); + () -> rules.createRules(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), emptyList(), INCLUDE)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).shouldHaveNoMoreInteractions(); @@ -377,7 +413,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.createRules(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), emptyList(), INCLUDE)); + () -> rules.createRules(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), emptyList(), INCLUDE)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF); @@ -386,7 +422,9 @@ public class RulesImplTest extends TestCase } } - /** Check that we can update a rule. */ + /** + * Check that we can update a rule. + */ @Test public void testUpdateRuleById() { @@ -419,7 +457,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.updateRuleById(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), RULE_ID, mock(Rule.class), INCLUDE)); + () -> rules.updateRuleById(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), RULE_ID, mock(Rule.class), INCLUDE)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).shouldHaveNoMoreInteractions(); @@ -438,7 +476,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.updateRuleById(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), RULE_ID, mock(Rule.class), INCLUDE)); + () -> rules.updateRuleById(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), RULE_ID, mock(Rule.class), INCLUDE)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF); @@ -459,7 +497,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.updateRuleById(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), RULE_ID, mock(Rule.class), INCLUDE)); + () -> rules.updateRuleById(FOLDER_NODE_REF.getId(), RULE_SET_NODE_REF.getId(), RULE_ID, mock(Rule.class), INCLUDE)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF); @@ -470,7 +508,8 @@ public class RulesImplTest extends TestCase } @Test - public void testDeleteRuleById() { + public void testDeleteRuleById() + { //when rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID); @@ -494,7 +533,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID)); + () -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).shouldHaveNoMoreInteractions(); @@ -513,7 +552,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID)); + () -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF); @@ -534,7 +573,7 @@ public class RulesImplTest extends TestCase // when assertThatExceptionOfType(exception.getClass()).isThrownBy( - () -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID)); + () -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID)); then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF); @@ -544,7 +583,8 @@ public class RulesImplTest extends TestCase } } - private static org.alfresco.service.cmr.rule.Rule createRule(final String id) { + private static org.alfresco.service.cmr.rule.Rule createRule(final String id) + { final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id); final org.alfresco.service.cmr.rule.Rule rule = new org.alfresco.service.cmr.rule.Rule(); rule.setNodeRef(nodeRef); @@ -556,27 +596,27 @@ public class RulesImplTest extends TestCase private static List folderValidationExceptions() { return List.of( - new EntityNotFoundException(FOLDER_NODE_ID), - new InvalidArgumentException(), - new PermissionDeniedException() + new EntityNotFoundException(FOLDER_NODE_ID), + new InvalidArgumentException(), + new PermissionDeniedException() ); } private static List ruleSetValidationExceptions() { return List.of( - new EntityNotFoundException(RULE_SET_ID), - new InvalidArgumentException(), - new RelationshipResourceNotFoundException(RULE_SET_ID, "fake-relationship-id") + new EntityNotFoundException(RULE_SET_ID), + new InvalidArgumentException(), + new RelationshipResourceNotFoundException(RULE_SET_ID, "fake-relationship-id") ); } private static List ruleValidationExceptions() { return List.of( - new EntityNotFoundException(RULE_ID), - new InvalidArgumentException(), - new RelationshipResourceNotFoundException(RULE_ID, "fake-relationship-id") + new EntityNotFoundException(RULE_ID), + new InvalidArgumentException(), + new RelationshipResourceNotFoundException(RULE_ID, "fake-relationship-id") ); } }