mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merge feature/FolderRulesMaster into master.
This commit is contained in:
@@ -161,7 +161,7 @@ public class BaseRMRestTest extends RestTest
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@BeforeClass (alwaysRun = true)
|
@BeforeClass (alwaysRun = true)
|
||||||
public void checkServerHealth() throws Exception
|
public void checkServerHealth()
|
||||||
{
|
{
|
||||||
// Create RM Site if not exist
|
// Create RM Site if not exist
|
||||||
createRMSiteIfNotExists();
|
createRMSiteIfNotExists();
|
||||||
|
@@ -156,25 +156,24 @@ public class ExtendedRuleServiceImpl extends RuleServiceImpl
|
|||||||
* @see org.alfresco.repo.rule.RuleServiceImpl#saveRule(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.rule.Rule)
|
* @see org.alfresco.repo.rule.RuleServiceImpl#saveRule(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.rule.Rule)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void saveRule(final NodeRef nodeRef, final Rule rule)
|
public Rule saveRule(final NodeRef nodeRef, final Rule rule)
|
||||||
{
|
{
|
||||||
validateWormLockRuleAction(rule);
|
validateWormLockRuleAction(rule);
|
||||||
if (filePlanService.isFilePlanComponent(nodeRef))
|
if (filePlanService.isFilePlanComponent(nodeRef))
|
||||||
{
|
{
|
||||||
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
return AuthenticationUtil.runAsSystem(new RunAsWork<Rule>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public Void doWork()
|
public Rule doWork()
|
||||||
{
|
{
|
||||||
ExtendedRuleServiceImpl.super.saveRule(nodeRef, rule);
|
return ExtendedRuleServiceImpl.super.saveRule(nodeRef, rule);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
super.saveRule(nodeRef, rule);
|
return super.saveRule(nodeRef, rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.rest.rules;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
|
import static org.alfresco.utility.model.FileModel.getRandomFileModel;
|
||||||
|
import static org.alfresco.utility.model.FileType.TEXT_PLAIN;
|
||||||
|
import static org.alfresco.utility.report.log.Step.STEP;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
|
import static org.springframework.http.HttpStatus.CREATED;
|
||||||
|
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
||||||
|
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
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.utility.model.FileModel;
|
||||||
|
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 POST /nodes/{nodeId}/rule-sets/{ruleSetId}/rules.
|
||||||
|
*/
|
||||||
|
@Test(groups = {TestGroup.RULES})
|
||||||
|
public class CreateRulesTests extends RestTest
|
||||||
|
{
|
||||||
|
private UserModel user;
|
||||||
|
private SiteModel site;
|
||||||
|
private FolderModel ruleFolder;
|
||||||
|
|
||||||
|
@BeforeClass(alwaysRun = true)
|
||||||
|
public void dataPreparation()
|
||||||
|
{
|
||||||
|
user = dataUser.createRandomTestUser();
|
||||||
|
site = dataSite.usingUser(user).createPublicRandomSite();
|
||||||
|
ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we can create a rule. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
|
||||||
|
public void createRule()
|
||||||
|
{
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("ruleName");
|
||||||
|
|
||||||
|
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
|
||||||
|
.createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(CREATED);
|
||||||
|
|
||||||
|
rule.assertThat().field("id").isNotNull()
|
||||||
|
.assertThat().field("name").is("ruleName");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check creating a rule in a non-existent folder returns an error. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void createRuleInNonExistentFolder()
|
||||||
|
{
|
||||||
|
STEP("Try to create a rule in non-existent folder.");
|
||||||
|
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
|
||||||
|
nonExistentFolder.setNodeRef("fake-id");
|
||||||
|
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("ruleName");
|
||||||
|
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(NOT_FOUND);
|
||||||
|
restClient.assertLastError().containsSummary("fake-id was not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check creating a rule in a non-existent rule set returns an error. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void createRuleInNonExistentRuleSet()
|
||||||
|
{
|
||||||
|
STEP("Try to create a rule in non-existent rule set.");
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("ruleName");
|
||||||
|
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingRuleSet("fake-id").createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(NOT_FOUND);
|
||||||
|
restClient.assertLastError().containsSummary("fake-id was not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Try to create a rule without a name and check the error. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void createRuleWithEmptyName()
|
||||||
|
{
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("");
|
||||||
|
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(BAD_REQUEST);
|
||||||
|
restClient.assertLastError().containsSummary("Rule name is a mandatory parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we can create two rules with the same name. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void duplicateRuleNameIsAcceptable()
|
||||||
|
{
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("duplicateRuleName");
|
||||||
|
|
||||||
|
STEP("Create two identical rules");
|
||||||
|
RestRuleModel ruleA = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
RestRuleModel ruleB = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
// Check that the names are the same but the ids are different.
|
||||||
|
ruleA.assertThat().field("name").is(ruleB.getName());
|
||||||
|
ruleA.assertThat().field("id").isNot(ruleB.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check that a user without permission to view the folder cannot create a rule in it. */
|
||||||
|
public void requirePermissionToCreateRule()
|
||||||
|
{
|
||||||
|
STEP("Create a user and use them to create a private site containing a folder");
|
||||||
|
UserModel privateUser = dataUser.createRandomTestUser();
|
||||||
|
SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
|
||||||
|
FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
|
||||||
|
|
||||||
|
STEP("Try to use a different user to create a rule in the private folder");
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("ruleName");
|
||||||
|
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(FORBIDDEN);
|
||||||
|
restClient.assertLastError().containsSummary("Cannot read from this node");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we can't create a rule under a document node. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void tryToCreateRuleUnderDocument()
|
||||||
|
{
|
||||||
|
STEP("Create a document.");
|
||||||
|
FileModel fileModel = dataContent.usingUser(user).usingSite(site).createContent(getRandomFileModel(TEXT_PLAIN));
|
||||||
|
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("ruleName");
|
||||||
|
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(fileModel).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(BAD_REQUEST);
|
||||||
|
restClient.assertLastError().containsSummary("folder is expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we can create several rules. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void createRules()
|
||||||
|
{
|
||||||
|
STEP("Create a list of rules in one POST request");
|
||||||
|
List<String> ruleNames = List.of("ruleA", "ruleB", "ruleC");
|
||||||
|
List<RestRuleModel> ruleModels = ruleNames.stream().map(ruleName ->
|
||||||
|
{
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName(ruleName);
|
||||||
|
return ruleModel;
|
||||||
|
}).collect(toList());
|
||||||
|
|
||||||
|
RestRuleModelsCollection rules = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet()
|
||||||
|
.createListOfRules(ruleModels);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(CREATED);
|
||||||
|
|
||||||
|
assertEquals("Unexpected number of rules received in response.", ruleNames.size(), rules.getEntries().size());
|
||||||
|
IntStream.range(0, ruleModels.size()).forEach(i ->
|
||||||
|
rules.getEntries().get(i).onModel()
|
||||||
|
.assertThat().field("id").isNotNull()
|
||||||
|
.assertThat().field("name").is(ruleNames.get(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Try to create several rules with an error in one of them. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void createRulesWithOneError()
|
||||||
|
{
|
||||||
|
STEP("Try to create a three rules but the middle one has an error.");
|
||||||
|
RestRuleModel ruleA = new RestRuleModel();
|
||||||
|
ruleA.setName("ruleA");
|
||||||
|
RestRuleModel ruleB = new RestRuleModel();
|
||||||
|
// Don't set a name for Rule B.
|
||||||
|
RestRuleModel ruleC = new RestRuleModel();
|
||||||
|
ruleC.setName("ruleC");
|
||||||
|
List<RestRuleModel> ruleModels = List.of(ruleA, ruleB, ruleC);
|
||||||
|
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createListOfRules(ruleModels);
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(BAD_REQUEST);
|
||||||
|
restClient.assertLastError().containsSummary("Rule name is a mandatory parameter");
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* #%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 java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
|
import static org.alfresco.utility.constants.UserRole.SiteCollaborator;
|
||||||
|
import static org.alfresco.utility.report.log.Step.STEP;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
||||||
|
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||||
|
import static org.springframework.http.HttpStatus.OK;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.alfresco.rest.RestTest;
|
||||||
|
import org.alfresco.rest.model.RestRuleModel;
|
||||||
|
import org.alfresco.rest.model.RestRuleModelsCollection;
|
||||||
|
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 and GET /nodes/{nodeId}/rule-sets/{ruleSetId}/rules/{ruleId}.
|
||||||
|
*/
|
||||||
|
@Test(groups = {TestGroup.RULES})
|
||||||
|
public class GetRulesTests extends RestTest
|
||||||
|
{
|
||||||
|
private UserModel user;
|
||||||
|
private SiteModel site;
|
||||||
|
private FolderModel ruleFolder;
|
||||||
|
private List<RestRuleModel> createdRules;
|
||||||
|
private RestRuleModel createdRuleA;
|
||||||
|
|
||||||
|
@BeforeClass(alwaysRun = true)
|
||||||
|
public void dataPreparation()
|
||||||
|
{
|
||||||
|
STEP("Create a user, site and folder");
|
||||||
|
user = dataUser.createRandomTestUser();
|
||||||
|
site = dataSite.usingUser(user).createPublicRandomSite();
|
||||||
|
ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||||
|
|
||||||
|
STEP("Create rules in the folder");
|
||||||
|
createdRules = Stream.of("ruleA", "ruleB").map(ruleName -> {
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName(ruleName);
|
||||||
|
return restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
}).collect(toList());
|
||||||
|
createdRuleA = createdRules.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we can get an empty list of rules. */
|
||||||
|
@Test(groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void getEmptyRulesList()
|
||||||
|
{
|
||||||
|
STEP("Create a folder in existing site");
|
||||||
|
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||||
|
|
||||||
|
STEP("Get the rules that apply to the folder");
|
||||||
|
RestRuleModelsCollection rules = restClient.authenticateUser(user).withCoreAPI().usingNode(folder).usingDefaultRuleSet().getListOfRules();
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(OK);
|
||||||
|
assertTrue("Expected no rules to be present.", rules.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we can get all the rules for a folder. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
|
||||||
|
public void getRulesList()
|
||||||
|
{
|
||||||
|
STEP("Get the rules that apply to the folder");
|
||||||
|
RestRuleModelsCollection rules = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().getListOfRules();
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(OK);
|
||||||
|
rules.assertThat().entriesListCountIs(createdRules.size());
|
||||||
|
IntStream.range(0, createdRules.size()).forEach(i ->
|
||||||
|
rules.getEntries().get(i).onModel()
|
||||||
|
.assertThat().field("id").is(createdRules.get(i).getId())
|
||||||
|
.assertThat().field("name").is(createdRules.get(i).getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we get a 404 if trying to load rules for a folder that doesn't exist. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void getRulesForNonExistentFolder()
|
||||||
|
{
|
||||||
|
STEP("Try to load rules for a non-existent folder.");
|
||||||
|
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
|
||||||
|
nonExistentFolder.setNodeRef("fake-id");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).usingDefaultRuleSet().getListOfRules();
|
||||||
|
restClient.assertStatusCodeIs(NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we get a 404 if trying to load rules with a rule set id that doesn't exist. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void getRulesFromNonExistentRuleSet()
|
||||||
|
{
|
||||||
|
STEP("Create a folder in existing site");
|
||||||
|
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||||
|
STEP("Try to load rules for a non-existent rule set.");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(folder).usingRuleSet("fake-id").getListOfRules();
|
||||||
|
restClient.assertStatusCodeIs(NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we can get a rule by its id. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
|
||||||
|
public void getSingleRule()
|
||||||
|
{
|
||||||
|
STEP("Load a particular rule");
|
||||||
|
RestRuleModel rule = restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().getSingleRule(createdRuleA.getId());
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(OK);
|
||||||
|
|
||||||
|
rule.assertThat().field("id").is(createdRuleA.getId())
|
||||||
|
.assertThat().field("name").is(createdRuleA.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we get a 404 if trying to load a rule from a folder that doesn't exist. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void getSingleRuleFromNonExistentFolder()
|
||||||
|
{
|
||||||
|
STEP("Try to load a rule from a non-existent folder.");
|
||||||
|
FolderModel nonExistentFolder = FolderModel.getRandomFolderModel();
|
||||||
|
nonExistentFolder.setNodeRef("fake-id");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistentFolder).usingDefaultRuleSet().getSingleRule("fake-rule-id");
|
||||||
|
restClient.assertStatusCodeIs(NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check we get a 404 if trying to load a rule with a rule set id that doesn't exist. */
|
||||||
|
@Test (groups = { TestGroup.REST_API, TestGroup.RULES })
|
||||||
|
public void getSingleRuleFromNonExistentRuleSet()
|
||||||
|
{
|
||||||
|
STEP("Create a folder in existing site");
|
||||||
|
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||||
|
STEP("Try to load rules for a non-existent rule set.");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(folder).usingRuleSet("fake-id").getSingleRule("fake-rule-id");
|
||||||
|
restClient.assertStatusCodeIs(NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check that a user without read permission cannot view the folder rules. */
|
||||||
|
public void requireReadPermissionToGetRule()
|
||||||
|
{
|
||||||
|
STEP("Create a user and use them to create a private site containing a folder with a rule");
|
||||||
|
UserModel privateUser = dataUser.createRandomTestUser();
|
||||||
|
SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
|
||||||
|
FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("Private site rule");
|
||||||
|
restClient.authenticateUser(privateUser).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
STEP("Try to get the rule with another user");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().getListOfRules();
|
||||||
|
|
||||||
|
restClient.assertLastError()
|
||||||
|
.statusCodeIs(FORBIDDEN)
|
||||||
|
.containsSummary("Cannot read from this node");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check that a user with only read permission can view the folder rules. */
|
||||||
|
public void dontRequireWritePermissionToGetRule()
|
||||||
|
{
|
||||||
|
STEP("Create a user and use them to create a private site containing a folder with a rule");
|
||||||
|
UserModel privateUser = dataUser.createRandomTestUser();
|
||||||
|
SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite();
|
||||||
|
FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder();
|
||||||
|
RestRuleModel ruleModel = new RestRuleModel();
|
||||||
|
ruleModel.setName("Private site rule");
|
||||||
|
restClient.authenticateUser(privateUser).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().createSingleRule(ruleModel);
|
||||||
|
|
||||||
|
STEP("Create a collaborator in the private site");
|
||||||
|
UserModel collaborator = dataUser.createRandomTestUser();
|
||||||
|
collaborator.setUserRole(SiteCollaborator);
|
||||||
|
restClient.authenticateUser(privateUser).withCoreAPI().usingSite(privateSite).addPerson(collaborator);
|
||||||
|
|
||||||
|
STEP("Check the collaborator can view the rule");
|
||||||
|
RestRuleModelsCollection rules = restClient.authenticateUser(collaborator).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().getListOfRules();
|
||||||
|
|
||||||
|
restClient.assertStatusCodeIs(OK);
|
||||||
|
rules.assertThat().entriesListContains("name", "Private site rule");
|
||||||
|
}
|
||||||
|
}
|
@@ -1,11 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
|
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
|
||||||
<suite name="REST API tests part1" preserve-order="true">
|
<suite name="REST API tests part1" preserve-order="true">
|
||||||
<listeners>
|
<listeners>
|
||||||
<listener class-name="org.alfresco.utility.report.HtmlReportListener"/>
|
<listener class-name="org.alfresco.utility.report.HtmlReportListener"/>
|
||||||
<listener class-name="org.alfresco.utility.testrail.TestRailExecutorListener"/>
|
<listener class-name="org.alfresco.utility.testrail.TestRailExecutorListener"/>
|
||||||
<listener class-name="org.alfresco.utility.testng.OSTestMethodSelector"/>
|
<listener class-name="org.alfresco.utility.testng.OSTestMethodSelector"/>
|
||||||
</listeners>
|
</listeners>
|
||||||
|
|
||||||
<test name="Part1">
|
<test name="Part1">
|
||||||
<packages>
|
<packages>
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
<package name="org.alfresco.rest.comments.*"/>
|
<package name="org.alfresco.rest.comments.*"/>
|
||||||
<package name="org.alfresco.rest.downloads.*"/>
|
<package name="org.alfresco.rest.downloads.*"/>
|
||||||
<package name="org.alfresco.rest.favorites.*"/>
|
<package name="org.alfresco.rest.favorites.*"/>
|
||||||
|
<package name="org.alfresco.rest.rules.*" />
|
||||||
<package name="org.alfresco.rest.servlet.*"/>
|
<package name="org.alfresco.rest.servlet.*"/>
|
||||||
</packages>
|
</packages>
|
||||||
</test>
|
</test>
|
||||||
|
4
pom.xml
4
pom.xml
@@ -118,9 +118,9 @@
|
|||||||
<dependency.mysql.version>8.0.29</dependency.mysql.version>
|
<dependency.mysql.version>8.0.29</dependency.mysql.version>
|
||||||
<dependency.mysql-image.version>8</dependency.mysql-image.version>
|
<dependency.mysql-image.version>8</dependency.mysql-image.version>
|
||||||
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
|
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
|
||||||
<dependency.tas-utility.version>3.0.48</dependency.tas-utility.version>
|
<dependency.tas-utility.version>3.0.49</dependency.tas-utility.version>
|
||||||
<dependency.rest-assured.version>3.3.0</dependency.rest-assured.version>
|
<dependency.rest-assured.version>3.3.0</dependency.rest-assured.version>
|
||||||
<dependency.tas-restapi.version>1.87</dependency.tas-restapi.version>
|
<dependency.tas-restapi.version>1.94</dependency.tas-restapi.version>
|
||||||
<dependency.tas-cmis.version>1.31</dependency.tas-cmis.version>
|
<dependency.tas-cmis.version>1.31</dependency.tas-cmis.version>
|
||||||
<dependency.tas-email.version>1.8</dependency.tas-email.version>
|
<dependency.tas-email.version>1.8</dependency.tas-email.version>
|
||||||
<dependency.tas-webdav.version>1.6</dependency.tas-webdav.version>
|
<dependency.tas-webdav.version>1.6</dependency.tas-webdav.version>
|
||||||
|
@@ -27,9 +27,13 @@
|
|||||||
package org.alfresco.rest.api;
|
package org.alfresco.rest.api;
|
||||||
|
|
||||||
import org.alfresco.rest.api.model.rules.Rule;
|
import org.alfresco.rest.api.model.rules.Rule;
|
||||||
|
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||||
import org.alfresco.rest.framework.resource.parameters.Paging;
|
import org.alfresco.rest.framework.resource.parameters.Paging;
|
||||||
import org.alfresco.service.Experimental;
|
import org.alfresco.service.Experimental;
|
||||||
|
import org.alfresco.service.cmr.rule.RuleServiceException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Folder node rules API.
|
* Folder node rules API.
|
||||||
@@ -57,4 +61,25 @@ public interface Rules
|
|||||||
* @return {@link Rule} definition
|
* @return {@link Rule} definition
|
||||||
*/
|
*/
|
||||||
Rule getRuleById(String folderNodeId, String ruleSetId, String ruleId);
|
Rule getRuleById(String folderNodeId, String ruleSetId, String ruleId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new rules (and potentially a rule set if "_default_" is supplied).
|
||||||
|
*
|
||||||
|
* @param folderNodeId The node id of a folder.
|
||||||
|
* @param ruleSetId The id of a rule set (or "_default_" to use/create the default rule set for the folder).
|
||||||
|
* @param rule The definition of the rule.
|
||||||
|
* @return The newly created rules.
|
||||||
|
* @throws InvalidArgumentException If the nodes are not the expected types, or the rule set does not correspond to the folder.
|
||||||
|
* @throws RuleServiceException If the folder is already linked to another rule set.
|
||||||
|
*/
|
||||||
|
List<Rule> createRules(String folderNodeId, String ruleSetId, List<Rule> rule);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete rule for rule's ID and check associations with folder node and rule set node
|
||||||
|
*
|
||||||
|
* @param folderNodeId - folder node ID
|
||||||
|
* @param ruleSetId - rule set ID
|
||||||
|
* @param ruleId - rule ID *
|
||||||
|
*/
|
||||||
|
void deleteRuleById(String folderNodeId, String ruleSetId, String ruleId);
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,10 @@
|
|||||||
|
|
||||||
package org.alfresco.rest.api.impl;
|
package org.alfresco.rest.api.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.rule.RuleModel;
|
import org.alfresco.repo.rule.RuleModel;
|
||||||
import org.alfresco.rest.api.Nodes;
|
import org.alfresco.rest.api.Nodes;
|
||||||
@@ -44,10 +48,6 @@ import org.alfresco.service.cmr.security.AccessStatus;
|
|||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Experimental
|
@Experimental
|
||||||
public class RulesImpl implements Rules
|
public class RulesImpl implements Rules
|
||||||
{
|
{
|
||||||
@@ -82,6 +82,33 @@ public class RulesImpl implements Rules
|
|||||||
return Rule.from(ruleService.getRule(ruleNodeRef));
|
return Rule.from(ruleService.getRule(ruleNodeRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Rule> createRules(final String folderNodeId, final String ruleSetId, final List<Rule> rules)
|
||||||
|
{
|
||||||
|
final NodeRef folderNodeRef = validateFolderNode(folderNodeId);
|
||||||
|
// Don't validate the ruleset node if -default- is passed since we may need to create it.
|
||||||
|
if (RuleSet.isNotDefaultId(ruleSetId))
|
||||||
|
{
|
||||||
|
validateRuleSetNode(ruleSetId, folderNodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rules.stream()
|
||||||
|
.map(rule -> rule.toServiceModel(nodes))
|
||||||
|
.map(rule -> ruleService.saveRule(folderNodeRef, rule))
|
||||||
|
.map(Rule::from)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteRuleById(String folderNodeId, String ruleSetId, String ruleId)
|
||||||
|
{
|
||||||
|
final NodeRef folderNodeRef = validateFolderNode(folderNodeId);
|
||||||
|
final NodeRef ruleSetNodeRef = validateRuleSetNode(ruleSetId, folderNodeRef);
|
||||||
|
final NodeRef ruleNodeRef = validateRuleNode(ruleId, ruleSetNodeRef);
|
||||||
|
final org.alfresco.service.cmr.rule.Rule rule = ruleService.getRule(ruleNodeRef);
|
||||||
|
ruleService.removeRule(folderNodeRef, rule);
|
||||||
|
}
|
||||||
|
|
||||||
public void setNodes(Nodes nodes)
|
public void setNodes(Nodes nodes)
|
||||||
{
|
{
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
|
@@ -26,17 +26,25 @@
|
|||||||
|
|
||||||
package org.alfresco.rest.api.model.rules;
|
package org.alfresco.rest.api.model.rules;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.action.ActionImpl;
|
||||||
|
import org.alfresco.repo.action.executer.SetPropertyValueActionExecuter;
|
||||||
|
import org.alfresco.rest.api.Nodes;
|
||||||
import org.alfresco.rest.framework.resource.UniqueId;
|
import org.alfresco.rest.framework.resource.UniqueId;
|
||||||
import org.alfresco.service.Experimental;
|
import org.alfresco.service.Experimental;
|
||||||
import org.alfresco.service.cmr.action.CompositeAction;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import java.util.List;
|
import org.alfresco.util.GUID;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Experimental
|
@Experimental
|
||||||
public class Rule
|
public class Rule
|
||||||
{
|
{
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@@ -45,11 +53,36 @@ public class Rule
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Rule rule = new Rule();
|
return builder()
|
||||||
rule.id = ruleModel.getNodeRef().getId();
|
.setId(ruleModel.getNodeRef().getId())
|
||||||
rule.name = ruleModel.getTitle();
|
.setName(ruleModel.getTitle())
|
||||||
|
.createRule();
|
||||||
|
}
|
||||||
|
|
||||||
return rule;
|
/**
|
||||||
|
* Convert the REST model object to the equivalent service POJO.
|
||||||
|
*
|
||||||
|
* @param nodes The nodes API.
|
||||||
|
* @return The rule service POJO.
|
||||||
|
*/
|
||||||
|
public org.alfresco.service.cmr.rule.Rule toServiceModel(Nodes nodes)
|
||||||
|
{
|
||||||
|
org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule();
|
||||||
|
if (id != null)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = nodes.validateOrLookupNode(id, null);
|
||||||
|
ruleModel.setNodeRef(nodeRef);
|
||||||
|
}
|
||||||
|
ruleModel.setTitle(name);
|
||||||
|
|
||||||
|
// TODO: Once we have actions working properly then this needs to be replaced.
|
||||||
|
Map<String, Serializable> parameters = Map.of(
|
||||||
|
SetPropertyValueActionExecuter.PARAM_PROPERTY, ContentModel.PROP_TITLE,
|
||||||
|
SetPropertyValueActionExecuter.PARAM_VALUE, "UPDATED:" + GUID.generate());
|
||||||
|
Action action = new ActionImpl(null, GUID.generate(), SetPropertyValueActionExecuter.NAME, parameters);
|
||||||
|
ruleModel.setAction(action);
|
||||||
|
|
||||||
|
return ruleModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@UniqueId
|
@UniqueId
|
||||||
@@ -73,9 +106,69 @@ public class Rule
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Added stub for actions as it's a required field. Replace this implementation when we implement support for actions.
|
||||||
|
public List<Void> getActions()
|
||||||
|
{
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (this == o)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof Rule))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Rule rule = (Rule) o;
|
||||||
|
return Objects.equals(id, rule.id) &&
|
||||||
|
Objects.equals(name, rule.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Objects.hash(id, name);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "Rule{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}';
|
return "Rule{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RuleBuilder builder()
|
||||||
|
{
|
||||||
|
return new RuleBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Builder class. */
|
||||||
|
public static class RuleBuilder
|
||||||
|
{
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public RuleBuilder setId(String id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RuleBuilder setName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rule createRule()
|
||||||
|
{
|
||||||
|
Rule rule = new Rule();
|
||||||
|
rule.setId(id);
|
||||||
|
rule.setName(name);
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,7 @@ import org.alfresco.service.Experimental;
|
|||||||
@Experimental
|
@Experimental
|
||||||
public class RuleSet
|
public class RuleSet
|
||||||
{
|
{
|
||||||
private static final String DEFAULT_ID = "-default-";
|
public static final String DEFAULT_ID = "-default-";
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@ import org.alfresco.util.PropertyCheck;
|
|||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Folder node's rules.
|
* Folder node's rules.
|
||||||
@@ -46,7 +47,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
*/
|
*/
|
||||||
@Experimental
|
@Experimental
|
||||||
@RelationshipResource(name = "rules", entityResource = NodeRuleSetsRelation.class, title = "Folder node rules")
|
@RelationshipResource(name = "rules", entityResource = NodeRuleSetsRelation.class, title = "Folder node rules")
|
||||||
public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>, RelationshipResourceAction.ReadById<Rule>, InitializingBean
|
public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>, RelationshipResourceAction.ReadById<Rule>,
|
||||||
|
RelationshipResourceAction.Create<Rule>, RelationshipResourceAction.Delete, InitializingBean
|
||||||
{
|
{
|
||||||
|
|
||||||
private Rules rules;
|
private Rules rules;
|
||||||
@@ -103,8 +105,51 @@ public class NodeRulesRelation implements RelationshipResourceAction.Read<Rule>,
|
|||||||
return rules.getRuleById(folderNodeId, ruleSetId, ruleId);
|
return rules.getRuleById(folderNodeId, ruleSetId, ruleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create one or more rules inside a given folder and rule set.
|
||||||
|
*
|
||||||
|
* @param folderNodeId The folder in which to create the rule.
|
||||||
|
* @param ruleList The list of rules to create.
|
||||||
|
* @param parameters List of parameters including the rule set id as the relationship.
|
||||||
|
* @return The newly created rules.
|
||||||
|
*/
|
||||||
|
@WebApiDescription(
|
||||||
|
title = "Create folder rule",
|
||||||
|
description = "Creates one or more folder rules for the given folder and rule set",
|
||||||
|
successStatus = HttpServletResponse.SC_CREATED
|
||||||
|
)
|
||||||
|
@Override
|
||||||
|
public List<Rule> create(String folderNodeId, List<Rule> ruleList, Parameters parameters)
|
||||||
|
{
|
||||||
|
final String ruleSetId = parameters.getRelationshipId();
|
||||||
|
|
||||||
|
return rules.createRules(folderNodeId, ruleSetId, ruleList);
|
||||||
|
}
|
||||||
|
|
||||||
public void setRules(Rules rules)
|
public void setRules(Rules rules)
|
||||||
{
|
{
|
||||||
this.rules = rules;
|
this.rules = rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete single folder rule for given node's, rule set's and rule's IDs.
|
||||||
|
*
|
||||||
|
* - DELETE /nodes/{folderNodeId}/rule-sets/{ruleSetId}/rules/{ruleId}
|
||||||
|
*
|
||||||
|
* @param folderNodeId - entity resource context for this relationship
|
||||||
|
* @param ruleSetId - rule set node ID (associated with folder node)
|
||||||
|
* @param parameters - Should not be null. Should contain at least ruleId (relationship2Id)
|
||||||
|
* @throws RelationshipResourceNotFoundException in case resource was not found
|
||||||
|
*/
|
||||||
|
@WebApiDescription(
|
||||||
|
title="Delete folder node rule",
|
||||||
|
description = "Deletes a single rule definition for given node's, rule set's and rule's IDs",
|
||||||
|
successStatus = HttpServletResponse.SC_NO_CONTENT
|
||||||
|
)
|
||||||
|
@Override
|
||||||
|
public void delete(String folderNodeId, String ruleSetId, Parameters parameters)
|
||||||
|
{
|
||||||
|
final String ruleId = parameters.getRelationship2Id();
|
||||||
|
rules.deleteRuleById(folderNodeId, ruleSetId, ruleId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,9 +26,26 @@
|
|||||||
|
|
||||||
package org.alfresco.rest.api.impl;
|
package org.alfresco.rest.api.impl;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
|
||||||
|
import static org.alfresco.rest.api.model.rules.RuleSet.DEFAULT_ID;
|
||||||
|
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.isNull;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.BDDMockito.then;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import org.alfresco.rest.api.Nodes;
|
import org.alfresco.rest.api.Nodes;
|
||||||
import org.alfresco.rest.api.model.rules.Rule;
|
import org.alfresco.rest.api.model.rules.Rule;
|
||||||
|
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
||||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||||
@@ -47,22 +64,10 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
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.isNull;
|
|
||||||
import static org.mockito.BDDMockito.given;
|
|
||||||
import static org.mockito.BDDMockito.then;
|
|
||||||
|
|
||||||
@Experimental
|
@Experimental
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class RulesImplTest extends TestCase
|
public class RulesImplTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final String FOLDER_NODE_ID = "dummy-folder-node-id";
|
private static final String FOLDER_NODE_ID = "dummy-folder-node-id";
|
||||||
private static final String RULE_SET_ID = "dummy-rule-set-id";
|
private static final String RULE_SET_ID = "dummy-rule-set-id";
|
||||||
private static final String RULE_ID = "dummy-rule-id";
|
private static final String RULE_ID = "dummy-rule-id";
|
||||||
@@ -70,6 +75,7 @@ public class RulesImplTest extends TestCase
|
|||||||
private static final NodeRef ruleSetNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
|
private static final NodeRef ruleSetNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
|
||||||
private static final NodeRef ruleNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID);
|
private static final NodeRef ruleNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID);
|
||||||
private static final Paging paging = Paging.DEFAULT;
|
private static final Paging paging = Paging.DEFAULT;
|
||||||
|
private static final String RULE_NAME = "Rule name";
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Nodes nodesMock;
|
private Nodes nodesMock;
|
||||||
@@ -90,7 +96,7 @@ public class RulesImplTest extends TestCase
|
|||||||
MockitoAnnotations.openMocks(this);
|
MockitoAnnotations.openMocks(this);
|
||||||
|
|
||||||
given(nodesMock.validateOrLookupNode(eq(FOLDER_NODE_ID), any())).willReturn(folderNodeRef);
|
given(nodesMock.validateOrLookupNode(eq(FOLDER_NODE_ID), any())).willReturn(folderNodeRef);
|
||||||
given(nodesMock.validateNode(eq(RULE_SET_ID))).willReturn(ruleSetNodeRef);
|
given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef);
|
||||||
given(nodesMock.nodeMatches(any(), any(), any())).willReturn(true);
|
given(nodesMock.nodeMatches(any(), any(), any())).willReturn(true);
|
||||||
given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.ALLOWED);
|
given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.ALLOWED);
|
||||||
}
|
}
|
||||||
@@ -104,15 +110,15 @@ public class RulesImplTest extends TestCase
|
|||||||
// when
|
// when
|
||||||
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging);
|
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging);
|
||||||
|
|
||||||
then(nodesMock).should().validateOrLookupNode(eq(FOLDER_NODE_ID), isNull());
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
then(nodesMock).should().validateNode(eq(RULE_SET_ID));
|
then(nodesMock).should().validateNode(RULE_SET_ID);
|
||||||
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
||||||
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
|
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
|
||||||
then(nodesMock).shouldHaveNoMoreInteractions();
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
then(permissionServiceMock).should().hasReadPermission(eq(folderNodeRef));
|
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
|
||||||
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
then(ruleServiceMock).should().getRules(eq(folderNodeRef));
|
then(ruleServiceMock).should().getRules(folderNodeRef);
|
||||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
assertThat(rulesPage)
|
assertThat(rulesPage)
|
||||||
.isNotNull()
|
.isNotNull()
|
||||||
@@ -129,19 +135,18 @@ public class RulesImplTest extends TestCase
|
|||||||
@Test
|
@Test
|
||||||
public void testGetRulesForDefaultRuleSet()
|
public void testGetRulesForDefaultRuleSet()
|
||||||
{
|
{
|
||||||
final String defaultRuleSetId = "-default-";
|
|
||||||
given(ruleServiceMock.getRules(any())).willReturn(List.of(createRule(RULE_ID)));
|
given(ruleServiceMock.getRules(any())).willReturn(List.of(createRule(RULE_ID)));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, defaultRuleSetId, paging);
|
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, DEFAULT_ID, paging);
|
||||||
|
|
||||||
then(nodesMock).should().validateOrLookupNode(eq(FOLDER_NODE_ID), isNull());
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
||||||
then(nodesMock).shouldHaveNoMoreInteractions();
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
then(permissionServiceMock).should().hasReadPermission(eq(folderNodeRef));
|
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
|
||||||
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
then(ruleServiceMock).should().getRuleSetNode(eq(folderNodeRef));
|
then(ruleServiceMock).should().getRuleSetNode(folderNodeRef);
|
||||||
then(ruleServiceMock).should().getRules(eq(folderNodeRef));
|
then(ruleServiceMock).should().getRules(folderNodeRef);
|
||||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
assertThat(rulesPage)
|
assertThat(rulesPage)
|
||||||
.isNotNull()
|
.isNotNull()
|
||||||
@@ -189,7 +194,7 @@ public class RulesImplTest extends TestCase
|
|||||||
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
|
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
|
||||||
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
|
() -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging));
|
||||||
|
|
||||||
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +213,7 @@ public class RulesImplTest extends TestCase
|
|||||||
@Test
|
@Test
|
||||||
public void testGetRuleById()
|
public void testGetRuleById()
|
||||||
{
|
{
|
||||||
given(nodesMock.validateNode(eq(RULE_ID))).willReturn(ruleNodeRef);
|
given(nodesMock.validateNode(RULE_ID)).willReturn(ruleNodeRef);
|
||||||
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
||||||
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(true);
|
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(true);
|
||||||
given(ruleServiceMock.getRule(any())).willReturn(createRule(RULE_ID));
|
given(ruleServiceMock.getRule(any())).willReturn(createRule(RULE_ID));
|
||||||
@@ -216,18 +221,18 @@ public class RulesImplTest extends TestCase
|
|||||||
// when
|
// when
|
||||||
final Rule rule = rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID);
|
final Rule rule = rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID);
|
||||||
|
|
||||||
then(nodesMock).should().validateOrLookupNode(eq(FOLDER_NODE_ID), isNull());
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
then(nodesMock).should().validateNode(eq(RULE_SET_ID));
|
then(nodesMock).should().validateNode(RULE_SET_ID);
|
||||||
then(nodesMock).should().validateNode(eq(RULE_ID));
|
then(nodesMock).should().validateNode(RULE_ID);
|
||||||
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
||||||
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
|
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
|
||||||
then(nodesMock).should().nodeMatches(eq(ruleNodeRef), any(), isNull());
|
then(nodesMock).should().nodeMatches(eq(ruleNodeRef), any(), isNull());
|
||||||
then(nodesMock).shouldHaveNoMoreInteractions();
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
then(permissionServiceMock).should().hasReadPermission(eq(folderNodeRef));
|
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
|
||||||
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(eq(ruleNodeRef), eq(ruleSetNodeRef));
|
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(ruleNodeRef, ruleSetNodeRef);
|
||||||
then(ruleServiceMock).should().getRule(eq(ruleNodeRef));
|
then(ruleServiceMock).should().getRule(ruleNodeRef);
|
||||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
assertThat(rule)
|
assertThat(rule)
|
||||||
.isNotNull()
|
.isNotNull()
|
||||||
@@ -239,7 +244,7 @@ public class RulesImplTest extends TestCase
|
|||||||
public void testGetRuleByIdForDefaultRuleSet()
|
public void testGetRuleByIdForDefaultRuleSet()
|
||||||
{
|
{
|
||||||
final String defaultRuleSetId = "-default-";
|
final String defaultRuleSetId = "-default-";
|
||||||
given(nodesMock.validateNode(eq(RULE_ID))).willReturn(ruleNodeRef);
|
given(nodesMock.validateNode(RULE_ID)).willReturn(ruleNodeRef);
|
||||||
given(ruleServiceMock.getRuleSetNode(any())).willReturn(ruleSetNodeRef);
|
given(ruleServiceMock.getRuleSetNode(any())).willReturn(ruleSetNodeRef);
|
||||||
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(true);
|
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(true);
|
||||||
given(ruleServiceMock.getRule(any())).willReturn(createRule(RULE_ID));
|
given(ruleServiceMock.getRule(any())).willReturn(createRule(RULE_ID));
|
||||||
@@ -247,15 +252,15 @@ public class RulesImplTest extends TestCase
|
|||||||
// when
|
// when
|
||||||
final Rule rule = rules.getRuleById(FOLDER_NODE_ID, defaultRuleSetId, RULE_ID);
|
final Rule rule = rules.getRuleById(FOLDER_NODE_ID, defaultRuleSetId, RULE_ID);
|
||||||
|
|
||||||
then(nodesMock).should().validateOrLookupNode(eq(FOLDER_NODE_ID), isNull());
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
then(nodesMock).should().validateNode(eq(RULE_ID));
|
then(nodesMock).should().validateNode(RULE_ID);
|
||||||
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
||||||
then(nodesMock).should().nodeMatches(eq(ruleNodeRef), any(), isNull());
|
then(nodesMock).should().nodeMatches(eq(ruleNodeRef), any(), isNull());
|
||||||
then(nodesMock).shouldHaveNoMoreInteractions();
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
then(permissionServiceMock).should().hasReadPermission(eq(folderNodeRef));
|
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
|
||||||
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
then(ruleServiceMock).should().getRuleSetNode(eq(folderNodeRef));
|
then(ruleServiceMock).should().getRuleSetNode(folderNodeRef);
|
||||||
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(eq(ruleNodeRef), eq(ruleSetNodeRef));
|
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(ruleNodeRef, ruleSetNodeRef);
|
||||||
then(ruleServiceMock).should().getRule(eq(ruleNodeRef));
|
then(ruleServiceMock).should().getRule(eq(ruleNodeRef));
|
||||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
assertThat(rule)
|
assertThat(rule)
|
||||||
@@ -267,8 +272,8 @@ public class RulesImplTest extends TestCase
|
|||||||
@Test
|
@Test
|
||||||
public void testGetRuleByIdForNotAssociatedRuleToRuleSet()
|
public void testGetRuleByIdForNotAssociatedRuleToRuleSet()
|
||||||
{
|
{
|
||||||
given(nodesMock.validateNode(eq(RULE_SET_ID))).willReturn(ruleSetNodeRef);
|
given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef);
|
||||||
given(nodesMock.validateNode(eq(RULE_ID))).willReturn(ruleNodeRef);
|
given(nodesMock.validateNode(RULE_ID)).willReturn(ruleNodeRef);
|
||||||
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
||||||
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(false);
|
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(false);
|
||||||
|
|
||||||
@@ -276,8 +281,240 @@ public class RulesImplTest extends TestCase
|
|||||||
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
|
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
|
||||||
() -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
|
() -> rules.getRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
|
||||||
|
|
||||||
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef));
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(eq(ruleNodeRef), eq(ruleSetNodeRef));
|
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(ruleNodeRef, ruleSetNodeRef);
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a single rule. */
|
||||||
|
@Test
|
||||||
|
public void testSaveRules()
|
||||||
|
{
|
||||||
|
Rule ruleBody = mock(Rule.class);
|
||||||
|
List<Rule> ruleList = List.of(ruleBody);
|
||||||
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
||||||
|
org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class);
|
||||||
|
given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody);
|
||||||
|
org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class);
|
||||||
|
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
|
||||||
|
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
|
||||||
|
|
||||||
|
// when
|
||||||
|
List<Rule> actual = rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), ruleList);
|
||||||
|
|
||||||
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
|
then(ruleServiceMock).should().saveRule(folderNodeRef, ruleBody.toServiceModel(nodesMock));
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
List<Rule> expected = List.of(Rule.from(serviceRule));
|
||||||
|
assertThat(actual).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check that when passing the default rule set then we don't perform any validation around the rule set node. */
|
||||||
|
@Test
|
||||||
|
public void testSaveRules_defaultRuleSet()
|
||||||
|
{
|
||||||
|
Rule ruleBody = mock(Rule.class);
|
||||||
|
List<Rule> ruleList = List.of(ruleBody);
|
||||||
|
org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class);
|
||||||
|
given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody);
|
||||||
|
org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class);
|
||||||
|
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
|
||||||
|
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
|
||||||
|
|
||||||
|
// when
|
||||||
|
List<Rule> actual = rules.createRules(folderNodeRef.getId(), DEFAULT_ID, ruleList);
|
||||||
|
|
||||||
|
then(ruleServiceMock).should().saveRule(folderNodeRef, ruleBody.toServiceModel(nodesMock));
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
List<Rule> expected = List.of(Rule.from(serviceRule));
|
||||||
|
assertThat(actual).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveRules_ruleSetNotAssociatedWithFolder()
|
||||||
|
{
|
||||||
|
Rule rule = Rule.builder().setName(RULE_NAME)
|
||||||
|
.createRule();
|
||||||
|
List<Rule> ruleList = List.of(rule);
|
||||||
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef)).willReturn(false);
|
||||||
|
|
||||||
|
// when
|
||||||
|
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
|
||||||
|
() -> rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), ruleList));
|
||||||
|
|
||||||
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveRules_emptyRuleList()
|
||||||
|
{
|
||||||
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
||||||
|
List<Rule> ruleList = emptyList();
|
||||||
|
|
||||||
|
// when
|
||||||
|
List<Rule> actual = this.rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), ruleList);
|
||||||
|
|
||||||
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
assertThat(actual).isEqualTo(emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create three rules in a single call and check they are all passed to the RuleService. */
|
||||||
|
@Test
|
||||||
|
public void testSaveRules_createMultipleRules()
|
||||||
|
{
|
||||||
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
||||||
|
List<Rule> ruleBodyList = new ArrayList<>();
|
||||||
|
List<Rule> expected = new ArrayList<>();
|
||||||
|
for (String ruleId : List.of("A", "B", "C"))
|
||||||
|
{
|
||||||
|
Rule ruleBody = mock(Rule.class);
|
||||||
|
ruleBodyList.add(ruleBody);
|
||||||
|
org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class);
|
||||||
|
given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody);
|
||||||
|
org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class);
|
||||||
|
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
|
||||||
|
NodeRef ruleNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, ruleId);
|
||||||
|
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
|
||||||
|
expected.add(Rule.from(serviceRule));
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
List<Rule> actual = rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), ruleBodyList);
|
||||||
|
|
||||||
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
|
for (Rule ruleBody : ruleBodyList)
|
||||||
|
{
|
||||||
|
then(ruleServiceMock).should().saveRule(folderNodeRef, ruleBody.toServiceModel(nodesMock));
|
||||||
|
}
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
assertThat(actual).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteRuleById() {
|
||||||
|
given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef);
|
||||||
|
given(nodesMock.validateNode(RULE_ID)).willReturn(ruleNodeRef);
|
||||||
|
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(true);
|
||||||
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
||||||
|
org.alfresco.service.cmr.rule.Rule rule = createRule(RULE_ID);
|
||||||
|
given(ruleServiceMock.getRule(any())).willReturn(rule);
|
||||||
|
|
||||||
|
//when
|
||||||
|
rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID);
|
||||||
|
|
||||||
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
|
then(nodesMock).should().validateNode(RULE_SET_ID);
|
||||||
|
then(nodesMock).should().validateNode(RULE_ID);
|
||||||
|
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).should().nodeMatches(eq(ruleNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
|
||||||
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
|
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(ruleNodeRef, ruleSetNodeRef);
|
||||||
|
then(ruleServiceMock).should().getRule(ruleNodeRef);
|
||||||
|
then(ruleServiceMock).should().removeRule(folderNodeRef, rule);
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteRuleById_NonExistingRuleId() {
|
||||||
|
given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef);
|
||||||
|
given(nodesMock.validateNode(RULE_ID)).willThrow(new EntityNotFoundException(RULE_ID));
|
||||||
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
||||||
|
|
||||||
|
//when
|
||||||
|
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(
|
||||||
|
() -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
|
||||||
|
|
||||||
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
|
then(nodesMock).should().validateNode(RULE_SET_ID);
|
||||||
|
then(nodesMock).should().validateNode(RULE_ID);
|
||||||
|
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
|
||||||
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteRuleById_RuleIdNotInRuleSet() {
|
||||||
|
given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef);
|
||||||
|
given(nodesMock.validateNode(RULE_ID)).willReturn(ruleNodeRef);
|
||||||
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true);
|
||||||
|
given(ruleServiceMock.isRuleAssociatedWithRuleSet(any(), any())).willReturn(false);
|
||||||
|
|
||||||
|
//when
|
||||||
|
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
|
||||||
|
() -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
|
||||||
|
|
||||||
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
|
then(nodesMock).should().validateNode(RULE_SET_ID);
|
||||||
|
then(nodesMock).should().validateNode(RULE_ID);
|
||||||
|
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).should().nodeMatches(eq(ruleNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
|
||||||
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
|
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(ruleNodeRef, ruleSetNodeRef);
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteRuleById_NonExistingRuleSetId() {
|
||||||
|
given(nodesMock.validateNode(RULE_SET_ID)).willThrow(new EntityNotFoundException(RULE_SET_ID));
|
||||||
|
|
||||||
|
//when
|
||||||
|
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(
|
||||||
|
() -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
|
||||||
|
|
||||||
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
|
then(nodesMock).should().validateNode(RULE_SET_ID);
|
||||||
|
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
|
||||||
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteRuleById_RuleSetNotInFolder() {
|
||||||
|
given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef);
|
||||||
|
given(ruleServiceMock.isRuleSetAssociatedWithFolder(any(), any())).willReturn(false);
|
||||||
|
|
||||||
|
//when
|
||||||
|
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
|
||||||
|
() -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
|
||||||
|
|
||||||
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
|
then(nodesMock).should().validateNode(RULE_SET_ID);
|
||||||
|
then(nodesMock).should().nodeMatches(eq(folderNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull());
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
|
||||||
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
|
||||||
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteRuleById_NonExistingFolderId() {
|
||||||
|
given(nodesMock.validateOrLookupNode(FOLDER_NODE_ID, null)).willThrow(new EntityNotFoundException(RULE_ID));
|
||||||
|
|
||||||
|
//when
|
||||||
|
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(
|
||||||
|
() -> rules.deleteRuleById(FOLDER_NODE_ID, RULE_SET_ID, RULE_ID));
|
||||||
|
|
||||||
|
then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null);
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(permissionServiceMock).shouldHaveNoMoreInteractions();
|
||||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -89,4 +89,14 @@ public class NodeRulesRelationTest extends TestCase
|
|||||||
then(rulesMock).should().getRuleById(eq(FOLDER_NODE_ID), eq(RULE_SET_ID), eq(RULE_ID));
|
then(rulesMock).should().getRuleById(eq(FOLDER_NODE_ID), eq(RULE_SET_ID), eq(RULE_ID));
|
||||||
then(rulesMock).shouldHaveNoMoreInteractions();
|
then(rulesMock).shouldHaveNoMoreInteractions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteById() {
|
||||||
|
final Parameters parameters = ParamsExtender.valueOf(null, FOLDER_NODE_ID, RULE_SET_ID, RULE_ID);
|
||||||
|
// when
|
||||||
|
nodeRulesRelation.delete(FOLDER_NODE_ID, RULE_SET_ID, parameters);
|
||||||
|
|
||||||
|
then(rulesMock).should().deleteRuleById(eq(FOLDER_NODE_ID), eq(RULE_SET_ID), eq(RULE_ID));
|
||||||
|
then(rulesMock).shouldHaveNoMoreInteractions();
|
||||||
|
}
|
||||||
}
|
}
|
@@ -732,6 +732,11 @@
|
|||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transform-model</artifactId>
|
<artifactId>alfresco-transform-model</artifactId>
|
||||||
|
@@ -745,62 +745,63 @@ public class RuleServiceImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveRule(NodeRef nodeRef, Rule rule)
|
public Rule saveRule(NodeRef nodeRef, Rule rule)
|
||||||
{
|
{
|
||||||
checkForLinkedRules(nodeRef);
|
checkForLinkedRules(nodeRef);
|
||||||
|
|
||||||
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == AccessStatus.ALLOWED)
|
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) != AccessStatus.ALLOWED)
|
||||||
{
|
|
||||||
disableRules();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (this.nodeService.exists(nodeRef) == false)
|
|
||||||
{
|
|
||||||
throw new RuleServiceException("The node does not exist.");
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeRef ruleNodeRef = rule.getNodeRef();
|
|
||||||
if (ruleNodeRef == null)
|
|
||||||
{
|
|
||||||
if (this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == false)
|
|
||||||
{
|
|
||||||
// Add the actionable aspect
|
|
||||||
this.nodeService.addAspect(nodeRef, RuleModel.ASPECT_RULES, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the action node
|
|
||||||
ruleNodeRef = this.nodeService.createNode(
|
|
||||||
getSavedRuleFolderRef(nodeRef),
|
|
||||||
ContentModel.ASSOC_CONTAINS,
|
|
||||||
QName.createQName(RuleModel.RULE_MODEL_URI, ASSOC_NAME_RULES_PREFIX + GUID.generate()),
|
|
||||||
RuleModel.TYPE_RULE).getChildRef();
|
|
||||||
|
|
||||||
// Set the rule node reference and the owning node reference
|
|
||||||
rule.setNodeRef(ruleNodeRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the properties of the rule
|
|
||||||
this.nodeService.setProperty(ruleNodeRef, ContentModel.PROP_TITLE, rule.getTitle());
|
|
||||||
this.nodeService.setProperty(ruleNodeRef, ContentModel.PROP_DESCRIPTION, rule.getDescription());
|
|
||||||
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_RULE_TYPE, (Serializable)rule.getRuleTypes());
|
|
||||||
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_APPLY_TO_CHILDREN, rule.isAppliedToChildren());
|
|
||||||
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_EXECUTE_ASYNC, rule.getExecuteAsynchronously());
|
|
||||||
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_DISABLED, rule.getRuleDisabled());
|
|
||||||
|
|
||||||
// Save the rule's action
|
|
||||||
saveAction(ruleNodeRef, rule);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
enableRules();
|
|
||||||
// Drop the rules from the cache
|
|
||||||
nodeRulesCache.remove(nodeRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
throw new RuleServiceException("Insufficient permissions to save a rule.");
|
throw new RuleServiceException("Insufficient permissions to save a rule.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disableRules();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (this.nodeService.exists(nodeRef) == false)
|
||||||
|
{
|
||||||
|
throw new RuleServiceException("The node does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef ruleNodeRef = rule.getNodeRef();
|
||||||
|
if (ruleNodeRef == null)
|
||||||
|
{
|
||||||
|
if (this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == false)
|
||||||
|
{
|
||||||
|
// Add the actionable aspect
|
||||||
|
this.nodeService.addAspect(nodeRef, RuleModel.ASPECT_RULES, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the action node
|
||||||
|
ruleNodeRef = this.nodeService.createNode(
|
||||||
|
getSavedRuleFolderRef(nodeRef),
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(RuleModel.RULE_MODEL_URI, ASSOC_NAME_RULES_PREFIX + GUID.generate()),
|
||||||
|
RuleModel.TYPE_RULE).getChildRef();
|
||||||
|
|
||||||
|
// Set the rule node reference and the owning node reference
|
||||||
|
rule.setNodeRef(ruleNodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the properties of the rule
|
||||||
|
String title = rule.getTitle();
|
||||||
|
ParameterCheck.mandatoryString("Rule name", title);
|
||||||
|
this.nodeService.setProperty(ruleNodeRef, ContentModel.PROP_TITLE, title);
|
||||||
|
this.nodeService.setProperty(ruleNodeRef, ContentModel.PROP_DESCRIPTION, rule.getDescription());
|
||||||
|
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_RULE_TYPE, (Serializable)rule.getRuleTypes());
|
||||||
|
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_APPLY_TO_CHILDREN, rule.isAppliedToChildren());
|
||||||
|
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_EXECUTE_ASYNC, rule.getExecuteAsynchronously());
|
||||||
|
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_DISABLED, rule.getRuleDisabled());
|
||||||
|
|
||||||
|
// Save the rule's action
|
||||||
|
saveAction(ruleNodeRef, rule);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
enableRules();
|
||||||
|
// Drop the rules from the cache
|
||||||
|
nodeRulesCache.remove(nodeRef);
|
||||||
|
}
|
||||||
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -901,10 +902,9 @@ public class RuleServiceImpl
|
|||||||
{
|
{
|
||||||
checkForLinkedRules(nodeRef);
|
checkForLinkedRules(nodeRef);
|
||||||
|
|
||||||
if (this.permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == AccessStatus.ALLOWED)
|
if (permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) == AccessStatus.ALLOWED)
|
||||||
{
|
{
|
||||||
if (this.nodeService.exists(nodeRef) == true &&
|
if (nodeService.exists(nodeRef) && nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES))
|
||||||
this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == true)
|
|
||||||
{
|
{
|
||||||
disableRules(nodeRef);
|
disableRules(nodeRef);
|
||||||
try
|
try
|
||||||
@@ -912,7 +912,7 @@ public class RuleServiceImpl
|
|||||||
NodeRef ruleNodeRef = rule.getNodeRef();
|
NodeRef ruleNodeRef = rule.getNodeRef();
|
||||||
if (ruleNodeRef != null)
|
if (ruleNodeRef != null)
|
||||||
{
|
{
|
||||||
this.nodeService.removeChild(getSavedRuleFolderRef(nodeRef), ruleNodeRef);
|
nodeService.removeChild(getSavedRuleFolderRef(nodeRef), ruleNodeRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -935,7 +935,7 @@ public class RuleServiceImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nodeService.removeAspect(nodeRef, RuleModel.ASPECT_RULES);
|
nodeService.removeAspect(nodeRef, RuleModel.ASPECT_RULES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Drop the rules from the cache
|
// Drop the rules from the cache
|
||||||
|
@@ -235,7 +235,7 @@ public interface RuleService
|
|||||||
* @param rule Rule
|
* @param rule Rule
|
||||||
*/
|
*/
|
||||||
@Auditable(parameters = {"nodeRef", "rule"})
|
@Auditable(parameters = {"nodeRef", "rule"})
|
||||||
public void saveRule(NodeRef nodeRef, Rule rule);
|
public Rule saveRule(NodeRef nodeRef, Rule rule);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@@ -73,6 +73,7 @@ import org.junit.runners.Suite;
|
|||||||
org.alfresco.repo.rendition.RenditionNodeManagerTest.class,
|
org.alfresco.repo.rendition.RenditionNodeManagerTest.class,
|
||||||
org.alfresco.repo.rendition.RenditionServiceImplTest.class,
|
org.alfresco.repo.rendition.RenditionServiceImplTest.class,
|
||||||
org.alfresco.repo.replication.ReplicationServiceImplTest.class,
|
org.alfresco.repo.replication.ReplicationServiceImplTest.class,
|
||||||
|
org.alfresco.repo.rule.RuleServiceImplUnitTest.class,
|
||||||
org.alfresco.repo.service.StoreRedirectorProxyFactoryTest.class,
|
org.alfresco.repo.service.StoreRedirectorProxyFactoryTest.class,
|
||||||
org.alfresco.repo.site.RoleComparatorImplTest.class,
|
org.alfresco.repo.site.RoleComparatorImplTest.class,
|
||||||
org.alfresco.repo.tenant.MultiTAdminServiceImplTest.class,
|
org.alfresco.repo.tenant.MultiTAdminServiceImplTest.class,
|
||||||
|
@@ -737,6 +737,7 @@ public class CopyServiceImplTest extends TestCase
|
|||||||
// Create a new rule and add it to the source noderef
|
// Create a new rule and add it to the source noderef
|
||||||
Rule rule = new Rule();
|
Rule rule = new Rule();
|
||||||
rule.setRuleType(RuleType.INBOUND);
|
rule.setRuleType(RuleType.INBOUND);
|
||||||
|
rule.setTitle("Rule name");
|
||||||
|
|
||||||
Map<String, Serializable> props = new HashMap<String, Serializable>(1);
|
Map<String, Serializable> props = new HashMap<String, Serializable>(1);
|
||||||
props.put(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE);
|
props.put(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE);
|
||||||
@@ -1011,6 +1012,7 @@ public class CopyServiceImplTest extends TestCase
|
|||||||
params.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, nodeTwo);
|
params.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, nodeTwo);
|
||||||
Rule rule = new Rule();
|
Rule rule = new Rule();
|
||||||
rule.setRuleType(RuleType.INBOUND);
|
rule.setRuleType(RuleType.INBOUND);
|
||||||
|
rule.setTitle("Rule name");
|
||||||
Action action = actionService.createAction(CopyActionExecuter.NAME, params);
|
Action action = actionService.createAction(CopyActionExecuter.NAME, params);
|
||||||
ActionCondition condition = actionService.createActionCondition(NoConditionEvaluator.NAME);
|
ActionCondition condition = actionService.createActionCondition(NoConditionEvaluator.NAME);
|
||||||
action.addActionCondition(condition);
|
action.addActionCondition(condition);
|
||||||
|
@@ -99,6 +99,7 @@ import org.alfresco.service.namespace.RegexQNamePattern;
|
|||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.test_category.OwnJVMTestsCategory;
|
import org.alfresco.test_category.OwnJVMTestsCategory;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
|
import org.alfresco.util.GUID;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.util.StopWatch;
|
import org.springframework.util.StopWatch;
|
||||||
@@ -195,14 +196,15 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
ContentModel.TYPE_CONTAINER).getChildRef();
|
ContentModel.TYPE_CONTAINER).getChildRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Rule createRule(
|
private Rule createRule(
|
||||||
String ruleTypeName,
|
String ruleTypeName,
|
||||||
String actionName,
|
String actionName,
|
||||||
Map<String, Serializable> actionParams,
|
Map<String, Serializable> actionParams,
|
||||||
String conditionName,
|
String conditionName,
|
||||||
Map<String, Serializable> conditionParams)
|
Map<String, Serializable> conditionParams)
|
||||||
{
|
{
|
||||||
Rule rule = new Rule();
|
Rule rule = new Rule();
|
||||||
|
rule.setTitle(GUID.generate());
|
||||||
rule.setRuleType(ruleTypeName);
|
rule.setRuleType(ruleTypeName);
|
||||||
|
|
||||||
Action action = this.actionService.createAction(actionName, actionParams);
|
Action action = this.actionService.createAction(actionName, actionParams);
|
||||||
@@ -211,7 +213,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
rule.setAction(action);
|
rule.setAction(action);
|
||||||
|
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the categories used in the tests
|
* Create the categories used in the tests
|
||||||
|
@@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.rule;
|
||||||
|
|
||||||
|
import static org.alfresco.model.ContentModel.ASSOC_CONTAINS;
|
||||||
|
import static org.alfresco.repo.rule.RuleModel.ASSOC_ACTION;
|
||||||
|
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.assertThatExceptionOfType;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.ArgumentMatchers.nullable;
|
||||||
|
import static org.mockito.BDDMockito.then;
|
||||||
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.mockito.MockitoAnnotations.openMocks;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.repo.action.RuntimeActionService;
|
||||||
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
|
import org.alfresco.service.cmr.action.Action;
|
||||||
|
import org.alfresco.service.cmr.action.ActionServiceException;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.rule.Rule;
|
||||||
|
import org.alfresco.service.cmr.rule.RuleService;
|
||||||
|
import org.alfresco.service.cmr.rule.RuleServiceException;
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
/** Unit tests for {@link RuleServiceImpl}. */
|
||||||
|
public class RuleServiceImplUnitTest
|
||||||
|
{
|
||||||
|
private static final NodeRef FOLDER_NODE = new NodeRef("folder://node/");
|
||||||
|
private static final NodeRef RULE_SET_NODE = new NodeRef("rule://set/node");
|
||||||
|
private static final NodeRef RULE_NODE = new NodeRef("rule://node/");
|
||||||
|
private static final NodeRef ACTION_NODE = new NodeRef("action://node/");
|
||||||
|
@InjectMocks
|
||||||
|
private RuleService ruleService = new RuleServiceImpl();
|
||||||
|
@Mock
|
||||||
|
private NodeService nodeService;
|
||||||
|
@Mock
|
||||||
|
private PermissionService permissionService;
|
||||||
|
@Mock
|
||||||
|
private SimpleCache nodeRulesCache;
|
||||||
|
@Mock
|
||||||
|
private NodeService runtimeNodeService;
|
||||||
|
@Mock
|
||||||
|
private RuntimeActionService runtimeActionService;
|
||||||
|
@Mock
|
||||||
|
private Rule mockRule;
|
||||||
|
@Mock
|
||||||
|
private Action mockAction;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp()
|
||||||
|
{
|
||||||
|
openMocks(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveRule()
|
||||||
|
{
|
||||||
|
when(permissionService.hasPermission(FOLDER_NODE, PermissionService.CHANGE_PERMISSIONS)).thenReturn(ALLOWED);
|
||||||
|
when(nodeService.exists(FOLDER_NODE)).thenReturn(true);
|
||||||
|
ChildAssociationRef ruleSet = mock(ChildAssociationRef.class);
|
||||||
|
when(ruleSet.getChildRef()).thenReturn(RULE_SET_NODE);
|
||||||
|
when(runtimeNodeService.getChildAssocs(FOLDER_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER)).thenReturn(List.of(ruleSet));
|
||||||
|
ChildAssociationRef ruleAssociation = mock(ChildAssociationRef.class);
|
||||||
|
when(ruleAssociation.getChildRef()).thenReturn(RULE_NODE);
|
||||||
|
when(nodeService.createNode(eq(RULE_SET_NODE), eq(ASSOC_CONTAINS), any(QName.class), eq(TYPE_RULE))).thenReturn(ruleAssociation);
|
||||||
|
// Set the rule title and action.
|
||||||
|
when(mockRule.getTitle()).thenReturn("Rule title");
|
||||||
|
when(mockRule.getAction()).thenReturn(mockAction);
|
||||||
|
when(runtimeActionService.createActionNodeRef(mockAction, RULE_NODE, ASSOC_ACTION, ASSOC_ACTION)).thenReturn(ACTION_NODE);
|
||||||
|
|
||||||
|
// Call the method under test.
|
||||||
|
ruleService.saveRule(FOLDER_NODE, mockRule);
|
||||||
|
|
||||||
|
then(nodeService).should(times(2)).hasAspect(FOLDER_NODE, RuleModel.ASPECT_RULES);
|
||||||
|
then(nodeService).should().exists(FOLDER_NODE);
|
||||||
|
then(nodeService).should().addAspect(FOLDER_NODE, RuleModel.ASPECT_RULES, null);
|
||||||
|
then(nodeService).should().createNode(eq(RULE_SET_NODE), eq(ASSOC_CONTAINS), any(QName.class), eq(TYPE_RULE));
|
||||||
|
then(nodeService).should(atLeastOnce()).setProperty(eq(RULE_NODE), any(QName.class), nullable(Serializable.class));
|
||||||
|
then(nodeService).should().getChildAssocs(RULE_NODE, RuleModel.ASSOC_ACTION, RuleModel.ASSOC_ACTION);
|
||||||
|
verifyNoMoreInteractions(nodeService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveRule_missingAction()
|
||||||
|
{
|
||||||
|
when(permissionService.hasPermission(FOLDER_NODE, PermissionService.CHANGE_PERMISSIONS)).thenReturn(ALLOWED);
|
||||||
|
when(nodeService.exists(FOLDER_NODE)).thenReturn(true);
|
||||||
|
ChildAssociationRef ruleSet = mock(ChildAssociationRef.class);
|
||||||
|
when(ruleSet.getChildRef()).thenReturn(RULE_SET_NODE);
|
||||||
|
when(runtimeNodeService.getChildAssocs(FOLDER_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER)).thenReturn(List.of(ruleSet));
|
||||||
|
ChildAssociationRef ruleAssociation = mock(ChildAssociationRef.class);
|
||||||
|
when(nodeService.createNode(eq(RULE_SET_NODE), eq(ASSOC_CONTAINS), any(QName.class), eq(TYPE_RULE))).thenReturn(ruleAssociation);
|
||||||
|
// Set the title and no action for the rule.
|
||||||
|
when(mockRule.getTitle()).thenReturn("Rule title");
|
||||||
|
when(mockRule.getAction()).thenReturn(null);
|
||||||
|
|
||||||
|
// Call the method under test.
|
||||||
|
assertThatExceptionOfType(RuleServiceException.class).isThrownBy(() -> ruleService.saveRule(FOLDER_NODE, mockRule));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveRule_missingTitle()
|
||||||
|
{
|
||||||
|
when(permissionService.hasPermission(FOLDER_NODE, PermissionService.CHANGE_PERMISSIONS)).thenReturn(ALLOWED);
|
||||||
|
when(nodeService.exists(FOLDER_NODE)).thenReturn(true);
|
||||||
|
ChildAssociationRef ruleSet = mock(ChildAssociationRef.class);
|
||||||
|
when(ruleSet.getChildRef()).thenReturn(RULE_SET_NODE);
|
||||||
|
when(runtimeNodeService.getChildAssocs(FOLDER_NODE, ASSOC_RULE_FOLDER, ASSOC_RULE_FOLDER)).thenReturn(List.of(ruleSet));
|
||||||
|
ChildAssociationRef ruleAssociation = mock(ChildAssociationRef.class);
|
||||||
|
when(nodeService.createNode(eq(RULE_SET_NODE), eq(ASSOC_CONTAINS), any(QName.class), eq(TYPE_RULE))).thenReturn(ruleAssociation);
|
||||||
|
// The rule has an empty title.
|
||||||
|
when(mockRule.getTitle()).thenReturn("");
|
||||||
|
|
||||||
|
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> ruleService.saveRule(FOLDER_NODE, mockRule));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveRule_errorIfFolderHasMultipleRuleSets()
|
||||||
|
{
|
||||||
|
when(permissionService.hasPermission(FOLDER_NODE, PermissionService.CHANGE_PERMISSIONS)).thenReturn(ALLOWED);
|
||||||
|
when(nodeService.exists(FOLDER_NODE)).thenReturn(true);
|
||||||
|
// Simulate a folder node with several rule sets.
|
||||||
|
ChildAssociationRef childA = mock(ChildAssociationRef.class);
|
||||||
|
ChildAssociationRef childB = mock(ChildAssociationRef.class);
|
||||||
|
when(runtimeNodeService.getChildAssocs(
|
||||||
|
FOLDER_NODE,
|
||||||
|
ASSOC_RULE_FOLDER,
|
||||||
|
ASSOC_RULE_FOLDER)).thenReturn(List.of(childA, childB));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ActionServiceException.class).isThrownBy(() -> ruleService.saveRule(FOLDER_NODE, mockRule));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveRule_nodeDoesNotExist()
|
||||||
|
{
|
||||||
|
when(permissionService.hasPermission(FOLDER_NODE, PermissionService.CHANGE_PERMISSIONS)).thenReturn(ALLOWED);
|
||||||
|
when(nodeService.exists(FOLDER_NODE)).thenReturn(false);
|
||||||
|
|
||||||
|
assertThatExceptionOfType(RuleServiceException.class).isThrownBy(() -> ruleService.saveRule(FOLDER_NODE, mockRule));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveRule_accessDenied()
|
||||||
|
{
|
||||||
|
when(permissionService.hasPermission(FOLDER_NODE, PermissionService.CHANGE_PERMISSIONS)).thenReturn(DENIED);
|
||||||
|
|
||||||
|
assertThatExceptionOfType(RuleServiceException.class).isThrownBy(() -> ruleService.saveRule(FOLDER_NODE, mockRule));
|
||||||
|
}
|
||||||
|
}
|
@@ -495,6 +495,7 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
params.put("aspect-name", ContentModel.ASPECT_GEN_CLASSIFIABLE);
|
params.put("aspect-name", ContentModel.ASPECT_GEN_CLASSIFIABLE);
|
||||||
Rule rule = new Rule();
|
Rule rule = new Rule();
|
||||||
rule.setRuleType(RuleType.INBOUND);
|
rule.setRuleType(RuleType.INBOUND);
|
||||||
|
rule.setTitle("Rule name");
|
||||||
Action action = this.actionService.createAction(AddFeaturesActionExecuter.NAME, params);
|
Action action = this.actionService.createAction(AddFeaturesActionExecuter.NAME, params);
|
||||||
ActionCondition condition = this.actionService.createActionCondition(NoConditionEvaluator.NAME, null);
|
ActionCondition condition = this.actionService.createActionCondition(NoConditionEvaluator.NAME, null);
|
||||||
action.addActionCondition(condition);
|
action.addActionCondition(condition);
|
||||||
|
Reference in New Issue
Block a user