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
new file mode 100644
index 0000000000..f33b862aa7
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/CompositeCondition.java
@@ -0,0 +1,230 @@
+/*
+ * #%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 java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.alfresco.service.Experimental;
+import org.alfresco.service.cmr.action.ActionCondition;
+import org.apache.commons.collections.CollectionUtils;
+
+@Experimental
+public class CompositeCondition
+{
+ private boolean inverted;
+ private ConditionOperator booleanMode = ConditionOperator.AND;
+ private List compositeConditions;
+ private List simpleConditions;
+
+ /**
+ * Converts Action conditions (service POJO) list to composite condition (REST model).
+ *
+ * @param actionConditions - list of {@link ActionCondition} service POJOs
+ * @return {@link CompositeCondition} REST model
+ */
+ public static CompositeCondition from(final List actionConditions)
+ {
+ if (actionConditions == null)
+ {
+ return null;
+ }
+
+ final CompositeCondition conditions = new CompositeCondition();
+ conditions.compositeConditions = new ArrayList<>();
+ // 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, inverted, ConditionOperator.AND))
+ // if composite condition present add to final list
+ .ifPresent(compositeCondition -> conditions.compositeConditions.add(compositeCondition)));
+
+ if (conditions.compositeConditions.isEmpty()) {
+ conditions.compositeConditions = null;
+ }
+
+ return conditions;
+ }
+
+ private static CompositeCondition ofActionConditions(final List actionConditions, final boolean inverted, final ConditionOperator conditionOperator)
+ {
+ if (actionConditions == null)
+ {
+ return null;
+ }
+
+ return ofSimpleConditions(SimpleCondition.listOf(actionConditions), inverted, conditionOperator);
+ }
+
+ /**
+ * Creates a composite condition instance of simple conditions.
+ *
+ * @param simpleConditions - list of {@link SimpleCondition}
+ * @param inverted - determines if condition should be inverted
+ * @param conditionOperator - determines the operation, see {@link ConditionOperator}
+ * @return {@link CompositeCondition}
+ */
+ public static CompositeCondition ofSimpleConditions(final List simpleConditions, final boolean inverted, final ConditionOperator conditionOperator)
+ {
+ return of(simpleConditions, null, inverted, conditionOperator);
+ }
+
+ private static CompositeCondition of(final List simpleConditions, final List compositeConditions,
+ final boolean inverted, final ConditionOperator conditionOperator)
+ {
+ if (CollectionUtils.isEmpty(simpleConditions) && CollectionUtils.isEmpty(compositeConditions))
+ {
+ return null;
+ }
+
+ return builder()
+ .inverted(inverted)
+ .booleanMode(conditionOperator)
+ .simpleConditions(simpleConditions)
+ .compositeConditions(compositeConditions)
+ .create();
+ }
+
+ public boolean isInverted()
+ {
+ return inverted;
+ }
+
+ public void setInverted(boolean inverted)
+ {
+ this.inverted = inverted;
+ }
+
+ public String getBooleanMode()
+ {
+ if (booleanMode == null)
+ {
+ return null;
+ }
+ return booleanMode.name().toLowerCase();
+ }
+
+ public void setBooleanMode(ConditionOperator booleanMode)
+ {
+ this.booleanMode = booleanMode;
+ }
+
+ public List getCompositeConditions()
+ {
+ return compositeConditions;
+ }
+
+ public void setCompositeConditions(List compositeConditions)
+ {
+ this.compositeConditions = compositeConditions;
+ }
+
+ public List getSimpleConditions()
+ {
+ return simpleConditions;
+ }
+
+ public void setSimpleConditions(List simpleConditions)
+ {
+ this.simpleConditions = simpleConditions;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "CompositeCondition{" + "inverted=" + inverted + ", booleanMode=" + booleanMode + ", compositeConditions=" + compositeConditions + ", simpleConditions="
+ + simpleConditions + '}';
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ CompositeCondition that = (CompositeCondition) o;
+ return inverted == that.inverted && booleanMode == that.booleanMode && Objects.equals(compositeConditions, that.compositeConditions) && Objects.equals(
+ simpleConditions, that.simpleConditions);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(inverted, booleanMode, compositeConditions, simpleConditions);
+ }
+
+ public static Builder builder()
+ {
+ return new Builder();
+ }
+
+ public static class Builder
+ {
+ private boolean inverted;
+ private ConditionOperator booleanMode = ConditionOperator.AND;
+ private List compositeConditions;
+ private List simpleConditions;
+
+ public Builder inverted(boolean inverted)
+ {
+ this.inverted = inverted;
+ return this;
+ }
+
+ public Builder booleanMode(ConditionOperator booleanMode)
+ {
+ this.booleanMode = booleanMode;
+ return this;
+ }
+
+ public Builder compositeConditions(List compositeConditions)
+ {
+ this.compositeConditions = compositeConditions;
+ return this;
+ }
+
+ public Builder simpleConditions(List simpleConditions)
+ {
+ this.simpleConditions = simpleConditions;
+ return this;
+ }
+
+ public CompositeCondition create()
+ {
+ final CompositeCondition condition = new CompositeCondition();
+ condition.setInverted(inverted);
+ condition.setBooleanMode(booleanMode);
+ condition.setCompositeConditions(compositeConditions);
+ condition.setSimpleConditions(simpleConditions);
+ return condition;
+ }
+ }
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/ConditionOperator.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/ConditionOperator.java
new file mode 100644
index 0000000000..a61d288339
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/ConditionOperator.java
@@ -0,0 +1,35 @@
+/*
+ * #%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 org.alfresco.service.Experimental;
+
+@Experimental
+public enum ConditionOperator
+{
+ AND, OR
+}
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 61b4b5bd8c..31782fad6a 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
@@ -49,6 +49,7 @@ public class Rule
private boolean shared;
private String errorScript;
private List triggers;
+ private CompositeCondition conditions;
private List actions;
/**
@@ -81,6 +82,7 @@ public class Rule
}
if (ruleModel.getAction() != null)
{
+ builder.conditions(CompositeCondition.from(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());
@@ -193,9 +195,13 @@ public class Rule
this.shared = shared;
}
- public List getTriggers()
+ public List getTriggers()
{
- return triggers;
+ if (triggers == null)
+ {
+ return null;
+ }
+ return triggers.stream().map(RuleTrigger::getValue).collect(Collectors.toList());
}
public void setTriggers(List triggers)
@@ -203,6 +209,16 @@ public class Rule
this.triggers = triggers;
}
+ public CompositeCondition getConditions()
+ {
+ return conditions;
+ }
+
+ public void setConditions(CompositeCondition conditions)
+ {
+ this.conditions = conditions;
+ }
+
public List getActions()
{
return actions;
@@ -217,7 +233,8 @@ public class Rule
public String toString()
{
return "Rule{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", description='" + description + '\'' + ", enabled=" + enabled + ", cascade=" + cascade
- + ", asynchronous=" + asynchronous + ", shared=" + shared + ", errorScript='" + errorScript + '\'' + ", triggers=" + triggers + ", actions=" + actions + '}';
+ + ", asynchronous=" + asynchronous + ", shared=" + shared + ", errorScript='" + errorScript + '\'' + ", triggers=" + triggers + ", conditions=" + conditions
+ + ", actions=" + actions + '}';
}
@Override
@@ -230,13 +247,13 @@ public class Rule
Rule rule = (Rule) o;
return enabled == rule.enabled && cascade == rule.cascade && asynchronous == rule.asynchronous && shared == rule.shared && Objects.equals(id, rule.id) && Objects.equals(
name, rule.name) && Objects.equals(description, rule.description) && Objects.equals(errorScript, rule.errorScript) && Objects.equals(triggers, rule.triggers)
- && Objects.equals(actions, rule.actions);
+ && Objects.equals(conditions, rule.conditions) && Objects.equals(actions, rule.actions);
}
@Override
public int hashCode()
{
- return Objects.hash(id, name, description, enabled, cascade, asynchronous, shared, errorScript, triggers, actions);
+ return Objects.hash(id, name, description, enabled, cascade, asynchronous, shared, errorScript, triggers, conditions, actions);
}
public static Builder builder()
@@ -256,6 +273,7 @@ public class Rule
private boolean shared;
private String errorScript;
private List triggers;
+ private CompositeCondition conditions;
private List actions;
public Builder id(String id)
@@ -312,6 +330,12 @@ public class Rule
return this;
}
+ public Builder conditions(CompositeCondition conditions)
+ {
+ this.conditions = conditions;
+ return this;
+ }
+
public Builder actions(List actions)
{
this.actions = actions;
@@ -330,6 +354,7 @@ public class Rule
rule.setShared(shared);
rule.setErrorScript(errorScript);
rule.setTriggers(triggers);
+ rule.setConditions(conditions);
rule.setActions(actions);
return rule;
}
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
new file mode 100644
index 0000000000..cdd26ddc2b
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/SimpleCondition.java
@@ -0,0 +1,277 @@
+/*
+ * #%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 java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+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.service.Experimental;
+import org.alfresco.service.cmr.action.ActionCondition;
+import org.apache.commons.collections.CollectionUtils;
+
+@Experimental
+public class SimpleCondition
+{
+ private static final String COMPARATOR_EQUALS = "equals";
+
+ private String field;
+ private String comparator;
+ private String parameter;
+
+ /**
+ * Converts list of service POJO action conditions to list of REST model simple conditions.
+ *
+ * @param actionConditions - list of {@link ActionCondition} service POJOs
+ * @return list of {@link SimpleCondition} REST models
+ */
+ public static List listOf(final List actionConditions)
+ {
+ if (CollectionUtils.isEmpty(actionConditions))
+ {
+ return null;
+ }
+
+ return actionConditions.stream()
+ .map(SimpleCondition::from)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Creates simple condition REST model instance from service POJO action condition.
+ *
+ * @param actionCondition - {@link ActionCondition} service POJO
+ * @return {@link SimpleCondition} REST model
+ */
+ public static SimpleCondition from(final ActionCondition actionCondition)
+ {
+ if (actionCondition == null || actionCondition.getActionConditionDefinitionName() == null || actionCondition.getParameterValues() == null)
+ {
+ return null;
+ }
+
+ switch (actionCondition.getActionConditionDefinitionName())
+ {
+ case ComparePropertyValueEvaluator.NAME:
+ return createComparePropertyValueCondition(actionCondition);
+ case CompareMimeTypeEvaluator.NAME:
+ return createCompareMimeTypeCondition(actionCondition);
+ case HasAspectEvaluator.NAME:
+ return createHasAspectCondition(actionCondition);
+ case HasChildEvaluator.NAME:
+ return createHasChildCondition(actionCondition);
+ case HasTagEvaluator.NAME:
+ return createHasTagCondition(actionCondition);
+ case HasVersionHistoryEvaluator.NAME:
+ return createHasVersionHistoryCondition(actionCondition);
+ case InCategoryEvaluator.NAME:
+ return createInCategoryCondition(actionCondition);
+ case IsSubTypeEvaluator.NAME:
+ return createIsSubtypeCondition(actionCondition);
+ case NoConditionEvaluator.NAME:
+ default:
+ return null;
+ }
+ }
+
+ public String getField()
+ {
+ return field;
+ }
+
+ public void setField(String field)
+ {
+ this.field = field;
+ }
+
+ public String getComparator()
+ {
+ return comparator;
+ }
+
+ public void setComparator(String comparator)
+ {
+ this.comparator = comparator;
+ }
+
+ public String getParameter()
+ {
+ return parameter;
+ }
+
+ public void setParameter(String parameter)
+ {
+ this.parameter = parameter;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "SimpleCondition{" + "field='" + field + '\'' + ", comparator='" + comparator + '\'' + ", parameter='" + parameter + '\'' + '}';
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ SimpleCondition that = (SimpleCondition) o;
+ return Objects.equals(field, that.field) && Objects.equals(comparator, that.comparator) && Objects.equals(parameter, that.parameter);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(field, comparator, parameter);
+ }
+
+ private static SimpleCondition createComparePropertyValueCondition(final ActionCondition actionCondition) {
+ 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(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY).toString().toLowerCase());
+ }
+ 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(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY).toString().toLowerCase())
+ .comparator(COMPARATOR_EQUALS)
+ .parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
+ .create();
+ }
+
+ private static SimpleCondition createHasAspectCondition(final ActionCondition actionCondition) {
+ return builder()
+ .field(HasAspectEvaluator.PARAM_ASPECT)
+ .comparator(COMPARATOR_EQUALS)
+ .parameter(actionCondition.getParameterValues().get(HasAspectEvaluator.PARAM_ASPECT).toString())
+ .create();
+ }
+
+ private static SimpleCondition createHasChildCondition(final ActionCondition actionCondition) {
+ final SimpleCondition.Builder builder = builder();
+ if (actionCondition.getParameterValues().get(HasChildEvaluator.PARAM_ASSOC_TYPE) != null)
+ {
+ builder.field(actionCondition.getParameterValues().get(HasChildEvaluator.PARAM_ASSOC_TYPE).toString().toLowerCase());
+ } else {
+ builder.field(actionCondition.getParameterValues().get(HasChildEvaluator.PARAM_ASSOC_NAME).toString().toLowerCase());
+ }
+ return builder
+ .comparator(COMPARATOR_EQUALS)
+ .parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
+ .create();
+ }
+
+ private static SimpleCondition createHasTagCondition(final ActionCondition actionCondition) {
+ return builder()
+ .field(HasTagEvaluator.PARAM_TAG)
+ .comparator(COMPARATOR_EQUALS)
+ .parameter(actionCondition.getParameterValues().get(HasTagEvaluator.PARAM_TAG).toString())
+ .create();
+ }
+
+ private static SimpleCondition createHasVersionHistoryCondition(final ActionCondition actionCondition) {
+ return builder()
+ .field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY).toString().toLowerCase())
+ .comparator(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_OPERATION).toString().toLowerCase())
+ .parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
+ .create();
+ }
+
+ private static SimpleCondition createInCategoryCondition(final ActionCondition actionCondition) {
+ return builder()
+ .field(actionCondition.getParameterValues().get(InCategoryEvaluator.PARAM_CATEGORY_ASPECT).toString().toLowerCase())
+ .comparator(COMPARATOR_EQUALS)
+ .parameter(actionCondition.getParameterValues().get(InCategoryEvaluator.PARAM_CATEGORY_VALUE).toString())
+ .create();
+ }
+
+ private static SimpleCondition createIsSubtypeCondition(final ActionCondition actionCondition) {
+ return builder()
+ .field(IsSubTypeEvaluator.PARAM_TYPE)
+ .comparator(COMPARATOR_EQUALS)
+ .parameter(actionCondition.getParameterValues().get(IsSubTypeEvaluator.PARAM_TYPE).toString())
+ .create();
+ }
+
+ public static Builder builder()
+ {
+ return new Builder();
+ }
+
+ public static class Builder
+ {
+ private String field;
+ private String comparator;
+ private String parameter;
+
+ public Builder field(String field)
+ {
+ this.field = field;
+ return this;
+ }
+
+ public Builder comparator(String comparator)
+ {
+ this.comparator = comparator;
+ return this;
+ }
+
+ public Builder parameter(String parameter)
+ {
+ this.parameter = parameter;
+ return this;
+ }
+
+ public SimpleCondition create() {
+ final SimpleCondition condition = new SimpleCondition();
+ condition.setField(field);
+ condition.setComparator(comparator);
+ condition.setParameter(parameter);
+ return condition;
+ }
+ }
+}
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 3b199328d4..cccc62de9b 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
@@ -28,7 +28,9 @@ package org.alfresco.rest.api;
import org.alfresco.rest.api.impl.RulesImplTest;
import org.alfresco.rest.api.model.rules.ActionTest;
+import org.alfresco.rest.api.model.rules.CompositeConditionTest;
import org.alfresco.rest.api.model.rules.RuleTest;
+import org.alfresco.rest.api.model.rules.SimpleConditionTest;
import org.alfresco.rest.api.nodes.NodeRulesRelationTest;
import org.alfresco.service.Experimental;
import org.junit.runner.RunWith;
@@ -40,7 +42,9 @@ import org.junit.runners.Suite;
NodeRulesRelationTest.class,
RulesImplTest.class,
RuleTest.class,
- ActionTest.class
+ ActionTest.class,
+ SimpleConditionTest.class,
+ CompositeConditionTest.class
})
public class RulesUnitTests
{
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java
index db64a7d9f1..a2fd5308eb 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java
@@ -49,6 +49,7 @@ import java.util.List;
import junit.framework.TestCase;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.rest.api.Nodes;
+import org.alfresco.rest.api.model.rules.CompositeCondition;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
@@ -463,10 +464,13 @@ public class RulesImplTest extends TestCase
then(ruleServiceMock).should().saveRule(folderNodeRef, serviceRuleBody);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
+
Rule expected = Rule.builder().id(RULE_ID)
.enabled(true)
.shared(true)
- .triggers(emptyList()).create();
+ .triggers(emptyList())
+ .conditions(CompositeCondition.builder().inverted(false).create())
+ .create();
assertThat(updatedRule).isEqualTo(expected);
}
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
new file mode 100644
index 0000000000..427c208848
--- /dev/null
+++ b/remote-api/src/test/java/org/alfresco/rest/api/model/rules/CompositeConditionTest.java
@@ -0,0 +1,180 @@
+/*
+ * #%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 java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.repo.action.ActionConditionImpl;
+import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
+import org.alfresco.service.Experimental;
+import org.alfresco.service.cmr.action.ActionCondition;
+import org.junit.Test;
+
+@Experimental
+public class CompositeConditionTest
+{
+
+ @Test
+ public void testFrom()
+ {
+ final List actionConditions = List.of(
+ createActionCondition("value1"),
+ createActionCondition("value2", true),
+ createActionCondition("value3")
+ );
+ final CompositeCondition expectedCompositeCondition = createCompositeCondition(List.of(
+ createCompositeCondition(false, List.of(
+ createSimpleCondition("value1"),
+ createSimpleCondition("value3")
+ )),
+ createCompositeCondition(true, List.of(
+ createSimpleCondition("value2")
+ ))
+ ));
+
+ // when
+ final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions);
+
+ assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition);
+ }
+
+ @Test
+ public void testFromEmptyList()
+ {
+ final List actionConditions = Collections.emptyList();
+ final CompositeCondition expectedCompositeCondition = CompositeCondition.builder().create();
+
+ // when
+ final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions);
+
+ assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition);
+ }
+
+ @Test
+ public void testFromNullValue()
+ {
+ // when
+ final CompositeCondition actualCompositeCondition = CompositeCondition.from(null);
+
+ assertThat(actualCompositeCondition).isNull();
+ }
+
+ @Test
+ public void testFromListContainingNull()
+ {
+ final List actionConditions = new ArrayList<>();
+ actionConditions.add(null);
+ final CompositeCondition expectedCompositeCondition = CompositeCondition.builder().create();
+
+ // when
+ final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions);
+
+ assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition);
+ }
+
+ @Test
+ public void testOfSimpleConditions()
+ {
+ final List simpleConditions = List.of(SimpleCondition.builder().field("field").comparator("comparator").parameter("param").create());
+ final boolean inverted = true;
+ final ConditionOperator conditionOperator = ConditionOperator.OR;
+ final CompositeCondition expectedCondition = createCompositeCondition(inverted, conditionOperator, null, simpleConditions);
+
+ // when
+ final CompositeCondition actualCompositeCondition = CompositeCondition.ofSimpleConditions(simpleConditions, inverted, conditionOperator);
+
+ assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCondition);
+ }
+
+ @Test
+ public void testOfEmptySimpleConditions()
+ {
+ // when
+ final CompositeCondition actualCompositeCondition = CompositeCondition.ofSimpleConditions(Collections.emptyList(), false, ConditionOperator.AND);
+
+ assertThat(actualCompositeCondition).isNull();
+ }
+
+ @Test
+ public void testOfNullSimpleConditions()
+ {
+ // when
+ final CompositeCondition actualCompositeCondition = CompositeCondition.ofSimpleConditions(null, false, ConditionOperator.AND);
+
+ assertThat(actualCompositeCondition).isNull();
+ }
+
+ private static ActionCondition createActionCondition(final String value)
+ {
+ return createActionCondition(value, false);
+ }
+
+ private static ActionCondition createActionCondition(final String value, final boolean inverted)
+ {
+ final ActionCondition actionCondition = new ActionConditionImpl("fake-id", ComparePropertyValueEvaluator.NAME);
+ actionCondition.setInvertCondition(inverted);
+ final Map parameterValues = new HashMap<>();
+ parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, "content-property");
+ parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, "operation");
+ parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, value);
+ actionCondition.setParameterValues(parameterValues);
+ return actionCondition;
+ }
+
+ private static SimpleCondition createSimpleCondition(final String value) {
+ return SimpleCondition.builder()
+ .field("content-property")
+ .comparator("operation")
+ .parameter(value)
+ .create();
+ }
+
+ private static CompositeCondition createCompositeCondition(final List compositeConditions) {
+ return createCompositeCondition(false, ConditionOperator.AND, compositeConditions, null);
+ }
+
+ private static CompositeCondition createCompositeCondition(final boolean inverted, final List simpleConditions) {
+ return createCompositeCondition(inverted, ConditionOperator.AND, null, simpleConditions);
+ }
+
+ private static CompositeCondition createCompositeCondition(final boolean inverted, final ConditionOperator conditionOperator,
+ final List compositeConditions, final List simpleConditions) {
+ return CompositeCondition.builder()
+ .inverted(inverted)
+ .booleanMode(conditionOperator)
+ .compositeConditions(compositeConditions)
+ .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 98e3c8c5f2..a21cfe575f 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
@@ -28,6 +28,7 @@ package org.alfresco.rest.api.model.rules;
import static org.assertj.core.api.Assertions.assertThat;
+import java.util.Collections;
import java.util.List;
import org.alfresco.repo.action.ActionConditionImpl;
@@ -110,6 +111,7 @@ public class RuleTest
.shared(RULE_SHARED)
.triggers(List.of(RuleTrigger.INBOUND, RuleTrigger.UPDATE))
.errorScript(ERROR_SCRIPT)
+ .conditions(CompositeCondition.from(Collections.emptyList()))
.create();
}
}
\ 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
new file mode 100644
index 0000000000..9c0de39112
--- /dev/null
+++ b/remote-api/src/test/java/org/alfresco/rest/api/model/rules/SimpleConditionTest.java
@@ -0,0 +1,213 @@
+/*
+ * #%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 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.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.service.Experimental;
+import org.alfresco.service.cmr.action.ActionCondition;
+import org.junit.Test;
+
+@Experimental
+public class SimpleConditionTest
+{
+
+ private static List getTestData() {
+ return List.of(
+ TestData.of(ComparePropertyValueEvaluator.NAME),
+ TestData.of(CompareMimeTypeEvaluator.NAME),
+ TestData.of(HasAspectEvaluator.NAME),
+ TestData.of(HasChildEvaluator.NAME),
+ TestData.of(HasTagEvaluator.NAME),
+ TestData.of(HasVersionHistoryEvaluator.NAME),
+ TestData.of(InCategoryEvaluator.NAME),
+ TestData.of(IsSubTypeEvaluator.NAME),
+ TestData.of(NoConditionEvaluator.NAME, true),
+ TestData.of("fake-definition-name", true),
+ TestData.of("", true),
+ TestData.of(null, true)
+ );
+ }
+
+ @Test
+ public void testFrom()
+ {
+ for (TestData testData : getTestData())
+ {
+ final ActionCondition actionCondition = createActionCondition(testData.actionDefinitionName);
+
+ // when
+ final SimpleCondition actualSimpleCondition = SimpleCondition.from(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 testFromNullValue()
+ {
+ // when
+ final SimpleCondition actualSimpleCondition = SimpleCondition.from(null);
+
+ assertThat(actualSimpleCondition).isNull();
+ }
+
+ @Test
+ public void testFromActionConditionWithoutDefinitionName()
+ {
+ final ActionCondition actionCondition = new ActionConditionImpl("fake-id", null, createParameterValues());
+
+ // when
+ final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition);
+
+ 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);
+
+ assertThat(actualSimpleCondition).isNull();
+ }
+
+ @Test
+ public void testListOf()
+ {
+ final List actionConditions = List.of(
+ createActionCondition(ComparePropertyValueEvaluator.NAME),
+ createActionCondition(CompareMimeTypeEvaluator.NAME)
+ );
+ final List expectedSimpleConditions = List.of(
+ SimpleCondition.builder().field("content-property").comparator("operation").parameter("value").create(),
+ SimpleCondition.builder().field("property").comparator("equals").parameter("value").create()
+ );
+
+ // when
+ final List actualSimpleConditions = SimpleCondition.listOf(actionConditions);
+
+ assertThat(actualSimpleConditions)
+ .isNotNull()
+ .containsExactlyElementsOf(expectedSimpleConditions);
+ }
+
+ @Test
+ public void testListOfEmptyActionConditions()
+ {
+ final List actualSimpleConditions = SimpleCondition.listOf(Collections.emptyList());
+
+ assertThat(actualSimpleConditions).isNull();
+ }
+
+ @Test
+ public void testListOfNullActionConditions()
+ {
+ final List actualSimpleConditions = SimpleCondition.listOf(null);
+
+ assertThat(actualSimpleConditions).isNull();
+ }
+
+ @Test
+ public void testListOfActionConditionsContainingNull()
+ {
+ final List actionConditions = new ArrayList<>();
+ actionConditions.add(null);
+
+ final List actualSimpleConditions = SimpleCondition.listOf(actionConditions);
+
+ assertThat(actualSimpleConditions).isNotNull().isEmpty();
+ }
+
+ private static ActionCondition createActionCondition(final String actionDefinitionName)
+ {
+ return new ActionConditionImpl("fake-id", actionDefinitionName, createParameterValues());
+ }
+
+ private static Map createParameterValues() {
+ final Map parameterValues = new HashMap<>();
+ parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, "content-property");
+ parameterValues.put(HasChildEvaluator.PARAM_ASSOC_TYPE, "assoc-type");
+ parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, "property");
+ parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, "operation");
+ parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, "value");
+ parameterValues.put(HasAspectEvaluator.PARAM_ASPECT, "aspect");
+ parameterValues.put(HasChildEvaluator.PARAM_ASSOC_NAME, "assoc-name");
+ parameterValues.put(HasTagEvaluator.PARAM_TAG, "tag");
+ parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, "category-aspect");
+ parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, "category-value");
+ parameterValues.put(IsSubTypeEvaluator.PARAM_TYPE, "type");
+
+ return parameterValues;
+ }
+
+ private static class TestData
+ {
+ String actionDefinitionName;
+ boolean isNullResult;
+
+ public TestData(String actionDefinitionName, boolean isNullResult)
+ {
+ this.actionDefinitionName = actionDefinitionName;
+ this.isNullResult = isNullResult;
+ }
+
+ public static TestData of(String actionDefinitionName) {
+ return new TestData(actionDefinitionName, false);
+ }
+
+ public static TestData of(String actionDefinitionName, boolean isNullResult) {
+ return new TestData(actionDefinitionName, isNullResult);
+ }
+ }
+}
\ No newline at end of file
diff --git a/repository/src/test/java/org/alfresco/repo/rule/RuleServiceImplUnitTest.java b/repository/src/test/java/org/alfresco/repo/rule/RuleServiceImplUnitTest.java
index 0c660bc4af..4403ac8e01 100644
--- a/repository/src/test/java/org/alfresco/repo/rule/RuleServiceImplUnitTest.java
+++ b/repository/src/test/java/org/alfresco/repo/rule/RuleServiceImplUnitTest.java
@@ -31,10 +31,12 @@ import static org.alfresco.repo.rule.RuleModel.ASSOC_RULE_FOLDER;
import static org.alfresco.repo.rule.RuleModel.TYPE_RULE;
import static org.alfresco.service.cmr.security.AccessStatus.ALLOWED;
import static org.alfresco.service.cmr.security.AccessStatus.DENIED;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
@@ -44,6 +46,7 @@ import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.openMocks;
import java.io.Serializable;
+import java.util.Collections;
import java.util.List;
import org.alfresco.repo.action.RuntimeActionService;
@@ -187,4 +190,170 @@ public class RuleServiceImplUnitTest
assertThatExceptionOfType(RuleServiceException.class).isThrownBy(() -> ruleService.saveRule(FOLDER_NODE, mockRule));
}
+
+ @Test
+ public void testGetRuleSetNode()
+ {
+ given(runtimeNodeService.getChildAssocs(any(), any(), any())).willReturn(List.of(createAssociation(FOLDER_NODE, RULE_SET_NODE)));
+
+ // when
+ final NodeRef actualNode = ruleService.getRuleSetNode(FOLDER_NODE);
+
+ then(runtimeNodeService).should().getChildAssocs(FOLDER_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(actualNode).isNotNull();
+ }
+
+ @Test
+ public void testGetRuleSetNode_emptyAssociation()
+ {
+ given(runtimeNodeService.getChildAssocs(any(), any(), any())).willReturn(Collections.emptyList());
+
+ // when
+ final NodeRef actualNode = ruleService.getRuleSetNode(FOLDER_NODE);
+
+ then(runtimeNodeService).should().getChildAssocs(FOLDER_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(actualNode).isNull();
+ }
+
+ @Test
+ public void testGetRuleSetNode_notPrimaryAssociation()
+ {
+ given(runtimeNodeService.getChildAssocs(any(), any(), any())).willReturn(List.of(createAssociation(FOLDER_NODE, RULE_SET_NODE, false)));
+
+ // when
+ final NodeRef actualNode = ruleService.getRuleSetNode(FOLDER_NODE);
+
+ then(runtimeNodeService).should().getChildAssocs(FOLDER_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(actualNode).isNotNull();
+ }
+
+ @Test
+ public void testIsRuleSetAssociatedWithFolder()
+ {
+ given(runtimeNodeService.getParentAssocs(any(), any(), any())).willReturn(List.of(createAssociation(FOLDER_NODE, RULE_SET_NODE)));
+
+ // when
+ boolean associated = ruleService.isRuleSetAssociatedWithFolder(RULE_SET_NODE, FOLDER_NODE);
+
+ then(runtimeNodeService).should().getParentAssocs(RULE_SET_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(associated).isTrue();
+ }
+
+ @Test
+ public void testIsRuleSetAssociatedWithFolder_emptyAssociation()
+ {
+ given(runtimeNodeService.getParentAssocs(any(), any(), any())).willReturn(Collections.emptyList());
+
+ // when
+ boolean associated = ruleService.isRuleSetAssociatedWithFolder(RULE_SET_NODE, FOLDER_NODE);
+
+ then(runtimeNodeService).should().getParentAssocs(RULE_SET_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(associated).isFalse();
+ }
+
+ @Test
+ public void testIsRuleSetAssociatedWithFolder_improperAssociation()
+ {
+ final NodeRef fakeFolderNode = new NodeRef("folder://node/fake");
+ given(runtimeNodeService.getParentAssocs(any(), any(), any())).willReturn(List.of(createAssociation(fakeFolderNode, RULE_SET_NODE)));
+
+ // when
+ boolean associated = ruleService.isRuleSetAssociatedWithFolder(RULE_SET_NODE, FOLDER_NODE);
+
+ then(runtimeNodeService).should().getParentAssocs(RULE_SET_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(associated).isFalse();
+ }
+
+ @Test
+ public void testIsRuleAssociatedWithRuleSet()
+ {
+ given(runtimeNodeService.getParentAssocs(any())).willReturn(List.of(createAssociation(RULE_SET_NODE, RULE_NODE)));
+
+ // when
+ boolean associated = ruleService.isRuleAssociatedWithRuleSet(RULE_NODE, RULE_SET_NODE);
+
+ then(runtimeNodeService).should().getParentAssocs(RULE_NODE);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(associated).isTrue();
+ }
+
+ @Test
+ public void testIsRuleAssociatedWithRuleSet_emptyAssociation()
+ {
+ given(runtimeNodeService.getParentAssocs(any())).willReturn(Collections.emptyList());
+
+ // when
+ boolean associated = ruleService.isRuleAssociatedWithRuleSet(RULE_NODE, RULE_SET_NODE);
+
+ then(runtimeNodeService).should().getParentAssocs(RULE_NODE);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(associated).isFalse();
+ }
+
+ @Test
+ public void testIsRuleAssociatedWithRuleSet_improperAssociation()
+ {
+ final NodeRef fakeRuleSetNode = new NodeRef("rule://set/node/fake");
+ given(runtimeNodeService.getParentAssocs(any())).willReturn(List.of(createAssociation(fakeRuleSetNode, RULE_NODE)));
+
+ // when
+ boolean associated = ruleService.isRuleAssociatedWithRuleSet(RULE_NODE, RULE_SET_NODE);
+
+ then(runtimeNodeService).should().getParentAssocs(RULE_NODE);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(associated).isFalse();
+ }
+
+ @Test
+ public void testIsRuleSetShared()
+ {
+ given(runtimeNodeService.getParentAssocs(any())).willReturn(List.of(createAssociation(FOLDER_NODE, RULE_SET_NODE, false)));
+
+ // when
+ boolean shared = ruleService.isRuleSetShared(RULE_SET_NODE);
+
+ then(runtimeNodeService).should().getParentAssocs(RULE_SET_NODE);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(shared).isTrue();
+ }
+
+ @Test
+ public void testIsRuleSetShared_notShared()
+ {
+ given(runtimeNodeService.getParentAssocs(any())).willReturn(List.of(createAssociation(FOLDER_NODE, RULE_SET_NODE)));
+
+ // when
+ boolean shared = ruleService.isRuleSetShared(RULE_SET_NODE);
+
+ then(runtimeNodeService).should().getParentAssocs(RULE_SET_NODE);
+ then(runtimeNodeService).shouldHaveNoMoreInteractions();
+ then(nodeService).shouldHaveNoInteractions();
+ assertThat(shared).isFalse();
+ }
+
+ private static ChildAssociationRef createAssociation(final NodeRef parentRef, final NodeRef childRef)
+ {
+ return createAssociation(parentRef, childRef, true);
+ }
+
+ private static ChildAssociationRef createAssociation(final NodeRef parentRef, final NodeRef childRef, final boolean isPrimary)
+ {
+ return new ChildAssociationRef(null, parentRef, null, childRef, isPrimary, 1);
+ }
}