From c228bfac1f1797867e767ce74088ff9d347ad6fc Mon Sep 17 00:00:00 2001 From: krdabrowski <98942253+krdabrowski@users.noreply.github.com> Date: Mon, 16 Jan 2023 11:40:37 +0100 Subject: [PATCH] Acs 4400 multiple same categories can be linked from content or folder (#1675) ACS-4400: Multiple same categories can be linked from content or folder --- .../rest/core/assertion/ModelAssertion.java | 16 +++++ .../categories/LinkToCategoriesTests.java | 69 +++++++++++++++++++ .../rest/api/impl/CategoriesImpl.java | 1 + .../rest/api/impl/CategoriesImplTest.java | 20 ++++++ 4 files changed, 106 insertions(+) diff --git a/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/core/assertion/ModelAssertion.java b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/core/assertion/ModelAssertion.java index d6c1407383..4f6331c035 100644 --- a/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/core/assertion/ModelAssertion.java +++ b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/core/assertion/ModelAssertion.java @@ -333,6 +333,22 @@ public class ModelAssertion return (T) model; } + public T containsOnce(String value) + { + final String fieldContent = fieldValue.toString(); + final int i = fieldContent.indexOf(value); + if (i == -1) + { + Assert.fail(errorMessage("does NOT contain at all the expected value: " + value + ", Current Value: " + fieldValue.toString())); + } + if (i != fieldContent.lastIndexOf(value)) + { + Assert.fail(errorMessage("contains more than one expected value: " + value + ", Current Value: " + fieldValue.toString())); + } + + return (T) model; + } + public T notContains(String value) { if (fieldValue.toString().contains(value)) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/LinkToCategoriesTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/LinkToCategoriesTests.java index a47f7e04f9..1831a3949f 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/LinkToCategoriesTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/LinkToCategoriesTests.java @@ -145,6 +145,75 @@ public class LinkToCategoriesTests extends CategoriesRestTest fileNode.assertThat().field(PROPERTIES_FIELD).contains(secondCategory.getId()); } + /** + * Try to link file to three categories, two of which are the same, and expect two distinct categories in output. + */ + @Test(groups = { TestGroup.REST_API}) + public void testLinkContentToCategory_withRepeatedCategory() + { + STEP("Check if file is not linked to any category"); + RestNodeModel fileNode = restClient.authenticateUser(user).withCoreAPI().usingNode(file).getNode(); + + fileNode.assertThat().field(ASPECTS_FIELD).notContains("cm:generalclassifiable"); + fileNode.assertThat().field(PROPERTIES_FIELD).notContains("cm:categories"); + + STEP("Link content to three (one repeated) categories and expect 201"); + final RestCategoryModel secondCategory = prepareCategoryUnderRoot(); + final List categoryLinkModels = List.of( + createCategoryLinkModelWithId(category.getId()), + createCategoryLinkModelWithId(secondCategory.getId()), + createCategoryLinkModelWithId(category.getId()) + ); + final RestCategoryModelsCollection linkedCategories = restClient.authenticateUser(user).withCoreAPI().usingNode(file).linkToCategories(categoryLinkModels); + + restClient.assertStatusCodeIs(CREATED); + linkedCategories.assertThat().entriesListCountIs(2); + linkedCategories.getEntries().get(0).onModel().assertThat().isEqualTo(category); + linkedCategories.getEntries().get(1).onModel().assertThat().isEqualTo(secondCategory); + + STEP("Verify if repeated category was ignored and only two categories are present in file metadata"); + fileNode = restClient.authenticateUser(user).withCoreAPI().usingNode(file).getNode(); + + fileNode.assertThat().field(PROPERTIES_FIELD).containsOnce(category.getId()); + fileNode.assertThat().field(PROPERTIES_FIELD).containsOnce(secondCategory.getId()); + } + + /** + * Try to link file to already linked category and expect distinct categories in response. + */ + @Test(groups = { TestGroup.REST_API}) + public void testLinkContentToCategory_usingAlreadyLinkedCategory() + { + STEP("Create second category under root"); + final RestCategoryModel secondCategory = prepareCategoryUnderRoot(); + + STEP("Link file to one category"); + final RestCategoryLinkBodyModel categoryLinkModel = createCategoryLinkModelWithId(category.getId()); + restClient.authenticateUser(user).withCoreAPI().usingNode(file).linkToCategory(categoryLinkModel); + RestNodeModel fileNode = restClient.authenticateUser(user).withCoreAPI().usingNode(file).getNode(); + + fileNode.assertThat().field(PROPERTIES_FIELD).containsOnce(category.getId()); + fileNode.assertThat().field(PROPERTIES_FIELD).notContains(secondCategory.getId()); + + STEP("Link content to two categories using one already linked before to and expect 201"); + final List categoryLinkModels = List.of( + createCategoryLinkModelWithId(category.getId()), + createCategoryLinkModelWithId(secondCategory.getId()) + ); + final RestCategoryModelsCollection linkedCategories = restClient.authenticateUser(user).withCoreAPI().usingNode(file).linkToCategories(categoryLinkModels); + + restClient.assertStatusCodeIs(CREATED); + linkedCategories.assertThat().entriesListCountIs(2); + linkedCategories.getEntries().get(0).onModel().assertThat().isEqualTo(category); + linkedCategories.getEntries().get(1).onModel().assertThat().isEqualTo(secondCategory); + + STEP("Verify if repeated category was ignored and only two categories are present in file metadata"); + fileNode = restClient.authenticateUser(user).withCoreAPI().usingNode(file).getNode(); + + fileNode.assertThat().field(PROPERTIES_FIELD).containsOnce(category.getId()); + fileNode.assertThat().field(PROPERTIES_FIELD).containsOnce(secondCategory.getId()); + } + /** * Link content, which already has some linked category to new ones and verify if all categories are present in node's properties */ diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java index 7c753a4b6a..2c45c7b79c 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java @@ -193,6 +193,7 @@ public class CategoriesImpl implements Categories .filter(Objects::nonNull) .map(Category::getId) .filter(StringUtils::isNotEmpty) + .distinct() .map(this::getCategoryNodeRef) .collect(Collectors.toList()); diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java index ab919462e2..b788a26021 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java @@ -1000,6 +1000,26 @@ public class CategoriesImplTest .hasMessageContaining(NOT_A_VALID_CATEGORY); } + @Test + public void testLinkNodeToCategories_withTwoIdenticalCategories() + { + final List categoryLinks = List.of(CATEGORY, CATEGORY); + final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID); + final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF); + given(nodesMock.getNode(any())).willReturn(prepareCategoryNode()); + given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); + + // when + final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks); + + final Map expectedProperties = Map.of(ContentModel.PROP_CATEGORIES, (Serializable) List.of(CATEGORY_NODE_REF)); + then(nodeServiceMock).should().addAspect(CONTENT_NODE_REF, ContentModel.ASPECT_GEN_CLASSIFIABLE, expectedProperties); + final List expectedLinkedCategories = List.of(CATEGORY); + assertThat(actualLinkedCategories) + .isNotNull().usingRecursiveComparison() + .isEqualTo(expectedLinkedCategories); + } + @Test public void testListCategoriesForNode() {