mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
ACS-3489 Use specified rule set. (#1373)
* ACS-3280 Get inherited rule sets. [tas] This needs to work the exact same way as get inherited rules. * ACS-3280 Replace LinkedList with ArrayList. * ACS-3280 Don't return duplicated rule sets when there are links. * ACS-3489 E2E test for getting rules with inheritance. * ACS-3489 Inherited rule sets are also associated with folders. * ACS-3489 Fix test to contain expected values. * ACS-3489 Ensure only rules from specified rule set are returned. Add E2E test case for inherited links and fix unit tests. * ACS-3489 Fix audit reference in RuleService.
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.rules;
|
||||
|
||||
import static org.alfresco.rest.rules.RulesTestsUtils.createRuleModelWithModifiedValues;
|
||||
import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.alfresco.rest.RestTest;
|
||||
import org.alfresco.rest.model.RestRuleModel;
|
||||
import org.alfresco.rest.model.RestRuleModelsCollection;
|
||||
import org.alfresco.rest.model.RestRuleSetLinkModel;
|
||||
import org.alfresco.rest.model.RestRuleSetModel;
|
||||
import org.alfresco.rest.model.RestRuleSetModelsCollection;
|
||||
import org.alfresco.utility.model.FolderModel;
|
||||
import org.alfresco.utility.model.SiteModel;
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests for GET /nodes/{nodeId}/rule-sets/{ruleSetId}/rules with rule inheritance.
|
||||
*/
|
||||
@Test(groups = {TestGroup.RULES})
|
||||
public class GetInheritedRulesTests extends RestTest
|
||||
{
|
||||
private UserModel user;
|
||||
private SiteModel site;
|
||||
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void dataPreparation()
|
||||
{
|
||||
STEP("Create a user and site");
|
||||
user = dataUser.createRandomTestUser();
|
||||
site = dataSite.usingUser(user).createPublicRandomSite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check we can get all the rules for the folder by providing the different rule set ids.
|
||||
*/
|
||||
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
|
||||
public void getInheritedRules()
|
||||
{
|
||||
STEP("Create a parent and child folder, each with inheriting rules");
|
||||
FolderModel parent = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||
FolderModel child = dataContent.usingUser(user).usingResource(parent).createFolder();
|
||||
RestRuleModel parentRule = createRuleModelWithModifiedValues();
|
||||
parentRule = restClient.authenticateUser(user).withCoreAPI().usingNode(parent).usingDefaultRuleSet().createSingleRule(parentRule);
|
||||
RestRuleModel childRule = createRuleModelWithModifiedValues();
|
||||
childRule = restClient.authenticateUser(user).withCoreAPI().usingNode(child).usingDefaultRuleSet().createSingleRule(childRule);
|
||||
|
||||
STEP("Get the rules in the default rule set for the child folder");
|
||||
RestRuleModelsCollection rules = restClient.authenticateUser(user).withCoreAPI().usingNode(child).usingDefaultRuleSet().getListOfRules();
|
||||
rules.assertThat().entriesListContains("id", childRule.getId())
|
||||
.and().entriesListCountIs(1);
|
||||
|
||||
STEP("Get the rules in the inherited rule set for the child folder");
|
||||
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI().usingNode(child).include("inclusionType").getListOfRuleSets();
|
||||
String inheritedRuleSetId = ruleSets.getEntries().stream()
|
||||
.filter(ruleSet -> ruleSet.onModel().getInclusionType().equals("inherited"))
|
||||
.findFirst().get().onModel().getId();
|
||||
RestRuleModelsCollection inheritedRules = restClient.authenticateUser(user).withCoreAPI().usingNode(child).usingRuleSet(inheritedRuleSetId).getListOfRules();
|
||||
inheritedRules.assertThat().entriesListContains("id", parentRule.getId())
|
||||
.and().entriesListCountIs(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that we only get each rule once with linking and inheritance, and the order is correct.
|
||||
* <p>
|
||||
* The folder structure for this test is as follows:
|
||||
* <pre>
|
||||
* A --[links]-> DRuleSet
|
||||
* +-B --[owns]-> BRuleSet
|
||||
* +-C --[owns]-> CRuleSet
|
||||
* +-D --[owns]--> DRuleSet
|
||||
* </pre>
|
||||
*/
|
||||
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
|
||||
public void rulesReturnedAreUnique()
|
||||
{
|
||||
STEP("Create four folders with rules");
|
||||
FolderModel folderA = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||
FolderModel folderB = dataContent.usingUser(user).usingResource(folderA).createFolder();
|
||||
FolderModel folderC = dataContent.usingUser(user).usingResource(folderB).createFolder();
|
||||
FolderModel folderD = dataContent.usingUser(user).usingResource(folderC).createFolder();
|
||||
RestRuleModel ruleB = restClient.authenticateUser(user).withCoreAPI().usingNode(folderB).usingDefaultRuleSet().createSingleRule(createRuleModelWithModifiedValues());
|
||||
RestRuleModel ruleC = restClient.authenticateUser(user).withCoreAPI().usingNode(folderC).usingDefaultRuleSet().createSingleRule(createRuleModelWithModifiedValues());
|
||||
RestRuleModel ruleD = restClient.authenticateUser(user).withCoreAPI().usingNode(folderD).usingDefaultRuleSet().createSingleRule(createRuleModelWithModifiedValues());
|
||||
STEP("Link folderA to ruleSetD");
|
||||
RestRuleSetLinkModel linkModel = new RestRuleSetLinkModel();
|
||||
linkModel.setId(folderD.getNodeRef());
|
||||
restClient.authenticateUser(user).withCoreAPI().usingNode(folderA).createRuleLink(linkModel);
|
||||
|
||||
STEP("Get the rule sets for the folderD");
|
||||
List<RestRuleSetModel> ruleSets = restClient.authenticateUser(user).withCoreAPI().usingNode(folderD).getListOfRuleSets().getEntries();
|
||||
|
||||
STEP("Check the rules for each rule set are as expected");
|
||||
List<RestRuleModel> expectedRuleIds = List.of(ruleD, ruleB, ruleC);
|
||||
IntStream.range(0, 2).forEach(index -> {
|
||||
String ruleSetId = ruleSets.get(index).onModel().getId();
|
||||
List<RestRuleModel> rules = restClient.authenticateUser(user)
|
||||
.withCoreAPI()
|
||||
.usingNode(folderD)
|
||||
.usingRuleSet(ruleSetId)
|
||||
.getListOfRules()
|
||||
.getEntries()
|
||||
.stream()
|
||||
.map(RestRuleModel::onModel)
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(rules, List.of(expectedRuleIds.get(index)), "Unexpected rules found for rule set " + ruleSetId);
|
||||
});
|
||||
assertEquals(ruleSets.size(), 3, "Expected three unique rule sets to be returned but got " + ruleSets);
|
||||
}
|
||||
}
|
@@ -63,9 +63,10 @@ public class RulesImpl implements Rules
|
||||
final Paging paging)
|
||||
{
|
||||
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, false);
|
||||
validator.validateRuleSetNode(ruleSetId, folderNodeRef);
|
||||
NodeRef ruleSetNode = validator.validateRuleSetNode(ruleSetId, folderNodeRef);
|
||||
NodeRef owningFolder = ruleService.getOwningNodeRef(ruleSetNode);
|
||||
|
||||
final List<Rule> rules = ruleService.getRules(folderNodeRef).stream()
|
||||
final List<Rule> rules = ruleService.getRules(owningFolder, false).stream()
|
||||
.map(ruleModel -> loadRuleAndConvertActionParams(ruleModel, includes))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
@@ -115,7 +115,8 @@ public class RulesImplTest extends TestCase
|
||||
given(nodeValidatorMock.validateRuleNode(any(), any())).willReturn(RULE_NODE_REF);
|
||||
|
||||
given(ruleServiceMock.getRule(RULE_NODE_REF)).willReturn(ruleModel);
|
||||
given(ruleServiceMock.getRules(FOLDER_NODE_REF)).willReturn(List.of(ruleModel));
|
||||
given(ruleServiceMock.getRules(FOLDER_NODE_REF, false)).willReturn(List.of(ruleModel));
|
||||
given(ruleServiceMock.getOwningNodeRef(RULE_SET_NODE_REF)).willReturn(FOLDER_NODE_REF);
|
||||
|
||||
given(ruleLoaderMock.loadRule(ruleModel, INCLUDE)).willReturn(ruleMock);
|
||||
|
||||
@@ -126,13 +127,15 @@ public class RulesImplTest extends TestCase
|
||||
public void testGetRules()
|
||||
{
|
||||
given(ruleLoaderMock.loadRule(ruleModel, emptyList())).willReturn(ruleMock);
|
||||
|
||||
// when
|
||||
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
|
||||
|
||||
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
|
||||
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF);
|
||||
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF);
|
||||
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
|
||||
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
|
||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleLoaderMock).should().loadRule(ruleModel, emptyList());
|
||||
then(ruleLoaderMock).shouldHaveNoMoreInteractions();
|
||||
@@ -148,12 +151,13 @@ public class RulesImplTest extends TestCase
|
||||
@Test
|
||||
public void testGetRules_emptyResult()
|
||||
{
|
||||
given(ruleServiceMock.getRules(any())).willReturn(emptyList());
|
||||
given(ruleServiceMock.getRules(FOLDER_NODE_REF, false)).willReturn(emptyList());
|
||||
|
||||
// when
|
||||
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
|
||||
|
||||
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF);
|
||||
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
|
||||
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
|
||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||
assertThat(rulesPage)
|
||||
.isNotNull()
|
||||
|
@@ -26,6 +26,7 @@
|
||||
package org.alfresco.repo.rule;
|
||||
|
||||
import static org.alfresco.repo.rule.RuleModel.ASPECT_IGNORE_INHERITED_RULES;
|
||||
import static org.alfresco.repo.rule.RuleModel.ASSOC_RULE_FOLDER;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
@@ -35,6 +36,9 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.ActionImpl;
|
||||
@@ -257,7 +261,7 @@ public class RuleServiceImpl
|
||||
policyComponent.bindAssociationBehaviour(
|
||||
NodeServicePolicies.OnCreateChildAssociationPolicy.QNAME,
|
||||
RuleModel.ASPECT_RULES,
|
||||
RuleModel.ASSOC_RULE_FOLDER,
|
||||
ASSOC_RULE_FOLDER,
|
||||
new JavaBehaviour(this, "onCreateChildAssociation"));
|
||||
policyComponent.bindClassBehaviour(
|
||||
NodeServicePolicies.OnAddAspectPolicy.QNAME,
|
||||
@@ -349,8 +353,8 @@ public class RuleServiceImpl
|
||||
|
||||
List<ChildAssociationRef> assocs = this.runtimeNodeService.getChildAssocs(
|
||||
nodeRef,
|
||||
RuleModel.ASSOC_RULE_FOLDER,
|
||||
RuleModel.ASSOC_RULE_FOLDER);
|
||||
ASSOC_RULE_FOLDER,
|
||||
ASSOC_RULE_FOLDER);
|
||||
if (assocs.size() > 1)
|
||||
{
|
||||
throw new ActionServiceException("There is more than one rule folder, which is invalid.");
|
||||
@@ -1568,6 +1572,12 @@ public class RuleServiceImpl
|
||||
return this.nodeService.getPrimaryParent(systemFolder).getParentRef();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeRef getOwningNodeRef(NodeRef ruleSet)
|
||||
{
|
||||
return nodeService.getPrimaryParent(ruleSet).getParentRef();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeRef getOwningNodeRef(final Action action)
|
||||
{
|
||||
@@ -1660,7 +1670,7 @@ public class RuleServiceImpl
|
||||
@Experimental
|
||||
public NodeRef getRuleSetNode(final NodeRef folderNodeRef)
|
||||
{
|
||||
return runtimeNodeService.getChildAssocs(folderNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER).stream()
|
||||
return runtimeNodeService.getChildAssocs(folderNodeRef, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER).stream()
|
||||
.map(ChildAssociationRef::getChildRef)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
@@ -1670,7 +1680,10 @@ public class RuleServiceImpl
|
||||
@Experimental
|
||||
public boolean isRuleSetAssociatedWithFolder(final NodeRef ruleSetNodeRef, final NodeRef folderNodeRef)
|
||||
{
|
||||
return isChildOf(ruleSetNodeRef, RuleModel.ASSOC_RULE_FOLDER, folderNodeRef);
|
||||
List<ChildAssociationRef> associations = runtimeNodeService.getParentAssocs(ruleSetNodeRef, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
|
||||
Set<NodeRef> associatedFolders = associations.stream().map(ChildAssociationRef::getParentRef).collect(Collectors.toSet());
|
||||
Set<NodeRef> supplyingFolders = new HashSet<>(getNodesSupplyingRuleSets(folderNodeRef));
|
||||
return !Sets.intersection(associatedFolders, supplyingFolders).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -311,7 +311,17 @@ public interface RuleService
|
||||
*/
|
||||
@Auditable(parameters = {"action"})
|
||||
public NodeRef getOwningNodeRef(Action action);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the owning node reference for a rule.
|
||||
*
|
||||
* @param ruleSet The rule set node.
|
||||
* @return the owning node reference
|
||||
*/
|
||||
@Auditable (parameters = { "ruleSet" })
|
||||
@Experimental
|
||||
NodeRef getOwningNodeRef(NodeRef ruleSet);
|
||||
|
||||
/**
|
||||
* Indicates whether the passed rule node reference is linked to another
|
||||
* rule node.
|
||||
@@ -353,7 +363,7 @@ public interface RuleService
|
||||
NodeRef getRuleSetNode(final NodeRef folderNodeRef);
|
||||
|
||||
/**
|
||||
* Check if rule set's associated parent matches folder node.
|
||||
* Check if rule set is associated (owned/linked/inherited) with the given folder node.
|
||||
*
|
||||
* @param ruleSetNodeRef - node reference of a rule set
|
||||
* @param folderNodeRef - node reference of a folder
|
||||
|
@@ -254,6 +254,8 @@ public class RuleServiceImplUnitTest
|
||||
boolean associated = ruleService.isRuleSetAssociatedWithFolder(RULE_SET_NODE, FOLDER_NODE);
|
||||
|
||||
then(runtimeNodeService).should().getParentAssocs(RULE_SET_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
|
||||
then(runtimeNodeService).should().hasAspect(FOLDER_NODE, ASPECT_IGNORE_INHERITED_RULES);
|
||||
then(runtimeNodeService).should().getParentAssocs(FOLDER_NODE);
|
||||
then(runtimeNodeService).shouldHaveNoMoreInteractions();
|
||||
then(nodeService).shouldHaveNoInteractions();
|
||||
assertThat(associated).isTrue();
|
||||
@@ -268,6 +270,8 @@ public class RuleServiceImplUnitTest
|
||||
boolean associated = ruleService.isRuleSetAssociatedWithFolder(RULE_SET_NODE, FOLDER_NODE);
|
||||
|
||||
then(runtimeNodeService).should().getParentAssocs(RULE_SET_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
|
||||
then(runtimeNodeService).should().hasAspect(FOLDER_NODE, ASPECT_IGNORE_INHERITED_RULES);
|
||||
then(runtimeNodeService).should().getParentAssocs(FOLDER_NODE);
|
||||
then(runtimeNodeService).shouldHaveNoMoreInteractions();
|
||||
then(nodeService).shouldHaveNoInteractions();
|
||||
assertThat(associated).isFalse();
|
||||
@@ -283,11 +287,45 @@ public class RuleServiceImplUnitTest
|
||||
boolean associated = ruleService.isRuleSetAssociatedWithFolder(RULE_SET_NODE, FOLDER_NODE);
|
||||
|
||||
then(runtimeNodeService).should().getParentAssocs(RULE_SET_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER);
|
||||
then(runtimeNodeService).should().hasAspect(FOLDER_NODE, ASPECT_IGNORE_INHERITED_RULES);
|
||||
then(runtimeNodeService).should().getParentAssocs(FOLDER_NODE);
|
||||
then(runtimeNodeService).shouldHaveNoMoreInteractions();
|
||||
then(nodeService).shouldHaveNoInteractions();
|
||||
assertThat(associated).isFalse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a rule set is associated with the folder in the following case:
|
||||
* <pre>
|
||||
* parent --[link]-> rule set <-[owned]-- owningFolder
|
||||
* +- child
|
||||
* </pre>
|
||||
*/
|
||||
@Test
|
||||
public void testIsRuleSetAssociatedWithFolder_inheritedLinkedAssociation()
|
||||
{
|
||||
// The rule is owned by one node.
|
||||
NodeRef owningFolder = new NodeRef("owning://node/");
|
||||
// The rule is linked to by the parent node.
|
||||
NodeRef parent = new NodeRef("parent://node/");
|
||||
List<ChildAssociationRef> ruleAssociations = List.of(createAssociation(owningFolder, RULE_SET_NODE), createAssociation(parent, RULE_SET_NODE));
|
||||
given(runtimeNodeService.getParentAssocs(RULE_SET_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER)).willReturn(ruleAssociations);
|
||||
// The parent and the child both supply rule sets.
|
||||
given(runtimeNodeService.getParentAssocs(FOLDER_NODE)).willReturn(List.of(createAssociation(parent, FOLDER_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).should().hasAspect(FOLDER_NODE, ASPECT_IGNORE_INHERITED_RULES);
|
||||
then(runtimeNodeService).should().getParentAssocs(FOLDER_NODE);
|
||||
then(runtimeNodeService).should().hasAspect(parent, ASPECT_IGNORE_INHERITED_RULES);
|
||||
then(runtimeNodeService).should().getParentAssocs(parent);
|
||||
then(runtimeNodeService).shouldHaveNoMoreInteractions();
|
||||
then(nodeService).shouldHaveNoInteractions();
|
||||
assertThat(associated).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsRuleAssociatedWithRuleSet()
|
||||
{
|
||||
|
Reference in New Issue
Block a user