From 4bc36ae18de3dc625f408876ac2d9f611063a3c4 Mon Sep 17 00:00:00 2001 From: Maciej Pichura <41297682+mpichura@users.noreply.github.com> Date: Tue, 27 Sep 2022 15:24:39 +0200 Subject: [PATCH] ACS-3510 Rule mappers refactor pt3 (#1438) * ACS-3510: Rule mappers refactor pt3 (presumably final) * ACS-3510: Rule mappers refactor pt3 - fixes after master merge. * ACS-3510: Fixing error script conversion, adding some logging. --- .../rules/RestRuleActionModelMapper.java | 107 ++++++++ ...RestRuleCompositeConditionModelMapper.java | 15 +- .../mapper/rules/RestRuleModelMapper.java | 164 ++++++++++++ .../impl/rules/ActionParameterConverter.java | 2 +- .../rest/api/impl/rules/RuleLoader.java | 10 +- .../rest/api/impl/rules/RulesImpl.java | 44 +--- .../api/model/mapper/RestModelMapper.java | 11 +- .../alfresco/rest/api/model/rules/Action.java | 60 ----- .../alfresco/rest/api/model/rules/Rule.java | 86 ------ .../alfresco/public-rest-context.xml | 17 +- .../org/alfresco/rest/api/RulesUnitTests.java | 10 +- .../rules/RestRuleActionModelMapperTest.java | 125 +++++++++ ...RuleCompositeConditionModelMapperTest.java | 33 ++- .../mapper/rules/RestRuleModelMapperTest.java | 244 ++++++++++++++++++ ...estRuleSimpleConditionModelMapperTest.java | 2 +- .../rest/api/impl/rules/RuleLoaderTest.java | 46 +++- .../rest/api/impl/rules/RulesImplTest.java | 53 +--- .../rest/api/model/rules/ActionTest.java | 79 ------ .../rest/api/model/rules/RuleTest.java | 181 ------------- 19 files changed, 765 insertions(+), 524 deletions(-) create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleActionModelMapper.java create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapper.java create mode 100644 remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleActionModelMapperTest.java create mode 100644 remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapperTest.java delete mode 100644 remote-api/src/test/java/org/alfresco/rest/api/model/rules/ActionTest.java delete mode 100644 remote-api/src/test/java/org/alfresco/rest/api/model/rules/RuleTest.java diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleActionModelMapper.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleActionModelMapper.java new file mode 100644 index 0000000000..404a4528b1 --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleActionModelMapper.java @@ -0,0 +1,107 @@ +/* + * #%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.mapper.rules; + +import static org.alfresco.repo.action.access.ActionAccessRestriction.ACTION_CONTEXT_PARAM_NAME; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; + +import org.alfresco.repo.action.ActionImpl; +import org.alfresco.repo.action.CompositeActionImpl; +import org.alfresco.rest.api.impl.rules.ActionParameterConverter; +import org.alfresco.rest.api.model.mapper.RestModelMapper; +import org.alfresco.rest.api.model.rules.Action; +import org.alfresco.service.Experimental; +import org.alfresco.util.GUID; +import org.apache.commons.collections.CollectionUtils; + +@Experimental +public class RestRuleActionModelMapper implements RestModelMapper +{ + private final ActionParameterConverter parameterConverter; + + public RestRuleActionModelMapper(ActionParameterConverter parameterConverter) + { + this.parameterConverter = parameterConverter; + } + + /** + * Converts service POJO action to REST model action. + * + * @param actionModel - {@link org.alfresco.service.cmr.action.Action} service POJO + * @return {@link Action} REST model + */ + @Override + public Action toRestModel(org.alfresco.service.cmr.action.Action actionModel) + { + if (actionModel == null) + { + return null; + } + + final Action.Builder builder = Action.builder().actionDefinitionId(actionModel.getActionDefinitionName()); + if (actionModel.getParameterValues() != null) + { + final Map convertedParams = actionModel.getParameterValues() + .entrySet() + .stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> parameterConverter.convertParamFromServiceModel(e.getValue()))); + convertedParams.remove(ACTION_CONTEXT_PARAM_NAME); + builder.params(convertedParams); + } + return builder.create(); + } + + /** + * Convert the REST model objects to composite action service POJO. + * + * @param actions List of actions. + * @return The composite action service POJO. + */ + @Override + public org.alfresco.service.cmr.action.Action toServiceModel(Collection actions) + { + if (CollectionUtils.isEmpty(actions)) + { + return null; + } + + final org.alfresco.service.cmr.action.CompositeAction compositeAction = new CompositeActionImpl(null, GUID.generate()); + actions.forEach(action -> compositeAction.addAction(toServiceAction(action))); + return compositeAction; + } + + private org.alfresco.service.cmr.action.Action toServiceAction(Action action) + { + final Map convertedParams = + parameterConverter.getConvertedParams(action.getParams(), action.getActionDefinitionId()); + return new ActionImpl(null, GUID.generate(), action.getActionDefinitionId(), convertedParams); + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleCompositeConditionModelMapper.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleCompositeConditionModelMapper.java index 2c7bdb1aab..1783f74fd3 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleCompositeConditionModelMapper.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleCompositeConditionModelMapper.java @@ -26,6 +26,8 @@ package org.alfresco.rest.api.impl.mapper.rules; +import static org.alfresco.repo.action.evaluator.NoConditionEvaluator.NAME; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -65,10 +67,19 @@ public class RestRuleCompositeConditionModelMapper implements RestModelMapper filteredActions = actionConditions.stream() + .filter(Objects::nonNull) + .filter(c -> !NAME.equals(c.getActionConditionDefinitionName())) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(filteredActions)) + { + return null; + } final CompositeCondition conditions = new CompositeCondition(); conditions.setCompositeConditions(new ArrayList<>()); // group action conditions by inversion flag - actionConditions.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(ActionCondition::getInvertCondition)) + filteredActions.stream() + .collect(Collectors.groupingBy(ActionCondition::getInvertCondition)) // map action condition sub lists .forEach((inverted, actionConditionsPart) -> Optional .ofNullable(ofActionConditions(actionConditionsPart, inverted, ConditionOperator.AND)) @@ -113,7 +124,7 @@ public class RestRuleCompositeConditionModelMapper implements RestModelMapper actionConditions, final boolean inverted, final ConditionOperator conditionOperator) { - if (actionConditions == null) + if (CollectionUtils.isEmpty(actionConditions)) { return null; } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapper.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapper.java new file mode 100644 index 0000000000..192fb654ca --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapper.java @@ -0,0 +1,164 @@ +/* + * #%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.mapper.rules; + +import java.io.Serializable; +import java.util.Map; +import java.util.stream.Collectors; + +import org.alfresco.repo.action.ActionImpl; +import org.alfresco.repo.action.executer.ScriptActionExecuter; +import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.impl.rules.ActionParameterConverter; +import org.alfresco.rest.api.model.mapper.RestModelMapper; +import org.alfresco.rest.api.model.rules.Action; +import org.alfresco.rest.api.model.rules.CompositeCondition; +import org.alfresco.rest.api.model.rules.Rule; +import org.alfresco.rest.api.model.rules.RuleTrigger; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.ActionCondition; +import org.alfresco.service.cmr.action.CompositeAction; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.util.GUID; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +@Experimental +public class RestRuleModelMapper implements RestModelMapper +{ + private static Log log = LogFactory.getLog(RestRuleModelMapper.class); + + private final RestModelMapper compositeConditionMapper; + private final RestModelMapper actionMapper; + private final Nodes nodes; + private final ActionParameterConverter actionParameterConverter; + + public RestRuleModelMapper( + RestModelMapper compositeConditionMapper, + RestModelMapper actionMapper, + Nodes nodes, + ActionParameterConverter actionParameterConverter) + { + this.compositeConditionMapper = compositeConditionMapper; + this.actionMapper = actionMapper; + this.nodes = nodes; + this.actionParameterConverter = actionParameterConverter; + } + + /** + * Converts service POJO rule to REST model rule. + * + * @param serviceRule - {@link org.alfresco.service.cmr.rule.Rule} service POJO + * @return {@link Rule} REST model + */ + @Override + public Rule toRestModel(org.alfresco.service.cmr.rule.Rule serviceRule) + { + if (serviceRule == null) + { + return null; + } + + final Rule.Builder builder = Rule.builder() + .name(serviceRule.getTitle()) + .description(serviceRule.getDescription()) + .isEnabled(!serviceRule.getRuleDisabled()) + .isInheritable(serviceRule.isAppliedToChildren()) + .isAsynchronous(serviceRule.getExecuteAsynchronously()); + + if (serviceRule.getNodeRef() != null) + { + builder.id(serviceRule.getNodeRef().getId()); + } + if (CollectionUtils.isNotEmpty(serviceRule.getRuleTypes())) + { + builder.triggers(serviceRule.getRuleTypes().stream().map(RuleTrigger::of).collect(Collectors.toList())); + } + if (serviceRule.getAction() != null) + { + builder.conditions(compositeConditionMapper.toRestModel(serviceRule.getAction().getActionConditions())); + if (serviceRule.getAction().getCompensatingAction() != null && + serviceRule.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF) != null) + { + String errorScript = actionParameterConverter.convertParamFromServiceModel( + serviceRule.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF)).toString(); + builder.errorScript(errorScript); + } + if (serviceRule.getAction() instanceof CompositeAction && ((CompositeAction) serviceRule.getAction()).getActions() != null) + { + builder.actions( + ((CompositeAction) serviceRule.getAction()).getActions().stream() + .map(actionMapper::toRestModel) + .collect(Collectors.toList())); + } else { + log.warn("Rule Action should be of 'CompositeAction' type but found: " + serviceRule.getAction().getClass()); + } + + } + + return builder.create(); + } + + /** + * Convert the REST model object to the equivalent service POJO. + * + * @param restRuleModel {@link Rule} REST model. + * @return The rule service POJO. + */ + @Override + public org.alfresco.service.cmr.rule.Rule toServiceModel(Rule restRuleModel) + { + final org.alfresco.service.cmr.rule.Rule serviceRule = new org.alfresco.service.cmr.rule.Rule(); + final NodeRef nodeRef = (restRuleModel.getId() != null) ? nodes.validateOrLookupNode(restRuleModel.getId(), null) : null; + serviceRule.setNodeRef(nodeRef); + serviceRule.setTitle(restRuleModel.getName()); + serviceRule.setDescription(restRuleModel.getDescription()); + serviceRule.setRuleDisabled(!restRuleModel.getIsEnabled()); + serviceRule.applyToChildren(restRuleModel.getIsInheritable()); + serviceRule.setExecuteAsynchronously(restRuleModel.getIsAsynchronous()); + serviceRule.setRuleTypes(restRuleModel.getTriggers()); + serviceRule.setAction(actionMapper.toServiceModel(restRuleModel.getActions())); + if (restRuleModel.getErrorScript() != null) + { + final org.alfresco.service.cmr.action.Action compensatingAction = + new ActionImpl(null, GUID.generate(), ScriptActionExecuter.NAME); + final Map scriptParam = actionParameterConverter + .getConvertedParams(Map.of(ScriptActionExecuter.PARAM_SCRIPTREF, restRuleModel.getErrorScript()), + compensatingAction.getActionDefinitionName()); + compensatingAction.setParameterValues(scriptParam); + serviceRule.getAction().setCompensatingAction(compensatingAction); + } + if (restRuleModel.getConditions() != null) + { + compositeConditionMapper.toServiceModels(restRuleModel.getConditions()) + .forEach(condition -> serviceRule.getAction().addActionCondition(condition)); + } + + return serviceRule; + } +} 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 index 3bcf0d32ba..e503495580 100644 --- 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 @@ -65,7 +65,7 @@ public class ActionParameterConverter this.namespaceService = namespaceService; } - Map getConvertedParams(Map params, String name) + public Map getConvertedParams(Map params, String name) { final Map parameters = new HashMap<>(params.size()); final ParameterizedItemDefinition definition; diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleLoader.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleLoader.java index 41360f9b97..aff384709e 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleLoader.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleLoader.java @@ -43,11 +43,11 @@ public class RuleLoader public static final String IS_SHARED = "isShared"; private RuleService ruleService; private NodeValidator nodeValidator; - private RestModelMapper compositeConditionMapper; + private RestModelMapper ruleMapper; public Rule loadRule(org.alfresco.service.cmr.rule.Rule ruleModel, List includes) { - Rule rule = Rule.from(ruleModel, compositeConditionMapper); + final Rule rule = ruleMapper.toRestModel(ruleModel); if (includes != null && includes.contains(IS_SHARED)) { NodeRef ruleSet = ruleService.getRuleSetNode(ruleModel.getNodeRef()); @@ -67,9 +67,9 @@ public class RuleLoader this.nodeValidator = nodeValidator; } - public void setCompositeConditionMapper( - RestModelMapper compositeConditionMapper) + public void setRuleMapper( + RestModelMapper ruleMapper) { - this.compositeConditionMapper = compositeConditionMapper; + this.ruleMapper = ruleMapper; } } 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 56cde7d4a6..7c9bc31193 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 @@ -58,13 +58,11 @@ public class RulesImpl implements Rules private static final Logger LOGGER = LoggerFactory.getLogger(RulesImpl.class); private static final String MUST_HAVE_AT_LEAST_ONE_ACTION = "A rule must have at least one action"; - private Nodes nodes; private RuleService ruleService; private NodeValidator validator; private RuleLoader ruleLoader; - private ActionParameterConverter actionParameterConverter; private ActionPermissionValidator actionPermissionValidator; - private RestModelMapper compositeConditionMapper; + private RestModelMapper ruleMapper; @Override public CollectionWithPagingInfo getRules(final String folderNodeId, @@ -77,7 +75,7 @@ public class RulesImpl implements Rules NodeRef owningFolder = ruleService.getOwningNodeRef(ruleSetNode); final List rules = ruleService.getRules(owningFolder, false).stream() - .map(ruleModel -> loadRuleAndConvertActionParams(ruleModel, includes)) + .map(ruleModel -> ruleLoader.loadRule(ruleModel, includes)) .collect(Collectors.toList()); return ListPage.of(rules, paging); @@ -90,7 +88,7 @@ public class RulesImpl implements Rules final NodeRef ruleSetNodeRef = validator.validateRuleSetNode(ruleSetId, folderNodeRef); final NodeRef ruleNodeRef = validator.validateRuleNode(ruleId, ruleSetNodeRef); - return loadRuleAndConvertActionParams(ruleService.getRule(ruleNodeRef), includes); + return ruleLoader.loadRule(ruleService.getRule(ruleNodeRef), includes); } @Override @@ -106,7 +104,7 @@ public class RulesImpl implements Rules return rules.stream() .map(this::mapToServiceModelAndValidateActions) .map(rule -> ruleService.saveRule(folderNodeRef, rule)) - .map(rule -> loadRuleAndConvertActionParams(rule, includes)) + .map(rule -> ruleLoader.loadRule(rule, includes)) .collect(Collectors.toList()); } @@ -138,32 +136,11 @@ public class RulesImpl implements Rules { throw new InvalidArgumentException(MUST_HAVE_AT_LEAST_ONE_ACTION); } - final org.alfresco.service.cmr.rule.Rule serviceModelRule = rule.toServiceModel(nodes, compositeConditionMapper); - final CompositeAction compositeAction = (CompositeAction) serviceModelRule.getAction(); - compositeAction.getActions().forEach(action -> action.setParameterValues( - actionParameterConverter.getConvertedParams(action.getParameterValues(), action.getActionDefinitionName()))); + final org.alfresco.service.cmr.rule.Rule serviceModelRule = ruleMapper.toServiceModel(rule); return actionPermissionValidator.validateRulePermissions(serviceModelRule); } - private Rule loadRuleAndConvertActionParams(org.alfresco.service.cmr.rule.Rule ruleModel, List includes) - { - final Rule rule = ruleLoader.loadRule(ruleModel, includes); - rule.getActions() - .forEach(a -> a.setParams(a.getParams().entrySet() - .stream() - .collect(Collectors - .toMap(Map.Entry::getKey, e -> actionParameterConverter.convertParamFromServiceModel(e.getValue()))) - ) - ); - return rule; - } - - public void setNodes(Nodes nodes) - { - this.nodes = nodes; - } - public void setRuleService(RuleService ruleService) { this.ruleService = ruleService; @@ -179,19 +156,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; } - public void setCompositeConditionMapper( - RestModelMapper compositeConditionMapper) + public void setRuleMapper( + RestModelMapper ruleMapper) { - this.compositeConditionMapper = compositeConditionMapper; + this.ruleMapper = ruleMapper; } } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/mapper/RestModelMapper.java b/remote-api/src/main/java/org/alfresco/rest/api/model/mapper/RestModelMapper.java index 6972f3061c..539a328bd4 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/model/mapper/RestModelMapper.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/mapper/RestModelMapper.java @@ -28,6 +28,7 @@ package org.alfresco.rest.api.model.mapper; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import org.alfresco.service.Experimental; @@ -49,10 +50,16 @@ public interface RestModelMapper throw new NotImplementedException(); } default List toRestModels(Collection serviceModels) { - return serviceModels.stream().map(this::toRestModel).collect(Collectors.toList()); + return serviceModels.stream() + .filter(Objects::nonNull) + .map(this::toRestModel) + .collect(Collectors.toList()); } default List toServiceModels(Collection restModels) { - return restModels.stream().map(this::toServiceModel).collect(Collectors.toList()); + return restModels.stream() + .filter(Objects::nonNull) + .map(this::toServiceModel) + .collect(Collectors.toList()); } default List toRestModels(S serviceModel) { throw new NotImplementedException(); 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 548116677c..c3befba7c2 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 @@ -26,19 +26,11 @@ package org.alfresco.rest.api.model.rules; -import static org.alfresco.repo.action.access.ActionAccessRestriction.ACTION_CONTEXT_PARAM_NAME; - import java.io.Serializable; -import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; -import org.alfresco.repo.action.ActionImpl; -import org.alfresco.repo.action.CompositeActionImpl; import org.alfresco.service.Experimental; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.util.GUID; @Experimental public class Action @@ -46,58 +38,6 @@ public class Action private String actionDefinitionId; private Map params; - /** - * Converts service POJO action to REST model action. - * - * @param actionModel - {@link org.alfresco.service.cmr.action.Action} service POJO - * @return {@link Action} REST model - */ - public static Action from(final org.alfresco.service.cmr.action.Action actionModel) - { - if (actionModel == null) - { - return null; - } - - final Action.Builder builder = builder().actionDefinitionId(actionModel.getActionDefinitionName()); - if (actionModel.getParameterValues() != null) - { - Map params = new HashMap<>(actionModel.getParameterValues()); - params.remove(ACTION_CONTEXT_PARAM_NAME); - builder.params(params); - } - - return builder.create(); - } - - /** - * Convert the REST model object to the equivalent service POJO. - * - * @param nodeRef The node reference. - * @return The action service POJO. - */ - public org.alfresco.service.cmr.action.Action toServiceModel(final NodeRef nodeRef) - { - return new ActionImpl(nodeRef, GUID.generate(), this.actionDefinitionId, params); - } - - /** - * Convert the REST model objects to composite action service POJO. - * - * @param actions List of actions. - * @return The composite action service POJO. - */ - public static org.alfresco.service.cmr.action.Action toCompositeAction(final List actions) { - if (actions == null) - { - return null; - } - - final org.alfresco.service.cmr.action.CompositeAction compositeAction = new CompositeActionImpl(null, GUID.generate()); - actions.forEach(action -> compositeAction.addAction(action.toServiceModel(null))); - return compositeAction; - } - public String getActionDefinitionId() { return actionDefinitionId; diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/Rule.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/Rule.java index c487d673f5..aa29eaef95 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/Rule.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/Rule.java @@ -30,16 +30,8 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import org.alfresco.repo.action.ActionImpl; -import org.alfresco.repo.action.executer.ScriptActionExecuter; -import org.alfresco.rest.api.Nodes; -import org.alfresco.rest.api.model.mapper.RestModelMapper; import org.alfresco.rest.framework.resource.UniqueId; import org.alfresco.service.Experimental; -import org.alfresco.service.cmr.action.ActionCondition; -import org.alfresco.service.cmr.action.CompositeAction; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.util.GUID; @Experimental public class Rule @@ -56,84 +48,6 @@ public class Rule private CompositeCondition conditions; private List actions; - /** - * Converts service POJO rule to REST model rule. - * - * @param ruleModel - {@link org.alfresco.service.cmr.rule.Rule} service POJO - * @return {@link Rule} REST model - */ - public static Rule from(final org.alfresco.service.cmr.rule.Rule ruleModel, final RestModelMapper compositeConditionMapper) - { - if (ruleModel == null) - { - return null; - } - - final Rule.Builder builder = builder() - .name(ruleModel.getTitle()) - .description(ruleModel.getDescription()) - .isEnabled(!ruleModel.getRuleDisabled()) - .isInheritable(ruleModel.isAppliedToChildren()) - .isAsynchronous(ruleModel.getExecuteAsynchronously()); - - if (ruleModel.getNodeRef() != null) { - builder.id(ruleModel.getNodeRef().getId()); - } - if (ruleModel.getRuleTypes() != null) - { - builder.triggers(ruleModel.getRuleTypes().stream().map(RuleTrigger::of).collect(Collectors.toList())); - } - if (ruleModel.getAction() != null) - { - builder.conditions(compositeConditionMapper.toRestModel(ruleModel.getAction().getActionConditions())); - if (ruleModel.getAction().getCompensatingAction() != null && ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF) != null) - { - builder.errorScript(ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF).toString()); - } - if (ruleModel.getAction() instanceof CompositeAction && ((CompositeAction) ruleModel.getAction()).getActions() != null) - { - builder.actions(((CompositeAction) ruleModel.getAction()).getActions().stream().map(Action::from).collect(Collectors.toList())); - } - } - - return builder.create(); - } - - /** - * Convert the REST model object to the equivalent service POJO. - * - * @param nodes The nodes API. - * @return The rule service POJO. - */ - public org.alfresco.service.cmr.rule.Rule toServiceModel(final Nodes nodes, final RestModelMapper compositeConditionMapper) - { - final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule(); - final NodeRef nodeRef = (id != null) ? nodes.validateOrLookupNode(id, null) : null; - ruleModel.setNodeRef(nodeRef); - ruleModel.setTitle(name); - ruleModel.setDescription(description); - ruleModel.setRuleDisabled(!isEnabled); - ruleModel.applyToChildren(isInheritable); - ruleModel.setExecuteAsynchronously(isAsynchronous); - if (triggers != null) - { - ruleModel.setRuleTypes(triggers.stream().map(RuleTrigger::getValue).collect(Collectors.toList())); - } - ruleModel.setAction(Action.toCompositeAction(actions)); - if (errorScript != null) - { - final org.alfresco.service.cmr.action.Action compensatingAction = new ActionImpl(null, GUID.generate(), ScriptActionExecuter.NAME); - compensatingAction.setParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF, errorScript); - ruleModel.getAction().setCompensatingAction(compensatingAction); - } - if (conditions != null) - { - compositeConditionMapper.toServiceModels(conditions).forEach(condition -> ruleModel.getAction().addActionCondition(condition)); - } - - return ruleModel; - } - @UniqueId public String getId() { 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 bfe4809e9b..a3da17122c 100644 --- a/remote-api/src/main/resources/alfresco/public-rest-context.xml +++ b/remote-api/src/main/resources/alfresco/public-rest-context.xml @@ -887,7 +887,7 @@ - + @@ -905,13 +905,11 @@ - - - + @@ -955,6 +953,17 @@ + + + + + + + + + + + diff --git a/remote-api/src/test/java/org/alfresco/rest/api/RulesUnitTests.java b/remote-api/src/test/java/org/alfresco/rest/api/RulesUnitTests.java index fa55c4e9d4..6b6df6ce5f 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/RulesUnitTests.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/RulesUnitTests.java @@ -26,16 +26,16 @@ package org.alfresco.rest.api; +import org.alfresco.rest.api.impl.mapper.rules.RestRuleActionModelMapperTest; import org.alfresco.rest.api.impl.mapper.rules.RestRuleCompositeConditionModelMapperTest; +import org.alfresco.rest.api.impl.mapper.rules.RestRuleModelMapperTest; import org.alfresco.rest.api.impl.mapper.rules.RestRuleSimpleConditionModelMapperTest; import org.alfresco.rest.api.impl.rules.ActionParameterConverterTest; import org.alfresco.rest.api.impl.rules.ActionPermissionValidatorTest; import org.alfresco.rest.api.impl.rules.NodeValidatorTest; import org.alfresco.rest.api.impl.rules.RuleLoaderTest; import org.alfresco.rest.api.impl.rules.RuleSetsImplTest; -import org.alfresco.rest.api.model.rules.ActionTest; import org.alfresco.rest.api.impl.rules.RulesImplTest; -import org.alfresco.rest.api.model.rules.RuleTest; import org.alfresco.rest.api.nodes.NodeRulesRelationTest; import org.alfresco.service.Experimental; import org.junit.runner.RunWith; @@ -48,13 +48,13 @@ import org.junit.runners.Suite; RulesImplTest.class, RuleSetsImplTest.class, NodeValidatorTest.class, - RuleTest.class, - ActionTest.class, RuleLoaderTest.class, ActionParameterConverterTest.class, ActionPermissionValidatorTest.class, RestRuleSimpleConditionModelMapperTest.class, - RestRuleCompositeConditionModelMapperTest.class + RestRuleCompositeConditionModelMapperTest.class, + RestRuleActionModelMapperTest.class, + RestRuleModelMapperTest.class }) public class RulesUnitTests { diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleActionModelMapperTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleActionModelMapperTest.java new file mode 100644 index 0000000000..46d1bf4aa3 --- /dev/null +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleActionModelMapperTest.java @@ -0,0 +1,125 @@ +/* + * #%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.mapper.rules; + +import static org.alfresco.repo.action.access.ActionAccessRestriction.ACTION_CONTEXT_PARAM_NAME; +import static org.alfresco.repo.action.executer.SetPropertyValueActionExecuter.PARAM_PROPERTY; +import static org.alfresco.repo.action.executer.SetPropertyValueActionExecuter.PARAM_VALUE; +import static org.assertj.core.api.Assertions.assertThat; +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.Collections; +import java.util.List; +import java.util.Map; + +import org.alfresco.repo.action.ActionImpl; +import org.alfresco.rest.api.impl.rules.ActionParameterConverter; +import org.alfresco.rest.api.model.rules.Action; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; +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 RestRuleActionModelMapperTest +{ + + private static final String ACTION_DEFINITION_NAME = "actionDefName"; + private static final Map parameters = + Map.of(PARAM_PROPERTY, "propertyName", PARAM_VALUE, "propertyValue", ACTION_CONTEXT_PARAM_NAME, "rule"); + + @Mock + private ActionParameterConverter parameterConverter; + + @InjectMocks + private RestRuleActionModelMapper objectUnderTest; + + @Test + public void testToRestModel() + { + final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "ruleId"); + final org.alfresco.service.cmr.action.Action actionServiceModel = + new ActionImpl(nodeRef, "actionId", ACTION_DEFINITION_NAME, parameters); + given(parameterConverter.convertParamFromServiceModel(any())).willAnswer(a -> a.getArgument(0)); + + //when + final Action actualAction = objectUnderTest.toRestModel(actionServiceModel); + + then(parameterConverter).should(times(3)).convertParamFromServiceModel(any()); + then(parameterConverter).shouldHaveNoMoreInteractions(); + final Map expectedParameters = Map.of(PARAM_PROPERTY, "propertyName", PARAM_VALUE, "propertyValue"); + final Action expectedAction = Action.builder().actionDefinitionId(ACTION_DEFINITION_NAME).params(expectedParameters).create(); + assertThat(actualAction).isNotNull().usingRecursiveComparison().isEqualTo(expectedAction); + } + + @Test + public void testToRestModelWithNullValues() + { + final org.alfresco.service.cmr.action.Action actionServiceModel = new ActionImpl(null, null, null); + final Action expectedAction = Action.builder().params(Collections.emptyMap()).create(); + + //when + final Action actualAction = objectUnderTest.toRestModel(actionServiceModel); + + then(parameterConverter).shouldHaveNoInteractions(); + assertThat(actualAction).isNotNull().usingRecursiveComparison().isEqualTo(expectedAction); + } + + @Test + public void testToServiceModel() { + final Action action = Action.builder().actionDefinitionId(ACTION_DEFINITION_NAME).params(parameters).create(); + final List actions = List.of(action); + given(parameterConverter.getConvertedParams(parameters, ACTION_DEFINITION_NAME)).willAnswer(a -> a.getArgument(0)); + + //when + final org.alfresco.service.cmr.action.Action serviceModelAction = objectUnderTest.toServiceModel(actions); + then(parameterConverter).should().getConvertedParams(parameters, ACTION_DEFINITION_NAME); + then(parameterConverter).shouldHaveNoMoreInteractions(); + assertThat(serviceModelAction).isNotNull(); + } + + @Test + public void testToServiceModelFromEmptyActions() { + final List actions = Collections.emptyList(); + + //when + final org.alfresco.service.cmr.action.Action serviceModelAction = objectUnderTest.toServiceModel(actions); + + then(parameterConverter).shouldHaveNoInteractions(); + assertThat(serviceModelAction).isNull(); + } + +} diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleCompositeConditionModelMapperTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleCompositeConditionModelMapperTest.java index 7ffc69d5aa..a75822a614 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleCompositeConditionModelMapperTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleCompositeConditionModelMapperTest.java @@ -26,8 +26,9 @@ package org.alfresco.rest.api.impl.mapper.rules; +import static org.alfresco.repo.action.evaluator.NoConditionEvaluator.NAME; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import java.io.Serializable; import java.util.ArrayList; @@ -61,7 +62,7 @@ public class RestRuleCompositeConditionModelMapperTest private RestModelMapper simpleConditionMapperMock; @InjectMocks - RestRuleCompositeConditionModelMapper objectUnderTest; + private RestRuleCompositeConditionModelMapper objectUnderTest; @Test public void testToRestModel() @@ -81,9 +82,8 @@ public class RestRuleCompositeConditionModelMapperTest createCompositeCondition(false, simpleConditions.subList(0,2)), createCompositeCondition(true, simpleConditions.subList(2,3)) )); - - when(simpleConditionMapperMock.toRestModels(actionConditions.subList(0,2))).thenReturn(simpleConditions.subList(0,2)); - when(simpleConditionMapperMock.toRestModels(actionConditions.subList(2,3))).thenReturn(simpleConditions.subList(2,3)); + given(simpleConditionMapperMock.toRestModels(actionConditions.subList(2,3))).willReturn(simpleConditions.subList(2,3)); + given(simpleConditionMapperMock.toRestModels(actionConditions.subList(0,2))).willReturn(simpleConditions.subList(0,2)); // when final CompositeCondition actualCompositeCondition = objectUnderTest.toRestModel(actionConditions); @@ -112,16 +112,29 @@ public class RestRuleCompositeConditionModelMapperTest } @Test - public void testToRestModel_fromListContainingNull() + public void testToRestModel_fromListContainingNullsOnly() { final List actionConditions = new ArrayList<>(); actionConditions.add(null); - final CompositeCondition expectedCompositeCondition = CompositeCondition.builder().create(); + actionConditions.add(null); // when final CompositeCondition actualCompositeCondition = objectUnderTest.toRestModel(actionConditions); - assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition); + assertThat(actualCompositeCondition).isNull(); + } + + @Test + public void testToRestModel_fromNoCondition() + { + final List actionConditions = new ArrayList<>(); + final ActionCondition noCondition = new ActionConditionImpl("fake-id", NAME); + actionConditions.add(noCondition); + + // when + final CompositeCondition actualCompositeCondition = objectUnderTest.toRestModel(actionConditions); + + assertThat(actualCompositeCondition).isNull(); } @Test @@ -142,7 +155,7 @@ public class RestRuleCompositeConditionModelMapperTest ); IntStream.rangeClosed(0, 2) - .forEach(i -> when(simpleConditionMapperMock.toServiceModel(simpleConditions.get(i))).thenReturn(actionConditions.get(i))); + .forEach(i -> given(simpleConditionMapperMock.toServiceModel(simpleConditions.get(i))).willReturn(actionConditions.get(i))); final List actualActionConditions = objectUnderTest.toServiceModels(compositeCondition); assertThat(actualActionConditions).isEqualTo(actionConditions); @@ -163,7 +176,7 @@ public class RestRuleCompositeConditionModelMapperTest ); IntStream.rangeClosed(0, 2) - .forEach(i -> when(simpleConditionMapperMock.toServiceModel(simpleConditions.get(i))).thenReturn(actionConditions.get(i))); + .forEach(i -> given(simpleConditionMapperMock.toServiceModel(simpleConditions.get(i))).willReturn(actionConditions.get(i))); final List actualActionConditions = objectUnderTest.toServiceModels(compositeCondition); assertThat(actualActionConditions).isEqualTo(actionConditions); diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapperTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapperTest.java new file mode 100644 index 0000000000..bcf7eacf78 --- /dev/null +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapperTest.java @@ -0,0 +1,244 @@ +/* + * #%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.mapper.rules; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; + +import java.util.List; + +import org.alfresco.repo.action.ActionConditionImpl; +import org.alfresco.repo.action.ActionImpl; +import org.alfresco.repo.action.CompositeActionImpl; +import org.alfresco.repo.action.executer.ScriptActionExecuter; +import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.impl.rules.ActionParameterConverter; +import org.alfresco.rest.api.model.rules.Action; +import org.alfresco.rest.api.model.rules.CompositeCondition; +import org.alfresco.rest.api.model.rules.Rule; +import org.alfresco.rest.api.model.rules.RuleTrigger; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.ActionCondition; +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.RuleType; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@Experimental +@RunWith(MockitoJUnitRunner.class) +public class RestRuleModelMapperTest +{ + private static final String RULE_ID = "fake-rule-id"; + private static final String RULE_NAME = "rule name"; + private static final String RULE_DESCRIPTION = "rule description"; + private static final boolean RULE_ENABLED = true; + private static final boolean RULE_INHERITABLE = true; + private static final boolean RULE_ASYNC = true; + private static final String ACTION_DEFINITION_NAME = "action-def-name"; + private static final String ERROR_SCRIPT = "error-script-ref"; + + @Mock + private RestRuleActionModelMapper actionMapperMock; + @Mock + private RestRuleCompositeConditionModelMapper compositeConditionMapperMock; + @Mock + private Nodes nodesMock; + @Mock + private ActionParameterConverter actionParameterConverterMock; + + private RestRuleModelMapper objectUnderTest; + + @Before + public void setUp() + { + objectUnderTest = new RestRuleModelMapper(compositeConditionMapperMock, actionMapperMock, nodesMock, actionParameterConverterMock); + } + + @Test + public void testToRestModel() + { + final org.alfresco.service.cmr.rule.Rule ruleModel = createRuleModel(); + given(actionParameterConverterMock.convertParamFromServiceModel(any())).willAnswer(a -> a.getArgument(0)); + given(actionMapperMock.toRestModel(createActionModel())).willReturn(createAction()); + given(compositeConditionMapperMock.toRestModel(List.of(createConditionModel()))).willReturn(createCondition()); + + // when + final Rule actualRule = objectUnderTest.toRestModel(ruleModel); + + then(compositeConditionMapperMock).should().toRestModel(ruleModel.getAction().getActionConditions()); + then(compositeConditionMapperMock).shouldHaveNoMoreInteractions(); + then(actionParameterConverterMock).should().convertParamFromServiceModel(ERROR_SCRIPT); + then(actionParameterConverterMock).shouldHaveNoMoreInteractions(); + ((CompositeAction) ruleModel.getAction()).getActions().forEach(a -> then(actionMapperMock).should().toRestModel(a)); + final Rule expectedRule = createRuleWithDefaultValues(); + assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule); + } + + @Test + public void testToRestModelWithNullValues() + { + final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule(); + final Rule expectedRule = Rule.builder().isEnabled(true).create(); + + // when + final Rule actualRule = objectUnderTest.toRestModel(ruleModel); + + assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule); + + } + + @Test + public void testToServiceModel() + { + final Rule rule = createRuleWithDefaultValues(); + final Action action = Action.builder().actionDefinitionId(ACTION_DEFINITION_NAME).create(); + rule.setActions(List.of(action)); + final CompositeCondition compositeCondition = CompositeCondition.builder().create(); + final org.alfresco.service.cmr.rule.Rule expectedRuleModel = createRuleModel(); + rule.setConditions(compositeCondition); + final org.alfresco.service.cmr.action.Action actionModel = createCompositeActionModel(); + given(actionMapperMock.toServiceModel(List.of(action))).willReturn(actionModel); + given(compositeConditionMapperMock.toServiceModels(compositeCondition)).willCallRealMethod(); + given(actionParameterConverterMock.getConvertedParams(any(), any())).willAnswer(a -> a.getArgument(0)); + // when + final org.alfresco.service.cmr.rule.Rule actualRuleModel = objectUnderTest.toServiceModel(rule); + + then(nodesMock).should().validateOrLookupNode(RULE_ID, null); + then(nodesMock).shouldHaveNoMoreInteractions(); + then(actionMapperMock).should().toServiceModel(List.of(action)); + then(actionMapperMock).shouldHaveNoMoreInteractions(); + then(compositeConditionMapperMock).should().toServiceModels(compositeCondition); + then(compositeConditionMapperMock).shouldHaveNoMoreInteractions(); + assertThat(actualRuleModel) + .isNotNull() + .usingRecursiveComparison().ignoringFields("nodeRef", "action") + .isEqualTo(expectedRuleModel); + assertThat(actualRuleModel.getAction()) + .isNotNull(); + final org.alfresco.service.cmr.action.Action expectedCompensatingActionModel = createCompensatingActionModel(); + assertThat(actualRuleModel.getAction().getCompensatingAction()) + .isNotNull() + .usingRecursiveComparison().ignoringFields("id") + .isEqualTo(expectedCompensatingActionModel); + } + + @Test + public void testToServiceModel_withNullValues() + { + final Rule rule = new Rule(); + final org.alfresco.service.cmr.rule.Rule expectedRuleModel = new org.alfresco.service.cmr.rule.Rule(); + expectedRuleModel.setRuleDisabled(true); + + // when + final org.alfresco.service.cmr.rule.Rule actualRuleModel = objectUnderTest.toServiceModel(rule); + + then(nodesMock).shouldHaveNoInteractions(); + assertThat(actualRuleModel) + .isNotNull() + .usingRecursiveComparison() + .ignoringFields("ruleTypes") + .isEqualTo(expectedRuleModel); + } + + private Rule createRuleWithDefaultValues() + { + return Rule.builder() + .id(RULE_ID) + .name(RULE_NAME) + .description(RULE_DESCRIPTION) + .isEnabled(RULE_ENABLED) + .isInheritable(RULE_INHERITABLE) + .isAsynchronous(RULE_ASYNC) + .triggers(List.of(RuleTrigger.INBOUND, RuleTrigger.UPDATE)) + .errorScript(ERROR_SCRIPT) + .actions(List.of(createAction())) + .conditions(createCondition()) + .create(); + } + + private CompositeCondition createCondition() + { + return CompositeCondition.builder().create(); + } + + private Action createAction() { + return Action.builder().actionDefinitionId(ACTION_DEFINITION_NAME).create(); + } + + private static org.alfresco.service.cmr.rule.Rule createRuleModel() + { + final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID); + final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule(nodeRef); + ruleModel.setTitle(RULE_NAME); + ruleModel.setDescription(RULE_DESCRIPTION); + ruleModel.setRuleDisabled(!RULE_ENABLED); + ruleModel.applyToChildren(RULE_INHERITABLE); + ruleModel.setExecuteAsynchronously(RULE_ASYNC); + ruleModel.setRuleTypes(List.of(RuleType.INBOUND, RuleType.UPDATE)); + ruleModel.setAction(createCompositeActionModel()); + + return ruleModel; + } + + private static org.alfresco.service.cmr.action.Action createCompositeActionModel() + { + final ActionCondition actionCondition = createConditionModel(); + final org.alfresco.service.cmr.action.CompositeAction compositeActionModel = new CompositeActionImpl(null, "composite-action"); + compositeActionModel.addAction(createActionModel()); + compositeActionModel.setCompensatingAction(createCompensatingActionModel()); + compositeActionModel.addActionCondition(actionCondition); + + return compositeActionModel; + } + + private static ActionConditionImpl createConditionModel() + { + return new ActionConditionImpl("action-condition-id", "action-condition-def-name"); + } + + private static ActionImpl createActionModel() + { + return new ActionImpl(null, "action-id", ACTION_DEFINITION_NAME); + } + + private static org.alfresco.service.cmr.action.Action createCompensatingActionModel() + { + final org.alfresco.service.cmr.action.Action compensatingActionModel = + new ActionImpl(null, "compensating-action-id", ScriptActionExecuter.NAME); + compensatingActionModel.setParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF, ERROR_SCRIPT); + + return compensatingActionModel; + } + +} diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java index ee2b4194a4..6a502a1224 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java @@ -176,7 +176,7 @@ public class RestRuleSimpleConditionModelMapperTest // when final List actualSimpleConditions = objectUnderTest.toRestModels(actionConditions); - assertThat(actualSimpleConditions).hasSize(1).containsOnlyNulls(); + assertThat(actualSimpleConditions).isEmpty(); } @Test diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleLoaderTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleLoaderTest.java index 9cfaa985fe..9af293534f 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleLoaderTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleLoaderTest.java @@ -33,19 +33,22 @@ import static org.alfresco.rest.api.model.rules.RuleTrigger.UPDATE; import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -import static org.mockito.MockitoAnnotations.openMocks; +import static org.mockito.BDDMockito.then; import java.util.List; +import org.alfresco.rest.api.model.mapper.RestModelMapper; import org.alfresco.rest.api.model.rules.Rule; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.rule.RuleService; -import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; /** Unit tests for {@link RuleLoader}. */ +@RunWith(MockitoJUnitRunner.class) public class RuleLoaderTest { private static final String NODE_ID = "node-id"; @@ -58,23 +61,25 @@ public class RuleLoaderTest private static final List TRIGGERS = List.of("update", "outbound"); private static final NodeRef RULE_SET_NODE = new NodeRef("rule://set/"); - @InjectMocks - private RuleLoader ruleLoader; @Mock private RuleService ruleServiceMock; @Mock private NodeValidator nodeValidatorMock; + @Mock + private RestModelMapper ruleMapperMock; + private org.alfresco.service.cmr.rule.Rule serviceRule = createServiceRule(); - @Before - public void setUp() - { - openMocks(this); - } + @InjectMocks + private RuleLoader ruleLoader; @Test public void testLoadRule() { + final Rule restModelRule = getRestModelRule(); + given(ruleMapperMock.toRestModel(serviceRule)).willReturn(restModelRule); + + //when Rule rule = ruleLoader.loadRule(serviceRule, emptyList()); Rule expected = Rule.builder().id(NODE_ID) @@ -90,18 +95,30 @@ public class RuleLoaderTest @Test public void testLoadRule_noExceptionWithNullInclude() { + //when ruleLoader.loadRule(serviceRule, null); + + then(ruleMapperMock).should().toRestModel(serviceRule); + then(ruleMapperMock).shouldHaveNoMoreInteractions(); } @Test public void testLoadRule_includeIsShared() { // Simulate the rule set being shared. + final Rule restModelRule = getRestModelRule(); given(ruleServiceMock.getRuleSetNode(NODE_REF)).willReturn(RULE_SET_NODE); given(nodeValidatorMock.isRuleSetNotNullAndShared(RULE_SET_NODE)).willReturn(true); + given(ruleMapperMock.toRestModel(serviceRule)).willReturn(restModelRule); Rule rule = ruleLoader.loadRule(serviceRule, List.of(IS_SHARED)); + then(ruleMapperMock).should().toRestModel(serviceRule); + then(ruleMapperMock).shouldHaveNoMoreInteractions(); + then(ruleServiceMock).should().getRuleSetNode(NODE_REF); + then(ruleServiceMock).shouldHaveNoMoreInteractions(); + then(nodeValidatorMock).should().isRuleSetNotNullAndShared(RULE_SET_NODE); + then(nodeValidatorMock).shouldHaveNoMoreInteractions(); assertThat(rule).extracting("isShared").isEqualTo(true); } @@ -118,4 +135,15 @@ public class RuleLoaderTest return rule; } + private Rule getRestModelRule() + { + return Rule.builder().id(NODE_ID) + .name(TITLE) + .description(DESCRIPTION) + .isEnabled(ENABLED) + .isInheritable(INHERITABLE) + .isAsynchronous(EXECUTE_ASYNCHRONOUSLY) + .triggers(List.of(UPDATE, OUTBOUND)).create(); + } + } 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 68126b01aa..24811b990b 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,24 +36,17 @@ 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.Action; import org.alfresco.rest.api.model.mapper.RestModelMapper; -import org.alfresco.rest.api.model.rules.CompositeCondition; +import org.alfresco.rest.api.model.rules.Action; import org.alfresco.rest.api.model.rules.Rule; -import org.alfresco.rest.api.model.rules.SimpleCondition; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; @@ -61,8 +54,6 @@ 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.ActionCondition; -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; @@ -86,13 +77,11 @@ 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; @Mock - private RestModelMapper compositeConditionMapperMock; + private RestModelMapper ruleMapper; @Mock private NodeValidator nodeValidatorMock; @Mock @@ -100,8 +89,6 @@ public class RulesImplTest extends TestCase @Mock private RuleLoader ruleLoaderMock; @Mock - private ActionParameterConverter actionParameterConverterMock; - @Mock private ActionPermissionValidator actionPermissionValidatorMock; @Mock private org.alfresco.service.cmr.rule.Rule serviceRuleMock; @@ -111,7 +98,6 @@ public class RulesImplTest extends TestCase private Action actionMock; private org.alfresco.service.cmr.rule.Rule ruleModel = createRule(RULE_ID); - private CompositeAction compositeAction = new CompositeActionImpl(RULE_NODE_REF, "compositeActionId"); @InjectMocks private RulesImpl rules; @@ -129,8 +115,6 @@ public class RulesImplTest extends TestCase given(ruleServiceMock.getOwningNodeRef(RULE_SET_NODE_REF)).willReturn(FOLDER_NODE_REF); given(ruleLoaderMock.loadRule(ruleModel, INCLUDE)).willReturn(ruleMock); - - compositeAction.addAction(new ActionImpl(FOLDER_NODE_REF, "actionId", ACTION_DEFINITION_NAME, DUMMY_PARAMS)); } @Test @@ -298,9 +282,8 @@ public class RulesImplTest extends TestCase public void testCreateRules() { List ruleList = List.of(ruleMock); - given(ruleMock.toServiceModel(nodesMock, compositeConditionMapperMock)).willReturn(serviceRuleMock); + given(ruleMapper.toServiceModel(ruleMock)).willReturn(serviceRuleMock); given(ruleMock.getActions()).willReturn(List.of(actionMock)); - 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]); @@ -311,11 +294,9 @@ 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(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, compositeConditionMapperMock)); + then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, serviceRuleMock); then(ruleServiceMock).shouldHaveNoMoreInteractions(); List expected = List.of(ruleMock); assertThat(actual).isEqualTo(expected); @@ -328,11 +309,10 @@ public class RulesImplTest extends TestCase public void testCreateRules_defaultRuleSet() { List ruleList = List.of(ruleMock); - given(ruleMock.toServiceModel(nodesMock, compositeConditionMapperMock)).willReturn(serviceRuleMock); + given(ruleMapper.toServiceModel(ruleMock)).willReturn(serviceRuleMock); given(ruleMock.getActions()).willReturn(List.of(actionMock)); 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 @@ -340,11 +320,9 @@ public class RulesImplTest extends TestCase then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, true); then(nodeValidatorMock).shouldHaveNoMoreInteractions(); - 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, compositeConditionMapperMock)); + then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, serviceRuleMock); then(ruleServiceMock).shouldHaveNoMoreInteractions(); List expected = List.of(ruleMock); assertThat(actual).isEqualTo(expected); @@ -375,10 +353,7 @@ public class RulesImplTest extends TestCase given(ruleBodyMock.getActions()).willReturn(List.of(actionMock)); ruleBodyList.add(ruleBodyMock); org.alfresco.service.cmr.rule.Rule serviceRuleMockInner = mock(org.alfresco.service.cmr.rule.Rule.class); - given(ruleBodyMock.toServiceModel(nodesMock, compositeConditionMapperMock)).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(ruleMapper.toServiceModel(ruleBodyMock)).willReturn(serviceRuleMockInner); given(ruleServiceMock.saveRule(FOLDER_NODE_REF, serviceRuleMockInner)).willAnswer(arg -> arg.getArguments()[1]); Rule ruleMockInner = mock(Rule.class); given(ruleLoaderMock.loadRule(serviceRuleMockInner, INCLUDE)).willReturn(ruleMockInner); @@ -394,12 +369,9 @@ public class RulesImplTest extends TestCase then(nodeValidatorMock).shouldHaveNoMoreInteractions(); for (Rule ruleBody : ruleBodyList) { - then(actionPermissionValidatorMock).should().validateRulePermissions(ruleBody.toServiceModel(nodesMock, - compositeConditionMapperMock)); - then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleBody.toServiceModel(nodesMock, compositeConditionMapperMock)); + then(actionPermissionValidatorMock).should().validateRulePermissions(ruleMapper.toServiceModel(ruleBody)); + then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleMapper.toServiceModel(ruleBody)); } - then(actionParameterConverterMock).should(times(3)).getConvertedParams(DUMMY_PARAMS, ACTION_DEFINITION_NAME); - then(actionParameterConverterMock).shouldHaveNoMoreInteractions(); then(actionPermissionValidatorMock).shouldHaveNoMoreInteractions(); then(ruleServiceMock).shouldHaveNoMoreInteractions(); assertThat(actual).isEqualTo(expected); @@ -459,7 +431,6 @@ 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(actionParameterConverterMock).shouldHaveNoInteractions(); then(actionPermissionValidatorMock).shouldHaveNoInteractions(); then(ruleServiceMock).shouldHaveNoInteractions(); } @@ -470,10 +441,9 @@ public class RulesImplTest extends TestCase @Test public void testUpdateRuleById() { - given(ruleMock.toServiceModel(nodesMock, compositeConditionMapperMock)).willReturn(serviceRuleMock); + given(ruleMapper.toServiceModel(ruleMock)).willReturn(serviceRuleMock); given(ruleMock.getActions()).willReturn(List.of(actionMock)); given(ruleServiceMock.saveRule(FOLDER_NODE_REF, serviceRuleMock)).willAnswer(a -> a.getArguments()[1]); - given(serviceRuleMock.getAction()).willReturn(compositeAction); given(ruleLoaderMock.loadRule(serviceRuleMock, INCLUDE)).willReturn(ruleMock); given(actionPermissionValidatorMock.validateRulePermissions(any())).willAnswer(arg -> arg.getArguments()[0]); @@ -486,8 +456,6 @@ public class RulesImplTest extends TestCase then(nodeValidatorMock).shouldHaveNoMoreInteractions(); then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, serviceRuleMock); then(ruleServiceMock).shouldHaveNoMoreInteractions(); - then(actionParameterConverterMock).should().getConvertedParams(DUMMY_PARAMS, ACTION_DEFINITION_NAME); - then(actionParameterConverterMock).shouldHaveNoMoreInteractions(); then(actionPermissionValidatorMock).should().validateRulePermissions(serviceRuleMock); then(actionPermissionValidatorMock).shouldHaveNoMoreInteractions(); assertThat(updatedRule).isEqualTo(ruleMock); @@ -571,7 +539,6 @@ public class RulesImplTest extends TestCase then(nodeValidatorMock).shouldHaveNoMoreInteractions(); then(ruleServiceMock).shouldHaveNoInteractions(); - then(actionParameterConverterMock).shouldHaveNoInteractions(); then(actionPermissionValidatorMock).shouldHaveNoInteractions(); } diff --git a/remote-api/src/test/java/org/alfresco/rest/api/model/rules/ActionTest.java b/remote-api/src/test/java/org/alfresco/rest/api/model/rules/ActionTest.java deleted file mode 100644 index af0b9a9014..0000000000 --- a/remote-api/src/test/java/org/alfresco/rest/api/model/rules/ActionTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * #%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.model.rules; - -import static org.alfresco.repo.action.executer.SetPropertyValueActionExecuter.PARAM_PROPERTY; -import static org.alfresco.repo.action.executer.SetPropertyValueActionExecuter.PARAM_VALUE; -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.alfresco.repo.action.ActionImpl; -import org.alfresco.service.Experimental; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; -import org.junit.Test; - -@Experimental -public class ActionTest -{ - - private static final String ACTION_DEFINITION_NAME = "actionDefName"; - private static final Map parameters = new HashMap<>(); - - static - { - parameters.put(PARAM_PROPERTY, "propertyName"); - parameters.put(PARAM_VALUE, "propertyValue"); - } - - @Test - public void testFrom() - { - final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "ruleId"); - final org.alfresco.service.cmr.action.Action actionModel = new ActionImpl(nodeRef, "actionId", ACTION_DEFINITION_NAME, parameters); - final Action expectedAction = Action.builder().actionDefinitionId(ACTION_DEFINITION_NAME).params(parameters).create(); - - final Action actualAction = Action.from(actionModel); - - assertThat(actualAction).isNotNull().usingRecursiveComparison().isEqualTo(expectedAction); - } - - @Test - public void testFromActionModelWithNullValues() - { - final org.alfresco.service.cmr.action.Action actionModel = new ActionImpl(null, null, null); - final Action expectedAction = Action.builder().params(Collections.emptyMap()).create(); - - final Action actualAction = Action.from(actionModel); - - assertThat(actualAction).isNotNull().usingRecursiveComparison().isEqualTo(expectedAction); - } -} diff --git a/remote-api/src/test/java/org/alfresco/rest/api/model/rules/RuleTest.java b/remote-api/src/test/java/org/alfresco/rest/api/model/rules/RuleTest.java deleted file mode 100644 index 18e3320d6f..0000000000 --- a/remote-api/src/test/java/org/alfresco/rest/api/model/rules/RuleTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * #%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.model.rules; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -import java.util.Collections; -import java.util.List; - -import org.alfresco.repo.action.ActionConditionImpl; -import org.alfresco.repo.action.ActionImpl; -import org.alfresco.repo.action.executer.ScriptActionExecuter; -import org.alfresco.rest.api.Nodes; -import org.alfresco.rest.api.impl.mapper.rules.RestRuleCompositeConditionModelMapper; -import org.alfresco.rest.api.model.mapper.RestModelMapper; -import org.alfresco.service.Experimental; -import org.alfresco.service.cmr.action.ActionCondition; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.rule.RuleType; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -@Experimental -@RunWith(MockitoJUnitRunner.class) -public class RuleTest -{ - private static final String RULE_ID = "fake-rule-id"; - private static final String RULE_NAME = "rule name"; - private static final String RULE_DESCRIPTION = "rule description"; - private static final boolean RULE_ENABLED = true; - private static final boolean RULE_INHERITABLE = true; - private static final boolean RULE_ASYNC = true; - private static final boolean RULE_SHARED = true; - private static final String ACTION_DEFINITION_NAME = "action-def-name"; - private static final String ERROR_SCRIPT = "error-script-ref"; - - private final RestModelMapper compositeConditionMapper = mock(RestRuleCompositeConditionModelMapper.class); - - @Test - public void testFrom() - { - final org.alfresco.service.cmr.rule.Rule ruleModel = createRuleModel(); - final Rule expectedRule = createRuleWithDefaultValues(); - - // when - final Rule actualRule = Rule.from(ruleModel, compositeConditionMapper); - - assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule); - - } - - @Test - public void testFromRuleModelWithNullValues() - { - final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule(); - final Rule expectedRule = Rule.builder().isEnabled(true).create(); - - // when - final Rule actualRule = Rule.from(ruleModel, compositeConditionMapper); - - assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule); - - } - - @Test - public void testToServiceModel() - { - final Nodes nodesMock = mock(Nodes.class); - final Rule rule = createRuleWithDefaultValues(); - rule.setActions(List.of(Action.builder().actionDefinitionId(ACTION_DEFINITION_NAME).create())); - final org.alfresco.service.cmr.rule.Rule expectedRuleModel = createRuleModel(); - final org.alfresco.service.cmr.action.Action expectedCompensatingActionModel = createCompensatingActionModel(); - - // when - final org.alfresco.service.cmr.rule.Rule actualRuleModel = rule.toServiceModel(nodesMock, compositeConditionMapper); - - then(nodesMock).should().validateOrLookupNode(RULE_ID, null); - then(nodesMock).shouldHaveNoMoreInteractions(); - assertThat(actualRuleModel) - .isNotNull() - .usingRecursiveComparison().ignoringFields("nodeRef", "action") - .isEqualTo(expectedRuleModel); - assertThat(actualRuleModel.getAction()) - .isNotNull(); - assertThat(actualRuleModel.getAction().getCompensatingAction()) - .isNotNull() - .usingRecursiveComparison().ignoringFields("id") - .isEqualTo(expectedCompensatingActionModel); - } - - @Test - public void testToServiceModel_withNullValues() - { - final Nodes nodesMock = mock(Nodes.class); - final Rule rule = new Rule(); - final org.alfresco.service.cmr.rule.Rule expectedRuleModel = new org.alfresco.service.cmr.rule.Rule(); - expectedRuleModel.setRuleDisabled(true); - - // when - final org.alfresco.service.cmr.rule.Rule actualRuleModel = rule.toServiceModel(nodesMock, compositeConditionMapper); - - then(nodesMock).shouldHaveNoInteractions(); - assertThat(actualRuleModel) - .isNotNull() - .usingRecursiveComparison() - .ignoringFields("ruleTypes") - .isEqualTo(expectedRuleModel); - } - - private Rule createRuleWithDefaultValues() { - return Rule.builder() - .id(RULE_ID) - .name(RULE_NAME) - .description(RULE_DESCRIPTION) - .isEnabled(RULE_ENABLED) - .isInheritable(RULE_INHERITABLE) - .isAsynchronous(RULE_ASYNC) - .triggers(List.of(RuleTrigger.INBOUND, RuleTrigger.UPDATE)) - .errorScript(ERROR_SCRIPT) - .conditions(compositeConditionMapper.toRestModel(Collections.emptyList())) - .create(); - } - - private static org.alfresco.service.cmr.rule.Rule createRuleModel() { - final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID); - final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule(nodeRef); - ruleModel.setTitle(RULE_NAME); - ruleModel.setDescription(RULE_DESCRIPTION); - ruleModel.setRuleDisabled(!RULE_ENABLED); - ruleModel.applyToChildren(RULE_INHERITABLE); - ruleModel.setExecuteAsynchronously(RULE_ASYNC); - ruleModel.setRuleTypes(List.of(RuleType.INBOUND, RuleType.UPDATE)); - ruleModel.setAction(createActionModel()); - - return ruleModel; - } - - private static org.alfresco.service.cmr.action.Action createActionModel() { - final ActionCondition actionCondition = new ActionConditionImpl("action-condition-id", "action-condition-def-name"); - final org.alfresco.service.cmr.action.Action actionModel = new ActionImpl(null, "action-id", ACTION_DEFINITION_NAME); - actionModel.setCompensatingAction(createCompensatingActionModel()); - actionModel.addActionCondition(actionCondition); - - return actionModel; - } - - private static org.alfresco.service.cmr.action.Action createCompensatingActionModel() { - final org.alfresco.service.cmr.action.Action compensatingActionModel = new ActionImpl(null, "compensating-action-id", ScriptActionExecuter.NAME); - compensatingActionModel.setParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF, ERROR_SCRIPT); - - return compensatingActionModel; - } -}