From 7b4f7c9174e8367416ae89b1f3330853341ff194 Mon Sep 17 00:00:00 2001 From: Maciej Pichura <41297682+mpichura@users.noreply.github.com> Date: Fri, 29 Jul 2022 14:29:56 +0200 Subject: [PATCH] ACS-3345 e2e REST API TAS tests delete rule (#1256) * ACS-3345: REST API TAS tests for delete rule. * ACS-3345: REST API TAS tests for delete rule. * ACS-3345: REST API TAS tests for delete rule. * ACS-3345: Fixing the naming. * ACS-3345: REST API TAS tests for delete rule. --- .../alfresco/rest/rules/DeleteRulesTests.java | 257 ++++++++++++++++++ .../alfresco/rest/rules/GetRulesTests.java | 13 +- .../org/alfresco/rest/api/impl/RulesImpl.java | 9 +- .../alfresco/rest/api/impl/RulesImplTest.java | 15 + 4 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/DeleteRulesTests.java diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/DeleteRulesTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/DeleteRulesTests.java new file mode 100644 index 0000000000..151e6dea1b --- /dev/null +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/DeleteRulesTests.java @@ -0,0 +1,257 @@ +/* + * #%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 . + * #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.constants.UserRole.SiteContributor; +import static org.alfresco.utility.constants.UserRole.SiteManager; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.NO_CONTENT; +import static org.springframework.http.HttpStatus.OK; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +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.junit.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Tests for DELETE /nodes/{nodeId}/rule-sets/{ruleSetId}/rules/{ruleId}. + */ +@Test(groups = {TestGroup.RULES}) +public class DeleteRulesTests extends RestTest +{ + private static final String FAKE_NODE_REF = "fake-node-id"; + + private UserModel user; + private SiteModel site; + + @BeforeClass(alwaysRun = true) + public void dataPreparation() + { + STEP("Create a Contributor user and a public site"); + user = dataUser.createRandomTestUser(); + user.setUserRole(SiteContributor); + site = dataSite.usingUser(user).createPublicRandomSite(); + } + + /** + * Delete previously created rule by its id (as Contributor). + */ + @Test(groups = {TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY}) + public void deleteSingleRuleAndGet204() + { + STEP("Create a few rules in the folder"); + final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder(); + final List createdRules = Stream.of("ruleA", "ruleB", "ruleC") + .map(ruleName -> { + RestRuleModel ruleModel = new RestRuleModel(); + ruleModel.setName(ruleName); + return restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet() + .createSingleRule(ruleModel); + }) + .collect(toList()); + + STEP("Attempt delete one rule"); + final RestRuleModel ruleA = createdRules.get(0); + restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().deleteRule(ruleA.getId()); + restClient.assertStatusCodeIs(NO_CONTENT); + + STEP("Get and check the rules from the folder after deleting one of them"); + final RestRuleModelsCollection rulesAfterDeletion = + restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().getListOfRules(); + restClient.assertStatusCodeIs(OK); + rulesAfterDeletion.assertThat().entriesListCountIs(createdRules.size() - 1); + Assert.assertTrue(rulesAfterDeletion.getEntries() + .stream() + .noneMatch(r -> r.onModel().getId().equals(ruleA.getId())) + ); + final Set ruleIdsThatShouldBeLeft = createdRules.stream() + .filter(r -> !r.getName().equals("ruleA")) + .map(RestRuleModel::getId) + .collect(Collectors.toSet()); + final Set ruleIdsAfterDeletion = rulesAfterDeletion.getEntries().stream() + .map(r -> r.onModel().getId()) + .collect(Collectors.toSet()); + Assert.assertEquals(ruleIdsThatShouldBeLeft, ruleIdsAfterDeletion); + } + + /** + * Try to delete a rule in a non-existing folder and get 404. + */ + @Test(groups = {TestGroup.REST_API, TestGroup.RULES}) + public void deleteRuleInNonExistingFolderAndGet404() + { + final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder(); + final RestRuleModel testRule = createRule(ruleFolder); + + STEP("Create a non-existing folder model"); + final FolderModel nonExistingFolder = new FolderModel(); + nonExistingFolder.setNodeRef(FAKE_NODE_REF); + + STEP("Attempt delete the rule in non-existing folder"); + restClient.authenticateUser(user).withCoreAPI().usingNode(nonExistingFolder).usingDefaultRuleSet().deleteRule(testRule.getId()); + + restClient.assertLastError().statusCodeIs(NOT_FOUND); + } + + /** + * Try to delete a rule in a non-existing rule set and get 404. + */ + @Test(groups = {TestGroup.REST_API, TestGroup.RULES}) + public void deleteRuleInNonExistingRuleSetAndGet404() + { + final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder(); + final RestRuleModel testRule = createRule(ruleFolder); + + STEP("Attempt delete the rule in non-existing rule set"); + restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingRuleSet(FAKE_NODE_REF).deleteRule(testRule.getId()); + + restClient.assertLastError().statusCodeIs(NOT_FOUND); + } + + /** + * Try to delete a non-existing rule and get 404. + */ + @Test(groups = {TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY}) + public void deleteNonExistingRuleAndGet404() + { + final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder(); + STEP("Attempt delete non-existing rule"); + restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().deleteRule(FAKE_NODE_REF); + + restClient.assertLastError().statusCodeIs(NOT_FOUND); + } + + /** + * Try to delete an existing rule passing a wrong but existing folder and get 404. + */ + @Test(groups = {TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY}) + public void deleteExistingRuleFromWrongFolderAndGet404() + { + final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder(); + final RestRuleModel testRule = createRule(ruleFolder); + + STEP("Create a second folder in the site"); + final FolderModel anotherFolder = dataContent.usingUser(user).usingSite(site).createFolder(); + + STEP("Attempt delete an existing rule from a wrong but existing (second) folder"); + restClient.authenticateUser(user).withCoreAPI().usingNode(anotherFolder).usingDefaultRuleSet().deleteRule(testRule.getId()); + + restClient.assertLastError().statusCodeIs(NOT_FOUND); + } + + /** + * Check that a user without write permission on folder cannot delete a rule inside it. + */ + public void deleteSinglePrivateRuleWithoutPermissionAndGet403() + { + STEP("Create a user and use them to create a private site containing a folder with a rule"); + final UserModel privateUser = dataUser.createRandomTestUser(); + final SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite(); + final FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder(); + final RestRuleModel ruleModel = new RestRuleModel(); + ruleModel.setName("Private site rule"); + final RestRuleModel createdRule = + restClient.authenticateUser(privateUser).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet() + .createSingleRule(ruleModel); + + STEP("Try to delete the rule with another user"); + restClient.authenticateUser(user).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet().deleteRule(createdRule.getId()); + + restClient.assertLastError().statusCodeIs(FORBIDDEN); + } + + /** + * Check that a user with SiteCollaborator permissions on folder can delete a rule inside it. + */ + public void deleteSinglePublicRuleAsCollaboratorAndGet403() + { + STEP("Create a user and use them to create a private site containing a folder with a rule"); + final FolderModel ruleFolder = dataContent.usingUser(user).usingSite(site).createFolder(); + final RestRuleModel testRule = createRule(ruleFolder); + + STEP("Create a manager in the private site"); + final UserModel siteCollaborator = dataUser.createRandomTestUser(); + siteCollaborator.setUserRole(SiteCollaborator); + restClient.authenticateUser(user).withCoreAPI().usingSite(site).addPerson(siteCollaborator); + + STEP("Check the manager can delete the rule"); + restClient.authenticateUser(siteCollaborator).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet() + .deleteRule(testRule.getId()); + + restClient.assertLastError().statusCodeIs(FORBIDDEN); + } + + /** + * Check that a user with SiteManager permissions on folder can delete a rule inside it. + */ + public void deleteSinglePrivateRuleAsSiteManagerAndGet204() + { + STEP("Create a user and use them to create a private site containing a folder with a rule"); + final UserModel privateUser = dataUser.createRandomTestUser(); + final SiteModel privateSite = dataSite.usingUser(privateUser).createPrivateRandomSite(); + final FolderModel privateFolder = dataContent.usingUser(privateUser).usingSite(privateSite).createFolder(); + final RestRuleModel ruleModel = new RestRuleModel(); + ruleModel.setName("Private site rule"); + final RestRuleModel createdRule = + restClient.authenticateUser(privateUser).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet() + .createSingleRule(ruleModel); + + STEP("Create a manager in the private site"); + final UserModel siteManager = dataUser.createRandomTestUser(); + siteManager.setUserRole(SiteManager); + restClient.authenticateUser(privateUser).withCoreAPI().usingSite(privateSite).addPerson(siteManager); + + STEP("Check the manager can delete the rule"); + restClient.authenticateUser(siteManager).withCoreAPI().usingNode(privateFolder).usingDefaultRuleSet() + .deleteRule(createdRule.getId()); + + restClient.assertStatusCodeIs(NO_CONTENT); + } + + private RestRuleModel createRule(FolderModel ruleFolder) + { + STEP("Create a rule in the folder"); + final RestRuleModel ruleModel = new RestRuleModel(); + ruleModel.setName("Test rule"); + return restClient.authenticateUser(user).withCoreAPI().usingNode(ruleFolder).usingDefaultRuleSet().createSingleRule(ruleModel); + } +} diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRulesTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRulesTests.java index 65e5ea40ad..b255a36d68 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRulesTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRulesTests.java @@ -87,7 +87,7 @@ public class GetRulesTests extends RestTest STEP("Get the rules that apply to the folder"); RestRuleModelsCollection rules = restClient.authenticateUser(user).withCoreAPI().usingNode(folder).usingDefaultRuleSet().getListOfRules(); - restClient.assertStatusCodeIs(OK); + restClient.assertStatusCodeIs(NOT_FOUND); assertTrue("Expected no rules to be present.", rules.isEmpty()); } @@ -163,6 +163,17 @@ public class GetRulesTests extends RestTest restClient.assertStatusCodeIs(NOT_FOUND); } + /** Check we get a 404 if trying to load an existing rule providing a wrong but existing folder */ + @Test (groups = { TestGroup.REST_API, TestGroup.RULES }) + public void getSingleRuleFromWrongFolder() + { + STEP("Create a folder in existing site"); + FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder(); + STEP("Try to load a rule for a wrong but existing folder."); + restClient.authenticateUser(user).withCoreAPI().usingNode(folder).usingDefaultRuleSet().getSingleRule(createdRuleA.getId()); + restClient.assertStatusCodeIs(NOT_FOUND); + } + /** Check that a user without read permission cannot view the folder rules. */ public void requireReadPermissionToGetRule() { diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/RulesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/RulesImpl.java index f029e58de0..bf59e496e0 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/RulesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/RulesImpl.java @@ -41,6 +41,7 @@ import org.alfresco.rest.api.model.rules.Rule; import org.alfresco.rest.api.model.rules.RuleSet; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; +import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.ListPage; import org.alfresco.rest.framework.resource.parameters.Paging; @@ -183,7 +184,13 @@ public class RulesImpl implements Rules { if (RuleSet.isDefaultId(ruleSetId)) { - return ruleService.getRuleSetNode(associatedFolderNodeRef); + final NodeRef ruleSetNodeRef = ruleService.getRuleSetNode(associatedFolderNodeRef); + if (ruleSetNodeRef == null) + { + //folder doesn't have a -default- rule set + throw new RelationshipResourceNotFoundException(associatedFolderNodeRef.getId(), ruleSetId); + } + return ruleSetNodeRef; } final NodeRef ruleSetNodeRef = validateNode(ruleSetId, ContentModel.TYPE_SYSTEM_FOLDER, RULE_SET_EXPECTED_TYPE_NAME); diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java index f538b8e3bd..db64a7d9f1 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java @@ -53,6 +53,7 @@ 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.PermissionDeniedException; +import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.service.Experimental; @@ -196,6 +197,20 @@ public class RulesImplTest extends TestCase then(ruleServiceMock).shouldHaveNoInteractions(); } + @Test + public void testGetRulesForNotExistingDefaultRuleSetNode() + { + given(nodesMock.nodeMatches(eq(folderNodeRef), any(), any())).willReturn(true); + given(ruleServiceMock.getRuleSetNode(folderNodeRef)).willReturn(null); + + // when + assertThatExceptionOfType(RelationshipResourceNotFoundException.class).isThrownBy( + () -> rules.getRules(FOLDER_NODE_ID, DEFAULT_ID, paging)); + + then(ruleServiceMock).should().getRuleSetNode(folderNodeRef); + then(ruleServiceMock).shouldHaveNoMoreInteractions(); + } + @Test public void testGetRulesForNotAssociatedRuleSetToFolder() {