From d24baf9ecd327d2a5b978b296f431183fb8ac903 Mon Sep 17 00:00:00 2001 From: Maciej Pichura <41297682+mpichura@users.noreply.github.com> Date: Mon, 19 Sep 2022 12:42:26 +0200 Subject: [PATCH] ACS-3354 Rule mappers pt1 (simple condition mapper) (#1388) * ACS-3363: Add rule simple condition mapping layer - part 1. * ACS-3363: Add rule simple condition mapping layer - part 1 - fixes and cleanup. * ACS-3354: Fixes and refactors for rule mappers pt 1. --- .../RestRuleSimpleConditionModelMapper.java | 220 +++++++++++ .../rest/api/impl/rules/RuleLoader.java | 12 +- .../rest/api/impl/rules/RulesImpl.java | 13 +- .../api/model/mapper/RestModelMapper.java | 53 +++ .../api/model/rules/CompositeCondition.java | 19 +- .../alfresco/rest/api/model/rules/Rule.java | 10 +- .../rest/api/model/rules/SimpleCondition.java | 159 +------- .../alfresco/public-rest-context.xml | 9 +- .../org/alfresco/rest/api/RulesUnitTests.java | 10 +- ...estRuleSimpleConditionModelMapperTest.java | 372 ++++++++++++++++++ .../rest/api/impl/rules/RulesImplTest.java | 22 +- .../model/rules/CompositeConditionTest.java | 38 +- .../rest/api/model/rules/RuleTest.java | 16 +- .../api/model/rules/SimpleConditionTest.java | 332 +++------------- 14 files changed, 793 insertions(+), 492 deletions(-) create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapper.java create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/model/mapper/RestModelMapper.java create mode 100644 remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapper.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapper.java new file mode 100644 index 0000000000..1f356e140f --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapper.java @@ -0,0 +1,220 @@ +/* + * #%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.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.action.ActionConditionImpl; +import org.alfresco.repo.action.evaluator.CompareMimeTypeEvaluator; +import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator; +import org.alfresco.repo.action.evaluator.HasAspectEvaluator; +import org.alfresco.repo.action.evaluator.HasTagEvaluator; +import org.alfresco.repo.action.evaluator.InCategoryEvaluator; +import org.alfresco.repo.action.evaluator.IsSubTypeEvaluator; +import org.alfresco.repo.action.evaluator.NoConditionEvaluator; +import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation; +import org.alfresco.repo.action.evaluator.compare.ContentPropertyName; +import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.model.mapper.RestModelMapper; +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.service.Experimental; +import org.alfresco.service.cmr.action.ActionCondition; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.apache.commons.collections.MapUtils; + +@Experimental +public class RestRuleSimpleConditionModelMapper implements RestModelMapper +{ + private final NamespaceService namespaceService; + private final Nodes nodes; + + public RestRuleSimpleConditionModelMapper(NamespaceService namespaceService, Nodes nodes) + { + this.namespaceService = namespaceService; + this.nodes = nodes; + } + + @Override + public SimpleCondition toRestModel(ActionCondition actionCondition) + { + if (actionCondition == null || actionCondition.getActionConditionDefinitionName() == null || + MapUtils.isEmpty(actionCondition.getParameterValues())) + { + return null; + } + + switch (actionCondition.getActionConditionDefinitionName()) + { + case ComparePropertyValueEvaluator.NAME: + return createComparePropertyValueCondition(actionCondition, namespaceService); + case CompareMimeTypeEvaluator.NAME: + return createCompareMimeTypeCondition(actionCondition); + case HasAspectEvaluator.NAME: + return createHasAspectCondition(actionCondition, namespaceService); + case HasTagEvaluator.NAME: + return createHasTagCondition(actionCondition); + case InCategoryEvaluator.NAME: + return createInCategoryCondition(actionCondition); + case IsSubTypeEvaluator.NAME: + return createIsSubtypeCondition(actionCondition, namespaceService); + case NoConditionEvaluator.NAME: + default: + return null; + } + } + + @Override + public ActionCondition toServiceModel(SimpleCondition restModel) + { + final String field = restModel.getField(); + if (field == null) + { + return null; + } + + Map parameterValues = new HashMap<>(); + String conditionDefinitionId; + String parameter = restModel.getParameter(); + + switch (field) + { + case HasAspectEvaluator.PARAM_ASPECT: + conditionDefinitionId = HasAspectEvaluator.NAME; + parameterValues.put(HasAspectEvaluator.PARAM_ASPECT, QName.createQName(parameter, namespaceService)); + break; + case HasTagEvaluator.PARAM_TAG: + conditionDefinitionId = HasTagEvaluator.NAME; + parameterValues.put(HasTagEvaluator.PARAM_TAG, parameter); + break; + case SimpleCondition.PARAM_CATEGORY: + conditionDefinitionId = InCategoryEvaluator.NAME; + parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, ContentModel.ASPECT_GEN_CLASSIFIABLE); + try + { + parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, nodes.validateOrLookupNode(parameter, null)); + } catch (EntityNotFoundException e) { + throw new InvalidArgumentException(SimpleCondition.CATEGORY_INVALID_MSG); + } + break; + case IsSubTypeEvaluator.PARAM_TYPE: + conditionDefinitionId = IsSubTypeEvaluator.NAME; + parameterValues.put(IsSubTypeEvaluator.PARAM_TYPE, QName.createQName(parameter, namespaceService)); + break; + case SimpleCondition.PARAM_MIMETYPE: + conditionDefinitionId = CompareMimeTypeEvaluator.NAME; + parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); + parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, parameter); + break; + default: + conditionDefinitionId = ComparePropertyValueEvaluator.NAME; + try + { + // if size or encoding create content property evaluator + ContentPropertyName.valueOf(field.toUpperCase()); + parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, field.toUpperCase()); + parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); + } + catch (IllegalArgumentException ignore) + { + // else create common property evaluator + parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, QName.createQName(field, namespaceService)); + } + parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, restModel.getComparator().toUpperCase()); + parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, parameter); + break; + } + return new ActionConditionImpl(UUID.randomUUID().toString(), conditionDefinitionId, parameterValues); + } + + private static SimpleCondition createComparePropertyValueCondition(final ActionCondition actionCondition, final NamespaceService namespaceService) + { + final SimpleCondition.Builder builder = SimpleCondition.builder(); + if (actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY) != null) + { + builder.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY).toString().toLowerCase()); + } else { + builder.field(((QName) actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY)).toPrefixString(namespaceService)); + } + return builder + .comparator(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_OPERATION).toString().toLowerCase()) + .parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString()) + .create(); + } + + private static SimpleCondition createCompareMimeTypeCondition(final ActionCondition actionCondition) + { + return SimpleCondition.builder() + .field(SimpleCondition.PARAM_MIMETYPE) + .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) + .parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString()) + .create(); + } + + private static SimpleCondition createHasAspectCondition(final ActionCondition actionCondition, final NamespaceService namespaceService) + { + return SimpleCondition.builder() + .field(HasAspectEvaluator.PARAM_ASPECT) + .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) + .parameter(((QName) actionCondition.getParameterValues().get(HasAspectEvaluator.PARAM_ASPECT)).toPrefixString(namespaceService)) + .create(); + } + + private static SimpleCondition createHasTagCondition(final ActionCondition actionCondition) + { + return SimpleCondition.builder() + .field(HasTagEvaluator.PARAM_TAG) + .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) + .parameter(actionCondition.getParameterValues().get(HasTagEvaluator.PARAM_TAG).toString()) + .create(); + } + + private static SimpleCondition createInCategoryCondition(final ActionCondition actionCondition) + { + return SimpleCondition.builder() + .field(SimpleCondition.PARAM_CATEGORY) + .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) + .parameter(((NodeRef) actionCondition.getParameterValues().get(InCategoryEvaluator.PARAM_CATEGORY_VALUE)).getId()) + .create(); + } + + private static SimpleCondition createIsSubtypeCondition(final ActionCondition actionCondition, final NamespaceService namespaceService) + { + return SimpleCondition.builder() + .field(IsSubTypeEvaluator.PARAM_TYPE) + .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) + .parameter(((QName) actionCondition.getParameterValues().get(IsSubTypeEvaluator.PARAM_TYPE)).toPrefixString(namespaceService)) + .create(); + } +} 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 80b416ab5f..a96231a51b 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 @@ -27,8 +27,11 @@ package org.alfresco.rest.api.impl.rules; import java.util.List; +import org.alfresco.rest.api.model.mapper.RestModelMapper; import org.alfresco.rest.api.model.rules.Rule; +import org.alfresco.rest.api.model.rules.SimpleCondition; import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.ActionCondition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.namespace.NamespaceService; @@ -40,11 +43,11 @@ public class RuleLoader public static final String IS_SHARED = "isShared"; private RuleService ruleService; private NodeValidator nodeValidator; - private NamespaceService namespaceService; + private RestModelMapper simpleConditionMapper; public Rule loadRule(org.alfresco.service.cmr.rule.Rule ruleModel, List includes) { - Rule rule = Rule.from(ruleModel, namespaceService); + Rule rule = Rule.from(ruleModel, simpleConditionMapper); if (includes != null && includes.contains(IS_SHARED)) { NodeRef ruleSet = ruleService.getRuleSetNode(ruleModel.getNodeRef()); @@ -64,8 +67,9 @@ public class RuleLoader this.nodeValidator = nodeValidator; } - public void setNamespaceService(NamespaceService namespaceService) + public void setSimpleConditionMapper( + RestModelMapper simpleConditionMapper) { - this.namespaceService = namespaceService; + this.simpleConditionMapper = simpleConditionMapper; } } 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 b5cce2a8e8..df35db897c 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 @@ -32,13 +32,17 @@ import java.util.stream.Collectors; import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.Rules; +import org.alfresco.rest.api.model.mapper.RestModelMapper; import org.alfresco.rest.api.model.rules.Rule; import org.alfresco.rest.api.model.rules.RuleSet; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; +import org.alfresco.rest.api.model.rules.SimpleCondition; +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; 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.ActionCondition; import org.alfresco.service.cmr.action.CompositeAction; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.rule.RuleService; @@ -59,7 +63,7 @@ public class RulesImpl implements Rules private RuleLoader ruleLoader; private ActionParameterConverter actionParameterConverter; private ActionPermissionValidator actionPermissionValidator; - private NamespaceService namespaceService; + private RestModelMapper simpleConditionMapper; @Override public CollectionWithPagingInfo getRules(final String folderNodeId, @@ -133,7 +137,7 @@ 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, namespaceService); + final org.alfresco.service.cmr.rule.Rule serviceModelRule = rule.toServiceModel(nodes, simpleConditionMapper); final CompositeAction compositeAction = (CompositeAction) serviceModelRule.getAction(); compositeAction.getActions().forEach(action -> action.setParameterValues( actionParameterConverter.getConvertedParams(action.getParameterValues(), action.getActionDefinitionName()))); @@ -184,8 +188,9 @@ public class RulesImpl implements Rules this.actionPermissionValidator = actionPermissionValidator; } - public void setNamespaceService(NamespaceService namespaceService) + public void setSimpleConditionMapper( + RestModelMapper simpleConditionMapper) { - this.namespaceService = namespaceService; + this.simpleConditionMapper = simpleConditionMapper; } } 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 new file mode 100644 index 0000000000..1a76ab13a5 --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/mapper/RestModelMapper.java @@ -0,0 +1,53 @@ +/* + * #%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.mapper; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.alfresco.service.Experimental; +import org.apache.commons.lang3.NotImplementedException; + +@Experimental +public interface RestModelMapper +{ + R toRestModel(S serviceModel); + S toServiceModel(R restModel); + default R toRestModel(Collection serviceModels) { + throw new NotImplementedException(); + } + default S toServiceModel(Collection restModels) { + throw new NotImplementedException(); + } + default List toRestModels(Collection serviceModels) { + return serviceModels.stream().map(this::toRestModel).collect(Collectors.toList()); + } + default List toServiceModels(Collection restModels) { + return restModels.stream().map(this::toServiceModel).collect(Collectors.toList()); + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/CompositeCondition.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/CompositeCondition.java index fc0c64dbf9..30c808fc3f 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/CompositeCondition.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/CompositeCondition.java @@ -32,10 +32,9 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.model.mapper.RestModelMapper; import org.alfresco.service.Experimental; import org.alfresco.service.cmr.action.ActionCondition; -import org.alfresco.service.namespace.NamespaceService; import org.apache.commons.collections.CollectionUtils; @Experimental @@ -52,7 +51,7 @@ public class CompositeCondition * @param actionConditions - list of {@link ActionCondition} service POJOs * @return {@link CompositeCondition} REST model */ - public static CompositeCondition from(final List actionConditions, final NamespaceService namespaceService) + public static CompositeCondition from(final List actionConditions, final RestModelMapper simpleConditionMapper) { if (actionConditions == null) { @@ -64,7 +63,7 @@ public class CompositeCondition // group action conditions by inversion flag actionConditions.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(ActionCondition::getInvertCondition)) // map action condition sub lists - .forEach((inverted, actionConditionsPart) -> Optional.ofNullable(CompositeCondition.ofActionConditions(actionConditionsPart, namespaceService, inverted, ConditionOperator.AND)) + .forEach((inverted, actionConditionsPart) -> Optional.ofNullable(CompositeCondition.ofActionConditions(actionConditionsPart, simpleConditionMapper, inverted, ConditionOperator.AND)) // if composite condition present add to final list .ifPresent(compositeCondition -> conditions.compositeConditions.add(compositeCondition))); @@ -75,14 +74,16 @@ public class CompositeCondition return conditions; } - private static CompositeCondition ofActionConditions(final List actionConditions, final NamespaceService namespaceService, final boolean inverted, final ConditionOperator conditionOperator) + private static CompositeCondition ofActionConditions(final List actionConditions, + final RestModelMapper simpleConditionMapper, + final boolean inverted, final ConditionOperator conditionOperator) { if (actionConditions == null) { return null; } - return ofSimpleConditions(SimpleCondition.listOf(actionConditions, namespaceService), inverted, conditionOperator); + return ofSimpleConditions(SimpleCondition.listOf(actionConditions, simpleConditionMapper), inverted, conditionOperator); } /** @@ -114,16 +115,16 @@ public class CompositeCondition .create(); } - public List toServiceModels(final Nodes nodes, final NamespaceService namespaceService) + public List toServiceModels(final RestModelMapper simpleConditionMapper) { final List actionConditions = new ArrayList<>(); if (CollectionUtils.isNotEmpty(simpleConditions)) { - simpleConditions.forEach(simpleCondition -> actionConditions.add(simpleCondition.toServiceModel(inverted, nodes, namespaceService))); + simpleConditions.forEach(simpleCondition -> actionConditions.add(simpleCondition.toServiceModel(inverted, simpleConditionMapper))); } if (CollectionUtils.isNotEmpty(compositeConditions)) { - compositeConditions.forEach(compositeCondition -> actionConditions.addAll(compositeCondition.toServiceModels(nodes, namespaceService))); + compositeConditions.forEach(compositeCondition -> actionConditions.addAll(compositeCondition.toServiceModels(simpleConditionMapper))); } return actionConditions; 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 4cad8386cc..69ee8fd385 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 @@ -33,8 +33,10 @@ 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.service.namespace.NamespaceService; @@ -61,7 +63,7 @@ public class 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 NamespaceService namespaceService) + public static Rule from(final org.alfresco.service.cmr.rule.Rule ruleModel, final RestModelMapper simpleConditionMapper) { if (ruleModel == null) { @@ -84,7 +86,7 @@ public class Rule } if (ruleModel.getAction() != null) { - builder.conditions(CompositeCondition.from(ruleModel.getAction().getActionConditions(), namespaceService)); + builder.conditions(CompositeCondition.from(ruleModel.getAction().getActionConditions(), simpleConditionMapper)); if (ruleModel.getAction().getCompensatingAction() != null && ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF) != null) { builder.errorScript(ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF).toString()); @@ -104,7 +106,7 @@ public class Rule * @param nodes The nodes API. * @return The rule service POJO. */ - public org.alfresco.service.cmr.rule.Rule toServiceModel(final Nodes nodes, final NamespaceService namespaceService) + public org.alfresco.service.cmr.rule.Rule toServiceModel(final Nodes nodes, final RestModelMapper simpleConditionMapper) { 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; @@ -127,7 +129,7 @@ public class Rule } if (conditions != null) { - conditions.toServiceModels(nodes, namespaceService).forEach(condition -> ruleModel.getAction().addActionCondition(condition)); + conditions.toServiceModels(simpleConditionMapper).forEach(condition -> ruleModel.getAction().addActionCondition(condition)); } return ruleModel; diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/SimpleCondition.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/SimpleCondition.java index 54e0b566a0..1037f0f9af 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/SimpleCondition.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/SimpleCondition.java @@ -46,6 +46,7 @@ import org.alfresco.repo.action.evaluator.NoConditionEvaluator; import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation; import org.alfresco.repo.action.evaluator.compare.ContentPropertyName; import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.model.mapper.RestModelMapper; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.service.Experimental; @@ -58,7 +59,7 @@ import org.apache.commons.collections.CollectionUtils; @Experimental public class SimpleCondition { - private static final String CATEGORY_INVALID_MSG = "Category in condition is invalid"; + public static final String CATEGORY_INVALID_MSG = "Category in condition is invalid"; public static final String PARAM_CATEGORY = "category"; public static final String PARAM_MIMETYPE = "mimetype"; @@ -72,17 +73,14 @@ public class SimpleCondition * @param actionConditions - list of {@link ActionCondition} service POJOs * @return list of {@link SimpleCondition} REST models */ - public static List listOf(final List actionConditions, final NamespaceService namespaceService) + public static List listOf(final List actionConditions, + final RestModelMapper simpleConditionMapper) { if (CollectionUtils.isEmpty(actionConditions)) { return null; } - - return actionConditions.stream() - .map(actionCondition -> from(actionCondition, namespaceService)) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + return simpleConditionMapper.toRestModels(actionConditions); } /** @@ -91,92 +89,15 @@ public class SimpleCondition * @param actionCondition - {@link ActionCondition} service POJO * @return {@link SimpleCondition} REST model */ - public static SimpleCondition from(final ActionCondition actionCondition, final NamespaceService namespaceService) + public static SimpleCondition from(final ActionCondition actionCondition, + final RestModelMapper simpleConditionMapper) { - if (actionCondition == null || actionCondition.getActionConditionDefinitionName() == null || actionCondition.getParameterValues() == null) - { - return null; - } - - switch (actionCondition.getActionConditionDefinitionName()) - { - case ComparePropertyValueEvaluator.NAME: - return createComparePropertyValueCondition(actionCondition, namespaceService); - case CompareMimeTypeEvaluator.NAME: - return createCompareMimeTypeCondition(actionCondition); - case HasAspectEvaluator.NAME: - return createHasAspectCondition(actionCondition, namespaceService); - case HasTagEvaluator.NAME: - return createHasTagCondition(actionCondition); - case InCategoryEvaluator.NAME: - return createInCategoryCondition(actionCondition); - case IsSubTypeEvaluator.NAME: - return createIsSubtypeCondition(actionCondition, namespaceService); - case NoConditionEvaluator.NAME: - default: - return null; - } + return simpleConditionMapper.toRestModel(actionCondition); } - public ActionCondition toServiceModel(final boolean inverted, final Nodes nodes, final NamespaceService namespaceService) + public ActionCondition toServiceModel(final boolean inverted, final RestModelMapper mapper) { - if (field == null) - { - return null; - } - - Map parameterValues = new HashMap<>(); - String conditionDefinitionId; - - switch (field) - { - case HasAspectEvaluator.PARAM_ASPECT: - conditionDefinitionId = HasAspectEvaluator.NAME; - parameterValues.put(HasAspectEvaluator.PARAM_ASPECT, QName.createQName(parameter, namespaceService)); - break; - case HasTagEvaluator.PARAM_TAG: - conditionDefinitionId = HasTagEvaluator.NAME; - parameterValues.put(HasTagEvaluator.PARAM_TAG, parameter); - break; - case PARAM_CATEGORY: - conditionDefinitionId = InCategoryEvaluator.NAME; - parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, ContentModel.ASPECT_GEN_CLASSIFIABLE); - try - { - parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, nodes.validateOrLookupNode(parameter, null)); - } catch (EntityNotFoundException e) { - throw new InvalidArgumentException(CATEGORY_INVALID_MSG); - } - break; - case IsSubTypeEvaluator.PARAM_TYPE: - conditionDefinitionId = IsSubTypeEvaluator.NAME; - parameterValues.put(IsSubTypeEvaluator.PARAM_TYPE, QName.createQName(parameter, namespaceService)); - break; - case PARAM_MIMETYPE: - conditionDefinitionId = CompareMimeTypeEvaluator.NAME; - parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); - parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, parameter); - break; - default: - conditionDefinitionId = ComparePropertyValueEvaluator.NAME; - try - { - // if size or encoding create content property evaluator - ContentPropertyName.valueOf(field.toUpperCase()); - parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, field.toUpperCase()); - parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); - } - catch (IllegalArgumentException ignore) - { - // else create common property evaluator - parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, QName.createQName(field, namespaceService)); - } - parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, comparator.toUpperCase()); - parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, parameter); - break; - } - - final ActionCondition actionCondition = new ActionConditionImpl(UUID.randomUUID().toString(), conditionDefinitionId, parameterValues); + final ActionCondition actionCondition = mapper.toServiceModel(this); actionCondition.setInvertCondition(inverted); return actionCondition; } @@ -234,66 +155,6 @@ public class SimpleCondition return Objects.hash(field, comparator, parameter); } - private static SimpleCondition createComparePropertyValueCondition(final ActionCondition actionCondition, final NamespaceService namespaceService) - { - final SimpleCondition.Builder builder = builder(); - if (actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY) != null) - { - builder.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY).toString().toLowerCase()); - } else { - builder.field(((QName) actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY)).toPrefixString(namespaceService)); - } - return builder - .comparator(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_OPERATION).toString().toLowerCase()) - .parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString()) - .create(); - } - - private static SimpleCondition createCompareMimeTypeCondition(final ActionCondition actionCondition) - { - return builder() - .field(PARAM_MIMETYPE) - .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) - .parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString()) - .create(); - } - - private static SimpleCondition createHasAspectCondition(final ActionCondition actionCondition, final NamespaceService namespaceService) - { - return builder() - .field(HasAspectEvaluator.PARAM_ASPECT) - .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) - .parameter(((QName) actionCondition.getParameterValues().get(HasAspectEvaluator.PARAM_ASPECT)).toPrefixString(namespaceService)) - .create(); - } - - private static SimpleCondition createHasTagCondition(final ActionCondition actionCondition) - { - return builder() - .field(HasTagEvaluator.PARAM_TAG) - .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) - .parameter(actionCondition.getParameterValues().get(HasTagEvaluator.PARAM_TAG).toString()) - .create(); - } - - private static SimpleCondition createInCategoryCondition(final ActionCondition actionCondition) - { - return builder() - .field(PARAM_CATEGORY) - .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) - .parameter(((NodeRef) actionCondition.getParameterValues().get(InCategoryEvaluator.PARAM_CATEGORY_VALUE)).getId()) - .create(); - } - - private static SimpleCondition createIsSubtypeCondition(final ActionCondition actionCondition, final NamespaceService namespaceService) - { - return builder() - .field(IsSubTypeEvaluator.PARAM_TYPE) - .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) - .parameter(((QName) actionCondition.getParameterValues().get(IsSubTypeEvaluator.PARAM_TYPE)).toPrefixString(namespaceService)) - .create(); - } - public static Builder builder() { return new Builder(); 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 e4c38b46db..feb432b8f9 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 @@ - + @@ -911,7 +911,7 @@ - + @@ -947,6 +947,11 @@ + + + + + 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 6718c031aa..ab63a58c53 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,7 +26,11 @@ package org.alfresco.rest.api; +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.model.rules.CompositeConditionTest; @@ -48,7 +52,11 @@ import org.junit.runners.Suite; RuleTest.class, ActionTest.class, SimpleConditionTest.class, - CompositeConditionTest.class + CompositeConditionTest.class, + RuleLoaderTest.class, + ActionParameterConverterTest.class, + ActionPermissionValidatorTest.class, + RestRuleSimpleConditionModelMapperTest.class }) public class RulesUnitTests { 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 new file mode 100644 index 0000000000..60f4409846 --- /dev/null +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java @@ -0,0 +1,372 @@ +/* + * #%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.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.BDDMockito.given; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import junit.framework.TestCase; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.action.ActionConditionImpl; +import org.alfresco.repo.action.evaluator.CompareMimeTypeEvaluator; +import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator; +import org.alfresco.repo.action.evaluator.HasAspectEvaluator; +import org.alfresco.repo.action.evaluator.HasChildEvaluator; +import org.alfresco.repo.action.evaluator.HasTagEvaluator; +import org.alfresco.repo.action.evaluator.HasVersionHistoryEvaluator; +import org.alfresco.repo.action.evaluator.InCategoryEvaluator; +import org.alfresco.repo.action.evaluator.IsSubTypeEvaluator; +import org.alfresco.repo.action.evaluator.NoConditionEvaluator; +import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation; +import org.alfresco.repo.action.evaluator.compare.ContentPropertyName; +import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.model.rules.SimpleCondition; +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.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +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; + +@Experimental +@RunWith(MockitoJUnitRunner.class) +public class RestRuleSimpleConditionModelMapperTest extends TestCase +{ + private static final boolean NULL_RESULT = true; + private static final String PARAMETER_DEFAULT = "value"; + + @Mock + private NamespaceService namespaceServiceMock; + @Mock + private Nodes nodesMock; + + @InjectMocks + private RestRuleSimpleConditionModelMapper objectUnderTest; + + @Before + public void setUp() throws Exception + { + given(namespaceServiceMock.getPrefixes(NamespaceService.CONTENT_MODEL_1_0_URI)).willReturn(List.of(NamespaceService.CONTENT_MODEL_PREFIX)); + given(namespaceServiceMock.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).willReturn(NamespaceService.CONTENT_MODEL_1_0_URI); + given(namespaceServiceMock.getPrefixes(NamespaceService.AUDIO_MODEL_1_0_URI)).willReturn(List.of(NamespaceService.AUDIO_MODEL_PREFIX)); + given(namespaceServiceMock.getNamespaceURI(NamespaceService.AUDIO_MODEL_PREFIX)).willReturn(NamespaceService.AUDIO_MODEL_1_0_URI); + } + + @Test + public void testToRestModel() + { + for (TestData testData : getTestData()) + { + final ActionCondition actionCondition = createActionCondition(testData.conditionDefinitionName); + + // when + final SimpleCondition actualSimpleCondition = objectUnderTest.toRestModel(actionCondition); + + assertThat(Objects.isNull(actualSimpleCondition)).isEqualTo(testData.isNullResult); + if (!testData.isNullResult) + { + assertThat(actualSimpleCondition.getField()).isNotEmpty(); + assertThat(actualSimpleCondition.getComparator()).isNotEmpty(); + assertThat(actualSimpleCondition.getParameter()).isNotEmpty(); + } + } + } + + @Test + public void testToRestModelFromNullValue() + { + // when + final ActionCondition actionCondition = null; + final SimpleCondition actualSimpleCondition = objectUnderTest.toRestModel(actionCondition); + + assertThat(actualSimpleCondition).isNull(); + } + + @Test + public void testToRestModelFromActionConditionWithoutDefinitionName() + { + final ActionCondition actionCondition = new ActionConditionImpl("fake-id", null, createParameterValues()); + + // when + final SimpleCondition actualSimpleCondition = objectUnderTest.toRestModel(actionCondition); + + assertThat(actualSimpleCondition).isNull(); + } + + @Test + public void testToRestModelFromActionConditionWithoutParameterValues() + { + final ActionCondition actionCondition = new ActionConditionImpl("fake-id", "fake-def-name", null); + + // when + final SimpleCondition actualSimpleCondition = objectUnderTest.toRestModel(actionCondition); + + assertThat(actualSimpleCondition).isNull(); + } + + @Test + public void testToRestModelListOfEmptyActionConditions() + { + // when + final List actualSimpleConditions = objectUnderTest.toRestModels(Collections.emptyList()); + + assertThat(actualSimpleConditions).isEmpty(); + } + + @Test + public void testToRestModelListOfNullActionConditions() + { + // when + assertThatExceptionOfType(NullPointerException.class).isThrownBy(() -> objectUnderTest.toRestModels(null)); + } + + @Test + public void testToRestModelListOfActionConditionsContainingNull() + { + final List actionConditions = new ArrayList<>(); + actionConditions.add(null); + + // when + final List actualSimpleConditions = objectUnderTest.toRestModels(actionConditions); + + assertThat(actualSimpleConditions).hasSize(1).containsOnlyNulls(); + } + + @Test + public void testToServiceModel_withSizeContentProperty() + { + final SimpleCondition simpleCondition = createSimpleCondition(ContentPropertyName.SIZE.toString().toLowerCase()); + + // when + final ActionCondition actualActionCondition = objectUnderTest.toServiceModel(simpleCondition); + + final Map expectedParameterValues = new HashMap<>(); + expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, ContentPropertyName.SIZE.toString()); + expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); + expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.EQUALS.toString()); + expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, PARAMETER_DEFAULT); + ActionCondition expectedActionCondition = new ActionConditionImpl(null, ComparePropertyValueEvaluator.NAME, expectedParameterValues); + assertThat(actualActionCondition) + .isNotNull().usingRecursiveComparison().ignoringFields("id") + .isEqualTo(expectedActionCondition); + } + + @Test + public void testToServiceModel_withoutContentProperty() + { + final String field = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + ContentModel.PROP_DESCRIPTION.toPrefixString(); + final SimpleCondition simpleCondition = createSimpleCondition(field); + + // when + final ActionCondition actualActionCondition = objectUnderTest.toServiceModel(simpleCondition); + + final Map expectedParameterValues = new HashMap<>(); + expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.PROP_DESCRIPTION); + expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.EQUALS.toString()); + expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, PARAMETER_DEFAULT); + final ActionCondition expectedActionCondition = new ActionConditionImpl(null, ComparePropertyValueEvaluator.NAME, expectedParameterValues); + assertThat(actualActionCondition) + .isNotNull().usingRecursiveComparison().ignoringFields("id", "parameterValues.property.prefix") + .isEqualTo(expectedActionCondition); + } + + @Test + public void testToServiceModel_compareMimetype() + { + final SimpleCondition simpleCondition = createSimpleCondition(SimpleCondition.PARAM_MIMETYPE); + + // when + final ActionCondition actualActionCondition = objectUnderTest.toServiceModel(simpleCondition); + + final Map expectedParameterValues = new HashMap<>(); + expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); + expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, PARAMETER_DEFAULT); + final ActionCondition expectedActionCondition = new ActionConditionImpl(null, CompareMimeTypeEvaluator.NAME, expectedParameterValues); + assertThat(actualActionCondition) + .isNotNull().usingRecursiveComparison().ignoringFields("id") + .isEqualTo(expectedActionCondition); + } + + @Test + public void testToServiceModel_hasAspect() + { + final QName audioAspect = QName.createQName(NamespaceService.AUDIO_MODEL_1_0_URI, NamespaceService.AUDIO_MODEL_PREFIX); + final String field = NamespaceService.AUDIO_MODEL_PREFIX + QName.NAMESPACE_PREFIX + NamespaceService.AUDIO_MODEL_PREFIX; + final SimpleCondition simpleCondition = createSimpleCondition(HasAspectEvaluator.PARAM_ASPECT, field); + + // when + final ActionCondition actualActionCondition = objectUnderTest.toServiceModel(simpleCondition); + + final Map expectedParameterValues = new HashMap<>(); + expectedParameterValues.put(HasAspectEvaluator.PARAM_ASPECT, audioAspect); + final ActionCondition expectedActionCondition = new ActionConditionImpl(null, HasAspectEvaluator.NAME, expectedParameterValues); + assertThat(actualActionCondition) + .isNotNull().usingRecursiveComparison().ignoringFields("id", "parameterValues.aspect.prefix") + .isEqualTo(expectedActionCondition); + } + + @Test + public void testToServiceModel_hasTag() + { + final String tag = "some tag"; + final SimpleCondition simpleCondition = createSimpleCondition(HasTagEvaluator.PARAM_TAG, tag); + + // when + final ActionCondition actualActionCondition = objectUnderTest.toServiceModel(simpleCondition); + + final Map expectedParameterValues = new HashMap<>(); + expectedParameterValues.put(HasTagEvaluator.PARAM_TAG, tag); + final ActionCondition expectedActionCondition = new ActionConditionImpl(null, HasTagEvaluator.NAME, expectedParameterValues); + assertThat(actualActionCondition) + .isNotNull().usingRecursiveComparison().ignoringFields("id") + .isEqualTo(expectedActionCondition); + } + + @Test + public void testToServiceModel_inCategory() + { + final SimpleCondition simpleCondition = createSimpleCondition(SimpleCondition.PARAM_CATEGORY); + final NodeRef defaultNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARAMETER_DEFAULT); + given(nodesMock.validateOrLookupNode(PARAMETER_DEFAULT, null)).willReturn(defaultNodeRef); + + // when + final ActionCondition actualActionCondition = objectUnderTest.toServiceModel(simpleCondition); + + final Map expectedParameterValues = new HashMap<>(); + expectedParameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, ContentModel.ASPECT_GEN_CLASSIFIABLE); + expectedParameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, defaultNodeRef); + final ActionCondition expectedActionCondition = new ActionConditionImpl(null, InCategoryEvaluator.NAME, expectedParameterValues); + assertThat(actualActionCondition) + .isNotNull().usingRecursiveComparison().ignoringFields("id") + .isEqualTo(expectedActionCondition); + } + + @Test + public void testToServiceModel_isSubType() + { + final String field = NamespaceService.CONTENT_MODEL_PREFIX + QName.NAMESPACE_PREFIX + ContentModel.TYPE_FOLDER.toPrefixString(); + final SimpleCondition simpleCondition = createSimpleCondition(IsSubTypeEvaluator.PARAM_TYPE, field); + + // when + final ActionCondition actualActionCondition = objectUnderTest.toServiceModel(simpleCondition); + + final Map expectedParameterValues = new HashMap<>(); + expectedParameterValues.put(IsSubTypeEvaluator.PARAM_TYPE, ContentModel.TYPE_FOLDER); + final ActionCondition expectedActionCondition = new ActionConditionImpl(null, IsSubTypeEvaluator.NAME, expectedParameterValues); + assertThat(actualActionCondition) + .isNotNull().usingRecursiveComparison().ignoringFields("id", "parameterValues.type.prefix") + .isEqualTo(expectedActionCondition); + } + + private static ActionCondition createActionCondition(final String actionDefinitionName) + { + return new ActionConditionImpl("fake-id", actionDefinitionName, createParameterValues()); + } + + private static Map createParameterValues() { + final QName audioAspect = QName.createQName(NamespaceService.AUDIO_MODEL_1_0_URI, NamespaceService.AUDIO_MODEL_PREFIX); + final NodeRef defaultNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARAMETER_DEFAULT); + final Map parameterValues = new HashMap<>(); + parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, "content-property"); + parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); + parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, "operation"); + parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, "value"); + parameterValues.put(HasAspectEvaluator.PARAM_ASPECT, audioAspect); + parameterValues.put(HasTagEvaluator.PARAM_TAG, "tag"); + parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, "category-aspect"); + parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, defaultNodeRef); + parameterValues.put(IsSubTypeEvaluator.PARAM_TYPE, ContentModel.TYPE_FOLDER); + + return parameterValues; + } + + private static SimpleCondition createSimpleCondition(final String field) + { + return createSimpleCondition(field, PARAMETER_DEFAULT); + } + + private static SimpleCondition createSimpleCondition(final String field, final String parameter) + { + return SimpleCondition.builder() + .field(field) + .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) + .parameter(parameter) + .create(); + } + + private static List getTestData() { + return List.of( + TestData.of(ComparePropertyValueEvaluator.NAME), + TestData.of(CompareMimeTypeEvaluator.NAME), + TestData.of(HasAspectEvaluator.NAME), + TestData.of(HasChildEvaluator.NAME, NULL_RESULT), + TestData.of(HasTagEvaluator.NAME), + TestData.of(HasVersionHistoryEvaluator.NAME, NULL_RESULT), + TestData.of(InCategoryEvaluator.NAME), + TestData.of(IsSubTypeEvaluator.NAME), + TestData.of(NoConditionEvaluator.NAME, NULL_RESULT), + TestData.of("fake-definition-name", NULL_RESULT), + TestData.of("", NULL_RESULT), + TestData.of(null, NULL_RESULT) + ); + } + + private static class TestData + { + String conditionDefinitionName; + boolean isNullResult; + + public TestData(String conditionDefinitionName, boolean isNullResult) + { + this.conditionDefinitionName = conditionDefinitionName; + this.isNullResult = isNullResult; + } + + public static TestData of(String conditionDefinitionName) { + return new TestData(conditionDefinitionName, false); + } + + public static TestData of(String conditionDefinitionName, boolean isNullResult) { + return new TestData(conditionDefinitionName, isNullResult); + } + } +} 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 c47f0a19d3..5b64a1bdcd 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 @@ -50,7 +50,9 @@ 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.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; @@ -58,11 +60,11 @@ 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; -import org.alfresco.service.namespace.NamespaceService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -89,7 +91,7 @@ public class RulesImplTest extends TestCase @Mock private Nodes nodesMock; @Mock - private NamespaceService namespaceService; + private RestModelMapper simpleConditionMapperMock; @Mock private NodeValidator nodeValidatorMock; @Mock @@ -295,7 +297,7 @@ public class RulesImplTest extends TestCase public void testCreateRules() { List ruleList = List.of(ruleMock); - given(ruleMock.toServiceModel(nodesMock, namespaceService)).willReturn(serviceRuleMock); + given(ruleMock.toServiceModel(nodesMock, simpleConditionMapperMock)).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]); @@ -312,7 +314,7 @@ public class RulesImplTest extends TestCase then(actionParameterConverterMock).shouldHaveNoMoreInteractions(); then(actionPermissionValidatorMock).should().validateRulePermissions(serviceRuleMock); then(actionPermissionValidatorMock).shouldHaveNoMoreInteractions(); - then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleMock.toServiceModel(nodesMock, namespaceService)); + then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleMock.toServiceModel(nodesMock, simpleConditionMapperMock)); then(ruleServiceMock).shouldHaveNoMoreInteractions(); List expected = List.of(ruleMock); assertThat(actual).isEqualTo(expected); @@ -325,7 +327,7 @@ public class RulesImplTest extends TestCase public void testCreateRules_defaultRuleSet() { List ruleList = List.of(ruleMock); - given(ruleMock.toServiceModel(nodesMock, namespaceService)).willReturn(serviceRuleMock); + given(ruleMock.toServiceModel(nodesMock, simpleConditionMapperMock)).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); @@ -341,7 +343,7 @@ public class RulesImplTest extends TestCase then(actionParameterConverterMock).shouldHaveNoMoreInteractions(); then(actionPermissionValidatorMock).should().validateRulePermissions(serviceRuleMock); then(actionPermissionValidatorMock).shouldHaveNoMoreInteractions(); - then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleMock.toServiceModel(nodesMock, namespaceService)); + then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleMock.toServiceModel(nodesMock, simpleConditionMapperMock)); then(ruleServiceMock).shouldHaveNoMoreInteractions(); List expected = List.of(ruleMock); assertThat(actual).isEqualTo(expected); @@ -372,7 +374,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, namespaceService)).willReturn(serviceRuleMockInner); + given(ruleBodyMock.toServiceModel(nodesMock, simpleConditionMapperMock)).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); @@ -391,8 +393,8 @@ public class RulesImplTest extends TestCase then(nodeValidatorMock).shouldHaveNoMoreInteractions(); for (Rule ruleBody : ruleBodyList) { - then(actionPermissionValidatorMock).should().validateRulePermissions(ruleBody.toServiceModel(nodesMock, namespaceService)); - then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleBody.toServiceModel(nodesMock, namespaceService)); + then(actionPermissionValidatorMock).should().validateRulePermissions(ruleBody.toServiceModel(nodesMock, simpleConditionMapperMock)); + then(ruleServiceMock).should().saveRule(FOLDER_NODE_REF, ruleBody.toServiceModel(nodesMock, simpleConditionMapperMock)); } then(actionParameterConverterMock).should(times(3)).getConvertedParams(DUMMY_PARAMS, ACTION_DEFINITION_NAME); then(actionParameterConverterMock).shouldHaveNoMoreInteractions(); @@ -466,7 +468,7 @@ public class RulesImplTest extends TestCase @Test public void testUpdateRuleById() { - given(ruleMock.toServiceModel(nodesMock, namespaceService)).willReturn(serviceRuleMock); + given(ruleMock.toServiceModel(nodesMock, simpleConditionMapperMock)).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); diff --git a/remote-api/src/test/java/org/alfresco/rest/api/model/rules/CompositeConditionTest.java b/remote-api/src/test/java/org/alfresco/rest/api/model/rules/CompositeConditionTest.java index 80b225cfc4..c1b3c11e41 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/model/rules/CompositeConditionTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/model/rules/CompositeConditionTest.java @@ -38,11 +38,13 @@ import java.util.Map; import org.alfresco.repo.action.ActionConditionImpl; import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator; +import org.alfresco.rest.api.impl.mapper.rules.RestRuleSimpleConditionModelMapper; +import org.alfresco.rest.api.model.mapper.RestModelMapper; import org.alfresco.service.Experimental; import org.alfresco.service.cmr.action.ActionCondition; -import org.alfresco.service.namespace.NamespaceService; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; @Experimental @@ -50,28 +52,32 @@ import org.mockito.junit.MockitoJUnitRunner; public class CompositeConditionTest { - private final NamespaceService namespaceService = mock(NamespaceService.class); + private final RestModelMapper simpleConditionMapper = mock(RestRuleSimpleConditionModelMapper.class); @Test public void testFrom() { final List actionConditions = List.of( - createActionCondition("value1"), - createActionCondition("value2", true), - createActionCondition("value3") + createActionCondition("value1"), + createActionCondition("value3"), + createActionCondition("value2", true) ); - final CompositeCondition expectedCompositeCondition = createCompositeCondition(List.of( - createCompositeCondition(false, List.of( + final List simpleConditions = List.of( createSimpleCondition("value1"), - createSimpleCondition("value3") - )), - createCompositeCondition(true, List.of( + createSimpleCondition("value3"), createSimpleCondition("value2") - )) + ); + + final CompositeCondition expectedCompositeCondition = createCompositeCondition(List.of( + createCompositeCondition(false, simpleConditions.subList(0,2)), + createCompositeCondition(true, simpleConditions.subList(2,3)) )); + Mockito.when(simpleConditionMapper.toRestModels(actionConditions.subList(0,2))).thenReturn(simpleConditions.subList(0,2)); + Mockito.when(simpleConditionMapper.toRestModels(actionConditions.subList(2,3))).thenReturn(simpleConditions.subList(2,3)); + // when - final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions, namespaceService); + final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions, simpleConditionMapper); assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition); } @@ -83,7 +89,7 @@ public class CompositeConditionTest final CompositeCondition expectedCompositeCondition = CompositeCondition.builder().create(); // when - final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions, namespaceService); + final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions, simpleConditionMapper); assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition); } @@ -92,7 +98,7 @@ public class CompositeConditionTest public void testFromNullValue() { // when - final CompositeCondition actualCompositeCondition = CompositeCondition.from(null, namespaceService); + final CompositeCondition actualCompositeCondition = CompositeCondition.from(null, simpleConditionMapper); assertThat(actualCompositeCondition).isNull(); } @@ -105,7 +111,7 @@ public class CompositeConditionTest final CompositeCondition expectedCompositeCondition = CompositeCondition.builder().create(); // when - final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions, namespaceService); + final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions, simpleConditionMapper); assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition); } @@ -184,4 +190,4 @@ public class CompositeConditionTest .simpleConditions(simpleConditions) .create(); } -} \ No newline at end of file +} 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 index 72a4d9b1ce..9a94c22924 100644 --- 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 @@ -37,6 +37,8 @@ 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.RestRuleSimpleConditionModelMapper; +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; @@ -61,7 +63,7 @@ public class RuleTest private static final String ACTION_DEFINITION_NAME = "action-def-name"; private static final String ERROR_SCRIPT = "error-script-ref"; - private final NamespaceService namespaceService = mock(NamespaceService.class); + private final RestModelMapper simpleConditionMapper = mock(RestRuleSimpleConditionModelMapper.class); @Test public void testFrom() @@ -70,7 +72,7 @@ public class RuleTest final Rule expectedRule = createRuleWithDefaultValues(); // when - final Rule actualRule = Rule.from(ruleModel, namespaceService); + final Rule actualRule = Rule.from(ruleModel, simpleConditionMapper); assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule); @@ -83,7 +85,7 @@ public class RuleTest final Rule expectedRule = Rule.builder().enabled(true).create(); // when - final Rule actualRule = Rule.from(ruleModel, namespaceService); + final Rule actualRule = Rule.from(ruleModel, simpleConditionMapper); assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule); @@ -99,7 +101,7 @@ public class RuleTest final org.alfresco.service.cmr.action.Action expectedCompensatingActionModel = createCompensatingActionModel(); // when - final org.alfresco.service.cmr.rule.Rule actualRuleModel = rule.toServiceModel(nodesMock, namespaceService); + final org.alfresco.service.cmr.rule.Rule actualRuleModel = rule.toServiceModel(nodesMock, simpleConditionMapper); then(nodesMock).should().validateOrLookupNode(RULE_ID, null); then(nodesMock).shouldHaveNoMoreInteractions(); @@ -124,7 +126,7 @@ public class RuleTest expectedRuleModel.setRuleDisabled(true); // when - final org.alfresco.service.cmr.rule.Rule actualRuleModel = rule.toServiceModel(nodesMock, namespaceService); + final org.alfresco.service.cmr.rule.Rule actualRuleModel = rule.toServiceModel(nodesMock, simpleConditionMapper); then(nodesMock).shouldHaveNoInteractions(); assertThat(actualRuleModel) @@ -144,7 +146,7 @@ public class RuleTest .asynchronous(RULE_ASYNC) .triggers(List.of(RuleTrigger.INBOUND, RuleTrigger.UPDATE)) .errorScript(ERROR_SCRIPT) - .conditions(CompositeCondition.from(Collections.emptyList(), namespaceService)) + .conditions(CompositeCondition.from(Collections.emptyList(), simpleConditionMapper)) .create(); } @@ -177,4 +179,4 @@ public class RuleTest return compensatingActionModel; } -} \ No newline at end of file +} diff --git a/remote-api/src/test/java/org/alfresco/rest/api/model/rules/SimpleConditionTest.java b/remote-api/src/test/java/org/alfresco/rest/api/model/rules/SimpleConditionTest.java index 6520a57fe2..2f75032dfc 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/model/rules/SimpleConditionTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/model/rules/SimpleConditionTest.java @@ -28,37 +28,21 @@ package org.alfresco.rest.api.model.rules; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.mock; -import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; -import org.alfresco.model.ContentModel; import org.alfresco.repo.action.ActionConditionImpl; -import org.alfresco.repo.action.evaluator.CompareMimeTypeEvaluator; import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator; -import org.alfresco.repo.action.evaluator.HasAspectEvaluator; -import org.alfresco.repo.action.evaluator.HasChildEvaluator; -import org.alfresco.repo.action.evaluator.HasTagEvaluator; -import org.alfresco.repo.action.evaluator.HasVersionHistoryEvaluator; -import org.alfresco.repo.action.evaluator.InCategoryEvaluator; -import org.alfresco.repo.action.evaluator.IsSubTypeEvaluator; -import org.alfresco.repo.action.evaluator.NoConditionEvaluator; import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation; -import org.alfresco.repo.action.evaluator.compare.ContentPropertyName; -import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.impl.mapper.rules.RestRuleSimpleConditionModelMapper; +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.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @@ -67,123 +51,49 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class SimpleConditionTest { - private static final boolean NULL_RESULT = true; - private static final boolean NOT_INVERTED = false; - private static final String PARAMETER_DEFAULT = "value"; + private static final boolean INVERTED = true; + private static final String VALUE = "value"; + private static final String KEY = "key"; - private final Nodes nodes = mock(Nodes.class); - private final NamespaceService namespaceService = mock(NamespaceService.class); - - @Before - public void setUp() throws Exception - { - given(namespaceService.getPrefixes(NamespaceService.CONTENT_MODEL_1_0_URI)).willReturn(List.of(NamespaceService.CONTENT_MODEL_PREFIX)); - given(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).willReturn(NamespaceService.CONTENT_MODEL_1_0_URI); - given(namespaceService.getPrefixes(NamespaceService.AUDIO_MODEL_1_0_URI)).willReturn(List.of(NamespaceService.AUDIO_MODEL_PREFIX)); - given(namespaceService.getNamespaceURI(NamespaceService.AUDIO_MODEL_PREFIX)).willReturn(NamespaceService.AUDIO_MODEL_1_0_URI); - } - - private static List getTestData() { - return List.of( - TestData.of(ComparePropertyValueEvaluator.NAME), - TestData.of(CompareMimeTypeEvaluator.NAME), - TestData.of(HasAspectEvaluator.NAME), - TestData.of(HasChildEvaluator.NAME, NULL_RESULT), - TestData.of(HasTagEvaluator.NAME), - TestData.of(HasVersionHistoryEvaluator.NAME, NULL_RESULT), - TestData.of(InCategoryEvaluator.NAME), - TestData.of(IsSubTypeEvaluator.NAME), - TestData.of(NoConditionEvaluator.NAME, NULL_RESULT), - TestData.of("fake-definition-name", NULL_RESULT), - TestData.of("", NULL_RESULT), - TestData.of(null, NULL_RESULT) - ); - } + private final RestModelMapper simpleConditionMapperMock = mock(RestRuleSimpleConditionModelMapper.class); @Test public void testFrom() { - for (TestData testData : getTestData()) - { - final ActionCondition actionCondition = createActionCondition(testData.conditionDefinitionName); + final ActionCondition actionCondition = createActionCondition(ComparePropertyValueEvaluator.NAME); + final SimpleCondition simpleConditionMock = mock(SimpleCondition.class); + given(simpleConditionMapperMock.toRestModel(actionCondition)).willReturn(simpleConditionMock); - // when - final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition, namespaceService); + //when + final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition, simpleConditionMapperMock); - assertThat(Objects.isNull(actualSimpleCondition)).isEqualTo(testData.isNullResult); - if (!testData.isNullResult) - { - assertThat(actualSimpleCondition.getField()).isNotEmpty(); - assertThat(actualSimpleCondition.getComparator()).isNotEmpty(); - assertThat(actualSimpleCondition.getParameter()).isNotEmpty(); - } - } - } - - @Test - public void testFromNullValue() - { - // when - final SimpleCondition actualSimpleCondition = SimpleCondition.from(null, namespaceService); - - assertThat(actualSimpleCondition).isNull(); - } - - @Test - public void testFromActionConditionWithoutDefinitionName() - { - final ActionCondition actionCondition = new ActionConditionImpl("fake-id", null, createParameterValues()); - - // when - final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition, namespaceService); - - assertThat(actualSimpleCondition).isNull(); - } - - @Test - public void testFromActionConditionWithoutParameterValues() - { - final ActionCondition actionCondition = new ActionConditionImpl("fake-id", "fake-def-name", null); - - // when - final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition, namespaceService); - - assertThat(actualSimpleCondition).isNull(); + then(simpleConditionMapperMock).should().toRestModel(actionCondition); + then(simpleConditionMapperMock).shouldHaveNoMoreInteractions(); + assertThat(actualSimpleCondition).isEqualTo(simpleConditionMock); } @Test public void testListOf() { - final List actionConditions = List.of( - createActionCondition(ComparePropertyValueEvaluator.NAME), - createActionCondition(CompareMimeTypeEvaluator.NAME) - ); + final List actionConditionsMock = mock(List.class); + final List simpleConditionsMock = mock(List.class); + given(simpleConditionMapperMock.toRestModels(actionConditionsMock)).willReturn(simpleConditionsMock); // when - final List actualSimpleConditions = SimpleCondition.listOf(actionConditions, namespaceService); + final List actualSimpleConditions = SimpleCondition.listOf(actionConditionsMock, simpleConditionMapperMock); - final List expectedSimpleConditions = List.of( - SimpleCondition.builder() - .field("content-property") - .comparator("operation") - .parameter("value") - .create(), - SimpleCondition.builder() - .field(SimpleCondition.PARAM_MIMETYPE) - .comparator(ComparePropertyValueOperation.EQUALS.toString().toLowerCase()) - .parameter("value") - .create() - ); + then(simpleConditionMapperMock).should().toRestModels(actionConditionsMock); + then(simpleConditionMapperMock).shouldHaveNoMoreInteractions(); assertThat(actualSimpleConditions) .isNotNull() - .containsExactlyElementsOf(expectedSimpleConditions); + .containsExactlyElementsOf(simpleConditionsMock); } @Test public void testListOfEmptyActionConditions() { // when - final List actualSimpleConditions = SimpleCondition.listOf(Collections.emptyList(), namespaceService); + final List actualSimpleConditions = SimpleCondition.listOf(Collections.emptyList(), simpleConditionMapperMock); assertThat(actualSimpleConditions).isNull(); } @@ -192,8 +102,9 @@ public class SimpleConditionTest public void testListOfNullActionConditions() { // when - final List actualSimpleConditions = SimpleCondition.listOf(null, namespaceService); + final List actualSimpleConditions = SimpleCondition.listOf(null, simpleConditionMapperMock); + then(simpleConditionMapperMock).shouldHaveNoInteractions(); assertThat(actualSimpleConditions).isNull(); } @@ -204,156 +115,47 @@ public class SimpleConditionTest actionConditions.add(null); // when - final List actualSimpleConditions = SimpleCondition.listOf(actionConditions, namespaceService); + final List actualSimpleConditions = SimpleCondition.listOf(actionConditions, simpleConditionMapperMock); + then(simpleConditionMapperMock).should().toRestModels(actionConditions); + then(simpleConditionMapperMock).shouldHaveNoMoreInteractions(); assertThat(actualSimpleConditions).isNotNull().isEmpty(); } @Test - public void testToServiceModel_withSizeContentProperty() + public void testToServiceModel_notInverted() { - final SimpleCondition simpleCondition = createSimpleCondition(ContentPropertyName.SIZE.toString().toLowerCase()); + final SimpleCondition simpleCondition = createSimpleCondition("field"); + final ActionCondition actionCondition = createActionCondition(ComparePropertyValueEvaluator.NAME); + given(simpleConditionMapperMock.toServiceModel(simpleCondition)).willReturn(actionCondition); // when - final ActionCondition actualActionCondition = simpleCondition.toServiceModel(NOT_INVERTED, nodes, namespaceService); + final ActionCondition actualActionCondition = simpleCondition.toServiceModel(!INVERTED, simpleConditionMapperMock); - final Map expectedParameterValues = new HashMap<>(); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, ContentPropertyName.SIZE.toString()); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.EQUALS.toString()); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, PARAMETER_DEFAULT); - ActionCondition expectedActionCondition = new ActionConditionImpl(null, ComparePropertyValueEvaluator.NAME, expectedParameterValues); - assertThat(actualActionCondition) - .isNotNull().usingRecursiveComparison().ignoringFields("id") - .isEqualTo(expectedActionCondition); - } - - @Test - public void testToServiceModel_withoutContentProperty() - { - final SimpleCondition simpleCondition = createSimpleCondition(ContentModel.PROP_DESCRIPTION.toPrefixString(namespaceService)); - - // when - final ActionCondition actualActionCondition = simpleCondition.toServiceModel(NOT_INVERTED, nodes, namespaceService); - - final Map expectedParameterValues = new HashMap<>(); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.PROP_DESCRIPTION); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.EQUALS.toString()); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, PARAMETER_DEFAULT); - final ActionCondition expectedActionCondition = new ActionConditionImpl(null, ComparePropertyValueEvaluator.NAME, expectedParameterValues); - assertThat(actualActionCondition) - .isNotNull().usingRecursiveComparison().ignoringFields("id", "parameterValues.property.prefix") - .isEqualTo(expectedActionCondition); - } - - @Test - public void testToServiceModel_compareMimetype() - { - final SimpleCondition simpleCondition = createSimpleCondition(SimpleCondition.PARAM_MIMETYPE); - - // when - final ActionCondition actualActionCondition = simpleCondition.toServiceModel(NOT_INVERTED, nodes, namespaceService); - - final Map expectedParameterValues = new HashMap<>(); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, PARAMETER_DEFAULT); - final ActionCondition expectedActionCondition = new ActionConditionImpl(null, CompareMimeTypeEvaluator.NAME, expectedParameterValues); - assertThat(actualActionCondition) - .isNotNull().usingRecursiveComparison().ignoringFields("id") - .isEqualTo(expectedActionCondition); - } - - @Test - public void testToServiceModel_hasAspect() - { - final QName audioAspect = QName.createQName(NamespaceService.AUDIO_MODEL_1_0_URI, NamespaceService.AUDIO_MODEL_PREFIX); - final SimpleCondition simpleCondition = createSimpleCondition(HasAspectEvaluator.PARAM_ASPECT, audioAspect.toPrefixString(namespaceService)); - - // when - final ActionCondition actualActionCondition = simpleCondition.toServiceModel(NOT_INVERTED, nodes, namespaceService); - - final Map expectedParameterValues = new HashMap<>(); - expectedParameterValues.put(HasAspectEvaluator.PARAM_ASPECT, audioAspect); - final ActionCondition expectedActionCondition = new ActionConditionImpl(null, HasAspectEvaluator.NAME, expectedParameterValues); - assertThat(actualActionCondition) - .isNotNull().usingRecursiveComparison().ignoringFields("id", "parameterValues.aspect.prefix") - .isEqualTo(expectedActionCondition); - } - - @Test - public void testToServiceModel_hasTag() - { - final String tag = "some tag"; - final SimpleCondition simpleCondition = createSimpleCondition(HasTagEvaluator.PARAM_TAG, tag); - - // when - final ActionCondition actualActionCondition = simpleCondition.toServiceModel(NOT_INVERTED, nodes, namespaceService); - - final Map expectedParameterValues = new HashMap<>(); - expectedParameterValues.put(HasTagEvaluator.PARAM_TAG, tag); - final ActionCondition expectedActionCondition = new ActionConditionImpl(null, HasTagEvaluator.NAME, expectedParameterValues); - assertThat(actualActionCondition) - .isNotNull().usingRecursiveComparison().ignoringFields("id") - .isEqualTo(expectedActionCondition); - } - - @Test - public void testToServiceModel_inCategory() - { - final SimpleCondition simpleCondition = createSimpleCondition(SimpleCondition.PARAM_CATEGORY); - final NodeRef defaultNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARAMETER_DEFAULT); - given(nodes.validateOrLookupNode(PARAMETER_DEFAULT, null)).willReturn(defaultNodeRef); - - // when - final ActionCondition actualActionCondition = simpleCondition.toServiceModel(NOT_INVERTED, nodes, namespaceService); - - final Map expectedParameterValues = new HashMap<>(); - expectedParameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, ContentModel.ASPECT_GEN_CLASSIFIABLE); - expectedParameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, defaultNodeRef); - final ActionCondition expectedActionCondition = new ActionConditionImpl(null, InCategoryEvaluator.NAME, expectedParameterValues); - assertThat(actualActionCondition) - .isNotNull().usingRecursiveComparison().ignoringFields("id") - .isEqualTo(expectedActionCondition); - } - - @Test - public void testToServiceModel_isSubType() - { - final SimpleCondition simpleCondition = createSimpleCondition(IsSubTypeEvaluator.PARAM_TYPE, ContentModel.TYPE_FOLDER.toPrefixString(namespaceService)); - - // when - final ActionCondition actualActionCondition = simpleCondition.toServiceModel(NOT_INVERTED, nodes, namespaceService); - - final Map expectedParameterValues = new HashMap<>(); - expectedParameterValues.put(IsSubTypeEvaluator.PARAM_TYPE, ContentModel.TYPE_FOLDER); - final ActionCondition expectedActionCondition = new ActionConditionImpl(null, IsSubTypeEvaluator.NAME, expectedParameterValues); - assertThat(actualActionCondition) - .isNotNull().usingRecursiveComparison().ignoringFields("id", "parameterValues.type.prefix") - .isEqualTo(expectedActionCondition); + assertThat(actualActionCondition).isEqualTo(actionCondition); } @Test public void testToServiceModel_inverted() { - final SimpleCondition simpleCondition = createSimpleCondition(ContentModel.PROP_DESCRIPTION.toPrefixString(namespaceService)); + final SimpleCondition simpleCondition = createSimpleCondition("field"); + final ActionCondition actionCondition = createActionCondition(ComparePropertyValueEvaluator.NAME); + given(simpleConditionMapperMock.toServiceModel(simpleCondition)).willReturn(actionCondition); // when - final ActionCondition actualActionCondition = simpleCondition.toServiceModel(!NOT_INVERTED, nodes, namespaceService); + final ActionCondition actualActionCondition = simpleCondition.toServiceModel(INVERTED, simpleConditionMapperMock); - final Map expectedParameterValues = new HashMap<>(); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.PROP_DESCRIPTION); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.EQUALS.toString()); - expectedParameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, PARAMETER_DEFAULT); - final ActionCondition expectedActionCondition = new ActionConditionImpl(null, ComparePropertyValueEvaluator.NAME, expectedParameterValues); - expectedActionCondition.setInvertCondition(!NOT_INVERTED); - assertThat(actualActionCondition) - .isNotNull().usingRecursiveComparison().ignoringFields("id", "parameterValues.property.prefix") - .isEqualTo(expectedActionCondition); + assertThat(actualActionCondition).isEqualTo(actionCondition); + } + + private static ActionCondition createActionCondition(final String actionDefinitionName) + { + return new ActionConditionImpl("fake-id", actionDefinitionName, Map.of(KEY, VALUE)); } private static SimpleCondition createSimpleCondition(final String field) { - return createSimpleCondition(field, PARAMETER_DEFAULT); + return createSimpleCondition(field, VALUE); } private static SimpleCondition createSimpleCondition(final String field, final String parameter) @@ -364,46 +166,4 @@ public class SimpleConditionTest .parameter(parameter) .create(); } - - private static ActionCondition createActionCondition(final String actionDefinitionName) - { - return new ActionConditionImpl("fake-id", actionDefinitionName, createParameterValues()); - } - - private static Map createParameterValues() { - final QName audioAspect = QName.createQName(NamespaceService.AUDIO_MODEL_1_0_URI, NamespaceService.AUDIO_MODEL_PREFIX); - final NodeRef defaultNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARAMETER_DEFAULT); - final Map parameterValues = new HashMap<>(); - parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, "content-property"); - parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, ContentModel.TYPE_CONTENT); - parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, "operation"); - parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, "value"); - parameterValues.put(HasAspectEvaluator.PARAM_ASPECT, audioAspect); - parameterValues.put(HasTagEvaluator.PARAM_TAG, "tag"); - parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, "category-aspect"); - parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, defaultNodeRef); - parameterValues.put(IsSubTypeEvaluator.PARAM_TYPE, ContentModel.TYPE_FOLDER); - - return parameterValues; - } - - private static class TestData - { - String conditionDefinitionName; - boolean isNullResult; - - public TestData(String conditionDefinitionName, boolean isNullResult) - { - this.conditionDefinitionName = conditionDefinitionName; - this.isNullResult = isNullResult; - } - - public static TestData of(String conditionDefinitionName) { - return new TestData(conditionDefinitionName, false); - } - - public static TestData of(String conditionDefinitionName, boolean isNullResult) { - return new TestData(conditionDefinitionName, isNullResult); - } - } -} \ No newline at end of file +}