From f1561504cd2d621c446696236cd222b1552bd65a Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Wed, 29 Mar 2023 16:22:48 +0200 Subject: [PATCH 01/21] ACS-4966 Add option to include path while fetching Categories --- .../rest/api/impl/CategoriesImpl.java | 34 +++++++++++++++---- .../org/alfresco/rest/api/model/Category.java | 24 +++++++++++-- 2 files changed, 49 insertions(+), 9 deletions(-) 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 53f9eddab8..5e25f27ed4 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 @@ -69,6 +69,7 @@ import org.apache.commons.lang3.StringUtils; public class CategoriesImpl implements Categories { static final String INCLUDE_COUNT_PARAM = "count"; + static final String INCLUDE_PATH_PARAM = "path"; static final String NOT_A_VALID_CATEGORY = "Node id does not refer to a valid category"; static final String NO_PERMISSION_TO_MANAGE_A_CATEGORY = "Current user does not have permission to manage a category"; static final String NO_PERMISSION_TO_READ_CONTENT = "Current user does not have read permission to content"; @@ -111,6 +112,11 @@ public class CategoriesImpl implements Categories category.setCount(categoriesCount.getOrDefault(category.getId(), 0)); } + if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + { + category.setPath(nodeService.getPath(nodeRef).toDisplayPath(nodeService, permissionService)); + } + return category; } @@ -136,11 +142,18 @@ public class CategoriesImpl implements Categories public List getCategoryChildren(final StoreRef storeRef, final String parentCategoryId, final Parameters parameters) { final NodeRef parentNodeRef = getCategoryNodeRef(storeRef, parentCategoryId); - final List categories = nodeService.getChildAssocs(parentNodeRef).stream() - .filter(ca -> ContentModel.ASSOC_SUBCATEGORIES.equals(ca.getTypeQName())) - .map(ChildAssociationRef::getChildRef) - .map(this::mapToCategory) - .collect(Collectors.toList()); + final List categories = nodeService.getChildAssocs(parentNodeRef) + .stream() + .filter(ca -> ContentModel.ASSOC_SUBCATEGORIES.equals(ca.getTypeQName())) + .map(ChildAssociationRef::getChildRef) + .map(this::mapToCategory) + .peek(category -> { + if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + { + category.setPath(nodeService.getPath(nodes.getNode(category.getId()).getNodeRef()).toDisplayPath(nodeService, permissionService)); + } + }) + .collect(Collectors.toList()); if (parameters.getInclude().contains(INCLUDE_COUNT_PARAM)) { @@ -200,7 +213,16 @@ public class CategoriesImpl implements Categories } final Collection actualCategories = DefaultTypeConverter.INSTANCE.getCollection(NodeRef.class, currentCategories); - return actualCategories.stream().map(this::mapToCategory).collect(Collectors.toList()); + return actualCategories + .stream() + .map(this::mapToCategory) + .peek(category -> { + if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + { + category.setPath(nodeService.getPath(nodes.getNode(category.getId()).getNodeRef()).toDisplayPath(nodeService, permissionService)); + } + }) + .collect(Collectors.toList()); } @Override diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/Category.java b/remote-api/src/main/java/org/alfresco/rest/api/model/Category.java index 812d362a96..d65b22b8a8 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/model/Category.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/Category.java @@ -35,6 +35,7 @@ public class Category private String parentId; private boolean hasChildren; private Integer count; + private String path; public String getId() { @@ -91,6 +92,14 @@ public class Category this.count = count; } + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + @Override public boolean equals(Object o) { @@ -100,19 +109,20 @@ public class Category return false; Category category = (Category) o; return hasChildren == category.hasChildren && Objects.equals(id, category.id) && Objects.equals(name, category.name) && Objects.equals(parentId, category.parentId) - && Objects.equals(count, category.count); + && Objects.equals(count, category.count) && Objects.equals(path, category.path); } @Override public int hashCode() { - return Objects.hash(id, name, parentId, hasChildren, count); + return Objects.hash(id, name, parentId, hasChildren, count, path); } @Override public String toString() { - return "Category{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", parentId='" + parentId + '\'' + ", hasChildren=" + hasChildren + ", count=" + count + '}'; + return "Category{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", parentId='" + parentId + '\'' + ", hasChildren=" + hasChildren + + ", count=" + count + ", path=" + path + '}'; } public static Builder builder() @@ -127,6 +137,7 @@ public class Category private String parentId; private boolean hasChildren; private Integer count; + private String path; public Builder id(String id) { @@ -158,6 +169,12 @@ public class Category return this; } + public Builder path(String path) + { + this.path = path; + return this; + } + public Category create() { final Category category = new Category(); @@ -166,6 +183,7 @@ public class Category category.setParentId(parentId); category.setHasChildren(hasChildren); category.setCount(count); + category.setPath(path); return category; } } From 5f5c377532aee61b54334c3402ae60582bf48b00 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Mon, 3 Apr 2023 10:12:54 +0200 Subject: [PATCH 02/21] ACS-4966 Add option to include path for other endpoints, add unit tests covering path param --- .../rest/api/impl/CategoriesImpl.java | 20 +- .../rest/api/impl/CategoriesImplTest.java | 174 ++++++++++++++++++ 2 files changed, 193 insertions(+), 1 deletion(-) 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 5e25f27ed4..efa17be46e 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 @@ -134,6 +134,10 @@ public class CategoriesImpl implements Categories { category.setCount(0); } + if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + { + category.setPath(nodeService.getPath(nodes.getNode(category.getId()).getNodeRef()).toDisplayPath(nodeService, permissionService)); + } }) .collect(Collectors.toList()); } @@ -183,6 +187,11 @@ public class CategoriesImpl implements Categories category.setCount(categoriesCount.getOrDefault(category.getId(), 0)); } + if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + { + category.setPath(nodeService.getPath(categoryNodeRef).toDisplayPath(nodeService, permissionService)); + } + return category; } @@ -252,7 +261,16 @@ public class CategoriesImpl implements Categories linkNodeToCategories(contentNodeRef, categoryNodeRefs); - return categoryNodeRefs.stream().map(this::mapToCategory).collect(Collectors.toList()); + return categoryNodeRefs + .stream() + .map(this::mapToCategory) + .peek(category -> { + if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + { + category.setPath(nodeService.getPath(nodes.getNode(category.getId()).getNodeRef()).toDisplayPath(nodeService, permissionService)); + } + }) + .collect(Collectors.toList()); } @Override 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 6d9dc98410..4d9a48f91c 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 @@ -28,6 +28,7 @@ package org.alfresco.rest.api.impl; import static org.alfresco.rest.api.Nodes.PATH_ROOT; import static org.alfresco.rest.api.impl.CategoriesImpl.INCLUDE_COUNT_PARAM; +import static org.alfresco.rest.api.impl.CategoriesImpl.INCLUDE_PATH_PARAM; import static org.alfresco.rest.api.impl.CategoriesImpl.INVALID_NODE_TYPE; import static org.alfresco.rest.api.impl.CategoriesImpl.NOT_A_VALID_CATEGORY; import static org.alfresco.rest.api.impl.CategoriesImpl.NOT_NULL_OR_EMPTY; @@ -71,6 +72,7 @@ import org.alfresco.rest.framework.resource.parameters.Parameters; 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.repository.Path; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.CategoryService; import org.alfresco.service.cmr.security.AccessStatus; @@ -252,6 +254,28 @@ public class CategoriesImplTest .isEqualTo(1); } + @Test + public void testGetCategoryById_includePath() + { + final QName categoryQName = createCmQNameOf(CATEGORY_NAME); + final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); + final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName); + Path mockPath = new Path(); + given(nodesMock.getNode(any())).willReturn(createNode()); + given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); + given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(nodeServiceMock.getPath(CATEGORY_NODE_REF)).willReturn(mockPath); + + // when + final Category actualCategory = objectUnderTest.getCategoryById(CATEGORY_ID, parametersMock); + + assertThat(actualCategory) + .isNotNull() + .extracting(Category::getPath) + .isNotNull() + .isEqualTo(""); + } + @Test public void testGetCategoryById_notACategory() { @@ -479,6 +503,37 @@ public class CategoriesImplTest .isEqualTo(0); } + @Test + public void testCreateCategory_includePath() + { + final QName categoryQName = createCmQNameOf(CATEGORY_NAME); + final NodeRef categoryNodeRef = createNodeRefWithId(CATEGORY_ID); + final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); + final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName); + final Path mockPath = new Path(); + given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef); + given(categoryServiceMock.createCategory(parentCategoryNodeRef, CATEGORY_NAME)).willReturn(categoryNodeRef); + given(nodesMock.getNode(any())).willReturn(createNode()); + given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); + given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(nodeServiceMock.getPath(any())).willReturn(mockPath); + final List categoryModels = new ArrayList<>(prepareCategories()); + + // when + final List actualCreatedCategories = objectUnderTest.createSubcategories(PARENT_ID, categoryModels, parametersMock); + + then(categoryServiceMock).should().createCategory(any(), any()); + then(categoryServiceMock).shouldHaveNoMoreInteractions(); + + assertThat(actualCreatedCategories) + .isNotNull() + .hasSize(1) + .element(0) + .extracting(Category::getPath) + .isNotNull() + .isEqualTo(""); + } + @Test public void testCreateCategories_noPermissions() { @@ -628,6 +683,31 @@ public class CategoriesImplTest .isEqualTo(List.of(0, 2, 0)); } + @Test + public void testGetCategoryChildren_includePath() + { + final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); + given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef); + given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true); + final int childrenCount = 3; + final List childAssociationRefMocks = prepareChildAssocMocks(childrenCount, parentCategoryNodeRef); + final Path mockPath = new Path(); + given(nodeServiceMock.getChildAssocs(parentCategoryNodeRef)).willReturn(childAssociationRefMocks); + childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks); + given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(nodeServiceMock.getPath(any())).willReturn(mockPath); + + // when + final List actualCategoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock); + + assertThat(actualCategoryChildren) + .isNotNull() + .hasSize(3) + .extracting(Category::getPath) + .isNotNull() + .isEqualTo(List.of("", "", "")); + } + @Test public void testGetCategoryChildren_noChildren() { @@ -751,6 +831,32 @@ public class CategoriesImplTest .isEqualTo(1); } + @Test + public void testUpdateCategoryById_includePath() + { + final String categoryNewName = "categoryNewName"; + final Category fixedCategory = createCategoryOnlyWithName(categoryNewName); + fixedCategory.setPath("/test/TestCat"); + final QName categoryQName = createCmQNameOf(CATEGORY_NAME); + final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); + final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName); + final Path mockPath = new Path(); + given(nodesMock.getNode(any())).willReturn(createNode(categoryNewName)); + given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); + given(nodeServiceMock.moveNode(any(), any(), any(), any())).willReturn(createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, createCmQNameOf(categoryNewName))); + given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(nodeServiceMock.getPath(CATEGORY_NODE_REF)).willReturn(mockPath); + + // when + final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, fixedCategory, parametersMock); + + assertThat(actualCategory) + .isNotNull() + .extracting(Category::getPath) + .isNotNull() + .isEqualTo(""); + } + @Test public void testUpdateCategoryById_noPermission() { @@ -918,6 +1024,7 @@ public class CategoriesImplTest then(nodeServiceMock).should().getParentAssocs(categoryParentNodeRef); then(nodeServiceMock).shouldHaveNoMoreInteractions(); final List expectedLinkedCategories = List.of(CATEGORY); + expectedLinkedCategories.get(0).setPath(null); assertThat(actualLinkedCategories) .isNotNull().usingRecursiveComparison() .isEqualTo(expectedLinkedCategories); @@ -984,6 +1091,37 @@ public class CategoriesImplTest .isEqualTo(expectedLinkedCategories); } + @Test + public void testLinkNodeToCategories_includePath() + { + final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID); + final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF); + final Path mockPath = new Path(); + given(nodesMock.getNode(any())).willReturn(createNode()); + given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); + given(nodeServiceMock.hasAspect(any(), any())).willReturn(true); + given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(nodeServiceMock.getPath(any())).willReturn(mockPath); + + // when + final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock); + + then(nodesMock).should(times(2)).getNode(CATEGORY_ID); + then(nodeServiceMock).should().getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false); + then(nodeServiceMock).should().getPrimaryParent(CATEGORY_NODE_REF); + then(nodeServiceMock).should().getParentAssocs(CATEGORY_NODE_REF); + then(nodeServiceMock).should().hasAspect(CONTENT_NODE_REF, ContentModel.ASPECT_GEN_CLASSIFIABLE); + then(nodeServiceMock).should().getProperty(CONTENT_NODE_REF, ContentModel.PROP_CATEGORIES); + final Serializable expectedCategories = (Serializable) List.of(CATEGORY_NODE_REF); + then(nodeServiceMock).should().setProperty(CONTENT_NODE_REF, ContentModel.PROP_CATEGORIES, expectedCategories); + then(nodeServiceMock).should().getParentAssocs(categoryParentNodeRef); + final List expectedLinkedCategories = List.of(CATEGORY); + expectedLinkedCategories.get(0).setPath(""); + assertThat(actualLinkedCategories) + .isNotNull().usingRecursiveComparison() + .isEqualTo(expectedLinkedCategories); + } + @Test public void testLinkNodeToCategories_withPreviouslyLinkedCategories() { @@ -1168,11 +1306,47 @@ public class CategoriesImplTest then(nodeServiceMock).should().getParentAssocs(categoryParentNodeRef); then(nodeServiceMock).shouldHaveNoMoreInteractions(); final List expectedCategories = List.of(CATEGORY); + expectedCategories.get(0).setPath(null); assertThat(actualCategories) .isNotNull().usingRecursiveComparison() .isEqualTo(expectedCategories); } + @Test + public void testListCategoriesForNode_includePath() + { + final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID); + final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF); + final Path mockPath = new Path(); + given(nodeServiceMock.getProperty(any(), eq(ContentModel.PROP_CATEGORIES))).willReturn((Serializable) List.of(CATEGORY_NODE_REF)); + given(nodesMock.getNode(any())).willReturn(createNode()); + given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); + given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(nodeServiceMock.getPath(any())).willReturn(mockPath); + + // when + final List actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock); + + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID); + then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF); + then(permissionServiceMock).shouldHaveNoMoreInteractions(); + then(typeConstraint).should().matches(CONTENT_NODE_REF); + then(typeConstraint).shouldHaveNoMoreInteractions(); + then(nodesMock).should(times(2)).getNode(CATEGORY_ID); + then(nodesMock).shouldHaveNoMoreInteractions(); + then(nodeServiceMock).should().getProperty(CONTENT_NODE_REF, ContentModel.PROP_CATEGORIES); + then(nodeServiceMock).should().getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false); + then(nodeServiceMock).should().getPrimaryParent(CATEGORY_NODE_REF); + then(nodeServiceMock).should().getParentAssocs(categoryParentNodeRef); + then(nodeServiceMock).should().getPath(any()); + then(nodeServiceMock).shouldHaveNoMoreInteractions(); + final List expectedCategories = List.of(CATEGORY); + expectedCategories.get(0).setPath(""); + assertThat(actualCategories) + .isNotNull().usingRecursiveComparison() + .isEqualTo(expectedCategories); + } + @Test public void testListCategoriesForNode_withInvalidNodeId() { From 444de08f91485cbf7c677e1c0fd10dbb3c20b51d Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Mon, 3 Apr 2023 12:08:12 +0200 Subject: [PATCH 03/21] ACS-4966 Add REST tests --- .../rest/categories/CategoriesPathTests.java | 194 ++++++++++++++++++ .../rest/categories/CategoriesRestTest.java | 2 + 2 files changed, 196 insertions(+) create mode 100644 packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java new file mode 100644 index 0000000000..17fa3ad940 --- /dev/null +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -0,0 +1,194 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2023 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.categories; + +import static org.alfresco.utility.data.RandomData.getRandomName; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.OK; +import static org.testng.Assert.assertTrue; + +import org.alfresco.dataprep.CMISUtil; +import org.alfresco.rest.model.RestCategoryModel; +import org.alfresco.rest.model.RestCategoryModelsCollection; +import org.alfresco.utility.Utility; +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.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class CategoriesPathTests extends CategoriesRestTest +{ + private RestCategoryModel category; + + @BeforeClass(alwaysRun = true) + public void dataPreparation() throws Exception + { + STEP("Create user and site"); + user = dataUser.createRandomTestUser(); + SiteModel site = dataSite.usingUser(user).createPublicRandomSite(); + + STEP("Create a folder, file in it and few categories"); + FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder(); + FileModel file = dataContent.usingUser(user).usingResource(folder).createContent(CMISUtil.DocumentType.TEXT_PLAIN); + category = prepareCategoryUnderRoot(); + + STEP("Wait for indexing to complete"); + Utility.sleep(1000, 60000, () -> restClient.authenticateUser(user) + .withCoreAPI() + .usingCategory(category) + .include(INCLUDE_PATH_PARAM) + .getCategory() + .assertThat() + .field(FIELD_PATH) + .isNotNull()); + } + + /** + * Verify path for a category linked with file and folder. + */ + @Test(groups = { TestGroup.REST_API }) + public void testGetCategoryById_includePath() + { + STEP("Get linked category and verify if path is not null"); + final RestCategoryModel actualCategory = restClient.authenticateUser(user) + .withCoreAPI() + .usingCategory(category) + .include(INCLUDE_PATH_PARAM) + .getCategory(); + + restClient.assertStatusCodeIs(OK); + actualCategory.assertThat().field(FIELD_ID).is(category.getId()); + actualCategory.assertThat().field(FIELD_PATH).is(""); + } + + /** + * Verify path for three categories: linked with file, linked with folder and third not linked to any content. + */ + @Test(groups = { TestGroup.REST_API }) + public void testGetCategories_includePath() + { + STEP("Get few categories and verify its paths"); + final RestCategoryModel parentCategory = createCategoryModelWithId(ROOT_CATEGORY_ID); + final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user) + .withCoreAPI() + .usingCategory(parentCategory) + .include(INCLUDE_PATH_PARAM) + .getCategoryChildren(); + + restClient.assertStatusCodeIs(OK); + assertTrue(actualCategories.getEntries().stream() + .map(RestCategoryModel::onModel) + .anyMatch(category -> category.getId().equals(category.getId()) && category.getPath().equals(""))); + } + + /** + * Create category and verify that it has a path. + */ + @Test(groups = { TestGroup.REST_API }) + public void testCreateCategory_includingPath() + { + STEP("Create a category under root and verify if path is not null"); + final String categoryName = getRandomName("Category"); + final RestCategoryModel rootCategory = createCategoryModelWithId(ROOT_CATEGORY_ID); + final RestCategoryModel aCategory = createCategoryModelWithName(categoryName); + final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser()) + .withCoreAPI() + .include(INCLUDE_PATH_PARAM) + .usingCategory(rootCategory) + .createSingleCategory(aCategory); + + STEP("Create a category under root category (as admin)"); + restClient.assertStatusCodeIs(CREATED); + createdCategory.assertThat().field(FIELD_NAME).is(categoryName); + createdCategory.assertThat().field(FIELD_PATH).is(""); + } + + /** + * Update category linked to file and folder and verify that it has a path. + */ + @Test(groups = { TestGroup.REST_API }) + public void testUpdateCategory_includePath() + { + STEP("Update linked category and verify if path is not null"); + final String categoryNewName = getRandomName("NewCategoryName"); + final RestCategoryModel fixedCategoryModel = createCategoryModelWithName(categoryNewName); + final RestCategoryModel updatedCategory = restClient.authenticateUser(dataUser.getAdminUser()) + .withCoreAPI() + .usingCategory(category) + .include(INCLUDE_PATH_PARAM) + .updateCategory(fixedCategoryModel); + + restClient.assertStatusCodeIs(OK); + updatedCategory.assertThat().field(FIELD_ID).is(category.getId()); + updatedCategory.assertThat().field(FIELD_PATH).is(""); + } + + /** + * Link node to categories and verify that they have path. + */ + @Test(groups = { TestGroup.REST_API }) + public void testLinkNodeToCategories_includePath() + { + STEP("Link node to categories and verify if path is not null"); + final RestCategoryLinkBodyModel categoryLinkModel = createCategoryLinkModelWithId(category.getId()); + final RestCategoryModel linkedCategory = restClient.authenticateUser(dataUser.getAdminUser()) + .withCoreAPI() + .usingNode(file) + .linkToCategory(categoryLinkModel); + + restClient.assertStatusCodeIs(CREATED); + linkedCategory.assertThat().field(FIELD_ID).is(category.getId()); + linkedCategory.assertThat().field(FIELD_PATH).is(""); + } + + /** + * List categories for given node and verify that they have a path. + */ + @Test(groups = { TestGroup.REST_API }) + public void testListCategoriesForNode_includePath() + { + STEP("Link file to category"); + final RestCategoryLinkBodyModel categoryLink = createCategoryLinkModelWithId(category.getId()); + final RestCategoryModel linkedCategory = restClient.authenticateUser(dataUser.getAdminUser()) + .withCoreAPI() + .usingNode(file) + .linkToCategory(categoryLink); + + STEP("Get linked category and verify if path is not null"); + final RestCategoryModelsCollection linkedCategories = restClient.authenticateUser(dataUser.getAdminUser()) + .withCoreAPI() + .usingNode(file) + .getLinkedCategories(); + + restClient.assertStatusCodeIs(OK); + linkedCategories.assertThat().entriesListCountIs(1); + linkedCategories.getEntries().get(0).onModel().assertThat().isEqualTo(linkedCategory); + } +} diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesRestTest.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesRestTest.java index c98c9802f7..792cec4b3e 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesRestTest.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesRestTest.java @@ -46,6 +46,7 @@ import org.testng.annotations.BeforeClass; abstract class CategoriesRestTest extends RestTest { protected static final String INCLUDE_COUNT_PARAM = "count"; + protected static final String INCLUDE_PATH_PARAM = "path"; protected static final String ROOT_CATEGORY_ID = "-root-"; protected static final String CATEGORY_NAME_PREFIX = "CategoryName"; protected static final String FIELD_NAME = "name"; @@ -53,6 +54,7 @@ abstract class CategoriesRestTest extends RestTest protected static final String FIELD_PARENT_ID = "parentId"; protected static final String FIELD_HAS_CHILDREN = "hasChildren"; protected static final String FIELD_COUNT = "count"; + protected static final String FIELD_PATH = "path"; protected UserModel user; From 13e3369a7f66ad2f2f921d0f25a713b106b82532 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Mon, 3 Apr 2023 13:12:51 +0200 Subject: [PATCH 04/21] ACS-4966 Add path to RestCategoryModel, fix path tests --- .../org/alfresco/rest/model/RestCategoryModel.java | 14 ++++++++++++++ .../rest/categories/CategoriesPathTests.java | 10 ++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestCategoryModel.java b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestCategoryModel.java index e25c56e22a..337c11f2da 100644 --- a/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestCategoryModel.java +++ b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestCategoryModel.java @@ -52,6 +52,11 @@ This must be unique within the parent category. */ private long count; + /** + The path to this category. + */ + private String path; + public String getId() { return this.id; @@ -102,6 +107,14 @@ This must be unique within the parent category. this.count = count; } + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + @Override public boolean equals(Object o) { @@ -126,6 +139,7 @@ This must be unique within the parent category. ", parentId='" + parentId + '\'' + ", hasChildren=" + hasChildren + ", count=" + count + + ", path=" + path + '}'; } diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index 17fa3ad940..4fffbc5382 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -33,6 +33,7 @@ import static org.springframework.http.HttpStatus.OK; import static org.testng.Assert.assertTrue; import org.alfresco.dataprep.CMISUtil; +import org.alfresco.rest.model.RestCategoryLinkBodyModel; import org.alfresco.rest.model.RestCategoryModel; import org.alfresco.rest.model.RestCategoryModelsCollection; import org.alfresco.utility.Utility; @@ -45,6 +46,7 @@ import org.testng.annotations.Test; public class CategoriesPathTests extends CategoriesRestTest { + private FileModel file; private RestCategoryModel category; @BeforeClass(alwaysRun = true) @@ -56,7 +58,7 @@ public class CategoriesPathTests extends CategoriesRestTest STEP("Create a folder, file in it and few categories"); FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder(); - FileModel file = dataContent.usingUser(user).usingResource(folder).createContent(CMISUtil.DocumentType.TEXT_PLAIN); + file = dataContent.usingUser(user).usingResource(folder).createContent(CMISUtil.DocumentType.TEXT_PLAIN); category = prepareCategoryUnderRoot(); STEP("Wait for indexing to complete"); @@ -71,7 +73,7 @@ public class CategoriesPathTests extends CategoriesRestTest } /** - * Verify path for a category linked with file and folder. + * Verify path for a category got by ID. */ @Test(groups = { TestGroup.REST_API }) public void testGetCategoryById_includePath() @@ -89,7 +91,7 @@ public class CategoriesPathTests extends CategoriesRestTest } /** - * Verify path for three categories: linked with file, linked with folder and third not linked to any content. + * Verify path for category. */ @Test(groups = { TestGroup.REST_API }) public void testGetCategories_includePath() @@ -131,7 +133,7 @@ public class CategoriesPathTests extends CategoriesRestTest } /** - * Update category linked to file and folder and verify that it has a path. + * Update category and verify that it has a path. */ @Test(groups = { TestGroup.REST_API }) public void testUpdateCategory_includePath() From 72a573c090defbbe196f3577a56cec244590cdb6 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Mon, 3 Apr 2023 15:45:59 +0200 Subject: [PATCH 05/21] ACS-4966 Rest tests expect correct path --- .../rest/categories/CategoriesPathTests.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index 4fffbc5382..ed9b29c986 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -56,7 +56,7 @@ public class CategoriesPathTests extends CategoriesRestTest user = dataUser.createRandomTestUser(); SiteModel site = dataSite.usingUser(user).createPublicRandomSite(); - STEP("Create a folder, file in it and few categories"); + STEP("Create a folder, file in it and a category"); FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder(); file = dataContent.usingUser(user).usingResource(folder).createContent(CMISUtil.DocumentType.TEXT_PLAIN); category = prepareCategoryUnderRoot(); @@ -78,7 +78,7 @@ public class CategoriesPathTests extends CategoriesRestTest @Test(groups = { TestGroup.REST_API }) public void testGetCategoryById_includePath() { - STEP("Get linked category and verify if path is not null"); + STEP("Get category and verify if path is a general path for categories"); final RestCategoryModel actualCategory = restClient.authenticateUser(user) .withCoreAPI() .usingCategory(category) @@ -87,7 +87,7 @@ public class CategoriesPathTests extends CategoriesRestTest restClient.assertStatusCodeIs(OK); actualCategory.assertThat().field(FIELD_ID).is(category.getId()); - actualCategory.assertThat().field(FIELD_PATH).is(""); + actualCategory.assertThat().field(FIELD_PATH).is("/categories/General"); } /** @@ -98,6 +98,7 @@ public class CategoriesPathTests extends CategoriesRestTest { STEP("Get few categories and verify its paths"); final RestCategoryModel parentCategory = createCategoryModelWithId(ROOT_CATEGORY_ID); + final anotherCategory = prepareCategoryUnderRoot(); final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user) .withCoreAPI() .usingCategory(parentCategory) @@ -116,7 +117,7 @@ public class CategoriesPathTests extends CategoriesRestTest @Test(groups = { TestGroup.REST_API }) public void testCreateCategory_includingPath() { - STEP("Create a category under root and verify if path is not null"); + STEP("Create a category under root and verify if path is a general path for categories"); final String categoryName = getRandomName("Category"); final RestCategoryModel rootCategory = createCategoryModelWithId(ROOT_CATEGORY_ID); final RestCategoryModel aCategory = createCategoryModelWithName(categoryName); @@ -126,10 +127,9 @@ public class CategoriesPathTests extends CategoriesRestTest .usingCategory(rootCategory) .createSingleCategory(aCategory); - STEP("Create a category under root category (as admin)"); restClient.assertStatusCodeIs(CREATED); createdCategory.assertThat().field(FIELD_NAME).is(categoryName); - createdCategory.assertThat().field(FIELD_PATH).is(""); + createdCategory.assertThat().field(FIELD_PATH).is("/categories/General"); } /** @@ -138,7 +138,7 @@ public class CategoriesPathTests extends CategoriesRestTest @Test(groups = { TestGroup.REST_API }) public void testUpdateCategory_includePath() { - STEP("Update linked category and verify if path is not null"); + STEP("Update linked category and verify if path is a general path for categories"); final String categoryNewName = getRandomName("NewCategoryName"); final RestCategoryModel fixedCategoryModel = createCategoryModelWithName(categoryNewName); final RestCategoryModel updatedCategory = restClient.authenticateUser(dataUser.getAdminUser()) @@ -149,7 +149,7 @@ public class CategoriesPathTests extends CategoriesRestTest restClient.assertStatusCodeIs(OK); updatedCategory.assertThat().field(FIELD_ID).is(category.getId()); - updatedCategory.assertThat().field(FIELD_PATH).is(""); + updatedCategory.assertThat().field(FIELD_PATH).is("/categories/General"); } /** @@ -158,16 +158,17 @@ public class CategoriesPathTests extends CategoriesRestTest @Test(groups = { TestGroup.REST_API }) public void testLinkNodeToCategories_includePath() { - STEP("Link node to categories and verify if path is not null"); + STEP("Link node to categories and verify if path is a general path"); final RestCategoryLinkBodyModel categoryLinkModel = createCategoryLinkModelWithId(category.getId()); final RestCategoryModel linkedCategory = restClient.authenticateUser(dataUser.getAdminUser()) .withCoreAPI() .usingNode(file) + .include(INCLUDE_PATH_PARAM) .linkToCategory(categoryLinkModel); restClient.assertStatusCodeIs(CREATED); linkedCategory.assertThat().field(FIELD_ID).is(category.getId()); - linkedCategory.assertThat().field(FIELD_PATH).is(""); + linkedCategory.assertThat().field(FIELD_PATH).is("/categories/General"); } /** @@ -181,16 +182,19 @@ public class CategoriesPathTests extends CategoriesRestTest final RestCategoryModel linkedCategory = restClient.authenticateUser(dataUser.getAdminUser()) .withCoreAPI() .usingNode(file) + .include(INCLUDE_PATH_PARAM) .linkToCategory(categoryLink); - STEP("Get linked category and verify if path is not null"); + STEP("Get linked category and verify if path is a general path"); final RestCategoryModelsCollection linkedCategories = restClient.authenticateUser(dataUser.getAdminUser()) .withCoreAPI() .usingNode(file) + .include(INCLUDE_PATH_PARAM) .getLinkedCategories(); restClient.assertStatusCodeIs(OK); linkedCategories.assertThat().entriesListCountIs(1); - linkedCategories.getEntries().get(0).onModel().assertThat().isEqualTo(linkedCategory); + linkedCategories.getEntries().get(0).onModel().assertThat().field(FIELD_ID).is(category.getId()); + linkedCategories.getEntries().get(0).onModel().assertThat().field(FIELD_PATH).is("/categories/General"); } } From eb6157ed2a5a97683e1be4f3bc5e4489fc08ec70 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Mon, 3 Apr 2023 15:55:06 +0200 Subject: [PATCH 06/21] ACS-4966 Move category creation to data preparation step --- .../java/org/alfresco/rest/categories/CategoriesPathTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index ed9b29c986..3aae91442a 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -48,6 +48,7 @@ public class CategoriesPathTests extends CategoriesRestTest { private FileModel file; private RestCategoryModel category; + private RestCategoryModel anotherCategory; @BeforeClass(alwaysRun = true) public void dataPreparation() throws Exception @@ -60,6 +61,7 @@ public class CategoriesPathTests extends CategoriesRestTest FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder(); file = dataContent.usingUser(user).usingResource(folder).createContent(CMISUtil.DocumentType.TEXT_PLAIN); category = prepareCategoryUnderRoot(); + anotherCategory = prepareCategoryUnderRoot(); STEP("Wait for indexing to complete"); Utility.sleep(1000, 60000, () -> restClient.authenticateUser(user) @@ -98,7 +100,6 @@ public class CategoriesPathTests extends CategoriesRestTest { STEP("Get few categories and verify its paths"); final RestCategoryModel parentCategory = createCategoryModelWithId(ROOT_CATEGORY_ID); - final anotherCategory = prepareCategoryUnderRoot(); final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user) .withCoreAPI() .usingCategory(parentCategory) From 0612d74c688f14c130ebfd31296d70b4274d4121 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Mon, 3 Apr 2023 16:46:22 +0200 Subject: [PATCH 07/21] ACS-4966 Correct path check --- .../java/org/alfresco/rest/categories/CategoriesPathTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index 3aae91442a..02311753b3 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -109,7 +109,7 @@ public class CategoriesPathTests extends CategoriesRestTest restClient.assertStatusCodeIs(OK); assertTrue(actualCategories.getEntries().stream() .map(RestCategoryModel::onModel) - .anyMatch(category -> category.getId().equals(category.getId()) && category.getPath().equals(""))); + .allMatch(cat -> cat.getPath().equals("/categories/General"))); } /** From 3dec621b1595e816b25de08e94e94adc6dd7c2b9 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Thu, 13 Apr 2023 09:19:05 +0200 Subject: [PATCH 08/21] ACS-4966 Correct path in unit tests, cover child category case --- .../rest/categories/CategoriesPathTests.java | 24 ++++++- .../rest/api/impl/CategoriesImpl.java | 37 +++++++---- .../rest/api/impl/CategoriesImplTest.java | 63 ++++++++++++++----- 3 files changed, 93 insertions(+), 31 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index 02311753b3..e958f893ec 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -53,8 +53,7 @@ public class CategoriesPathTests extends CategoriesRestTest @BeforeClass(alwaysRun = true) public void dataPreparation() throws Exception { - STEP("Create user and site"); - user = dataUser.createRandomTestUser(); + STEP("Create site"); SiteModel site = dataSite.usingUser(user).createPublicRandomSite(); STEP("Create a folder, file in it and a category"); @@ -112,6 +111,27 @@ public class CategoriesPathTests extends CategoriesRestTest .allMatch(cat -> cat.getPath().equals("/categories/General"))); } + /** + * Verify path for child category. + */ + @Test(groups = { TestGroup.REST_API }) + public void testGetChildCategory_includePath() + { + STEP("Create parent and child categories and verify if child path contains parent name"); + final RestCategoryModel parentCategory = createCategoryModelWithId(ROOT_CATEGORY_ID); + final RestCategoryModel childCategory = prepareCategoriesUnder(parentCategory, 2); + final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user) + .withCoreAPI() + .usingCategory(parentCategory) + .include(INCLUDE_PATH_PARAM) + .getCategoryChildren(); + + restClient.assertStatusCodeIs(OK); + assertTrue(actualCategories.getEntries().stream() + .map(RestCategoryModel::onModel) + .allMatch(cat -> cat.getPath().equals("/categories/General/" + parentCategory.getName()))); + } + /** * Create category and verify that it has a path. */ 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 efa17be46e..c733d71ab1 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 @@ -69,7 +69,6 @@ import org.apache.commons.lang3.StringUtils; public class CategoriesImpl implements Categories { static final String INCLUDE_COUNT_PARAM = "count"; - static final String INCLUDE_PATH_PARAM = "path"; static final String NOT_A_VALID_CATEGORY = "Node id does not refer to a valid category"; static final String NO_PERMISSION_TO_MANAGE_A_CATEGORY = "Current user does not have permission to manage a category"; static final String NO_PERMISSION_TO_READ_CONTENT = "Current user does not have read permission to content"; @@ -112,9 +111,9 @@ public class CategoriesImpl implements Categories category.setCount(categoriesCount.getOrDefault(category.getId(), 0)); } - if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH)) { - category.setPath(nodeService.getPath(nodeRef).toDisplayPath(nodeService, permissionService)); + category.setPath(getCategoryPath(category)); } return category; @@ -134,9 +133,9 @@ public class CategoriesImpl implements Categories { category.setCount(0); } - if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH)) { - category.setPath(nodeService.getPath(nodes.getNode(category.getId()).getNodeRef()).toDisplayPath(nodeService, permissionService)); + category.setPath(getCategoryPath(category)); } }) .collect(Collectors.toList()); @@ -152,9 +151,9 @@ public class CategoriesImpl implements Categories .map(ChildAssociationRef::getChildRef) .map(this::mapToCategory) .peek(category -> { - if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH)) { - category.setPath(nodeService.getPath(nodes.getNode(category.getId()).getNodeRef()).toDisplayPath(nodeService, permissionService)); + category.setPath(getCategoryPath(category)); } }) .collect(Collectors.toList()); @@ -187,9 +186,9 @@ public class CategoriesImpl implements Categories category.setCount(categoriesCount.getOrDefault(category.getId(), 0)); } - if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH)) { - category.setPath(nodeService.getPath(categoryNodeRef).toDisplayPath(nodeService, permissionService)); + category.setPath(getCategoryPath(category)); } return category; @@ -226,9 +225,9 @@ public class CategoriesImpl implements Categories .stream() .map(this::mapToCategory) .peek(category -> { - if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH)) { - category.setPath(nodeService.getPath(nodes.getNode(category.getId()).getNodeRef()).toDisplayPath(nodeService, permissionService)); + category.setPath(getCategoryPath(category)); } }) .collect(Collectors.toList()); @@ -265,9 +264,9 @@ public class CategoriesImpl implements Categories .stream() .map(this::mapToCategory) .peek(category -> { - if (parameters.getInclude().contains(INCLUDE_PATH_PARAM)) + if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH)) { - category.setPath(nodeService.getPath(nodes.getNode(category.getId()).getNodeRef()).toDisplayPath(nodeService, permissionService)); + category.setPath(getCategoryPath(category)); } }) .collect(Collectors.toList()); @@ -515,4 +514,16 @@ public class CategoriesImpl implements Categories .stream() .collect(Collectors.toMap(pair -> pair.getFirst().toString().replace(idPrefix, StringUtils.EMPTY), Pair::getSecond)); } + + /** + * Get path for a given category in human-readable form. + * + * @param category Category to provide path for. + * @return Path for a category in human-readable form. + */ + private String getCategoryPath(final Category category) + { + final NodeRef categoryNodeRef = nodes.getNode(category.getId()).getNodeRef(); + return nodeService.getPath(categoryNodeRef).toDisplayPath(nodeService, permissionService); + } } 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 4d9a48f91c..9b748d1bb5 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 @@ -28,7 +28,6 @@ package org.alfresco.rest.api.impl; import static org.alfresco.rest.api.Nodes.PATH_ROOT; import static org.alfresco.rest.api.impl.CategoriesImpl.INCLUDE_COUNT_PARAM; -import static org.alfresco.rest.api.impl.CategoriesImpl.INCLUDE_PATH_PARAM; import static org.alfresco.rest.api.impl.CategoriesImpl.INVALID_NODE_TYPE; import static org.alfresco.rest.api.impl.CategoriesImpl.NOT_A_VALID_CATEGORY; import static org.alfresco.rest.api.impl.CategoriesImpl.NOT_NULL_OR_EMPTY; @@ -61,6 +60,7 @@ import java.util.stream.IntStream; import java.util.stream.Stream; import org.alfresco.model.ContentModel; +import org.alfresco.repo.transfer.PathHelper; import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.model.Category; import org.alfresco.rest.api.model.Node; @@ -260,11 +260,16 @@ public class CategoriesImplTest final QName categoryQName = createCmQNameOf(CATEGORY_NAME); final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName); - Path mockPath = new Path(); + final Path mockPath = new Path(); + final String mockRootLevel = "/{mockRootLevel}"; + final String mockChildLevel = "/{mockChild}"; + mockPath.append(PathHelper.stringToPath(mockRootLevel)); + mockPath.append(PathHelper.stringToPath(mockChildLevel)); + mockPath.append(PathHelper.stringToPath("/")); given(nodesMock.getNode(any())).willReturn(createNode()); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); - given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); - given(nodeServiceMock.getPath(CATEGORY_NODE_REF)).willReturn(mockPath); + given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); + given(nodeServiceMock.getPath(any())).willReturn(mockPath); // when final Category actualCategory = objectUnderTest.getCategoryById(CATEGORY_ID, parametersMock); @@ -273,7 +278,7 @@ public class CategoriesImplTest .isNotNull() .extracting(Category::getPath) .isNotNull() - .isEqualTo(""); + .isEqualTo("//" + mockRootLevel + "//" + mockChildLevel); } @Test @@ -511,11 +516,16 @@ public class CategoriesImplTest final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName); final Path mockPath = new Path(); + final String mockRootLevel = "/{mockRootLevel}"; + final String mockChildLevel = "/{mockChild}"; + mockPath.append(PathHelper.stringToPath(mockRootLevel)); + mockPath.append(PathHelper.stringToPath(mockChildLevel)); + mockPath.append(PathHelper.stringToPath("/")); given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef); given(categoryServiceMock.createCategory(parentCategoryNodeRef, CATEGORY_NAME)).willReturn(categoryNodeRef); given(nodesMock.getNode(any())).willReturn(createNode()); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); - given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); given(nodeServiceMock.getPath(any())).willReturn(mockPath); final List categoryModels = new ArrayList<>(prepareCategories()); @@ -531,7 +541,7 @@ public class CategoriesImplTest .element(0) .extracting(Category::getPath) .isNotNull() - .isEqualTo(""); + .isEqualTo("//" + mockRootLevel + "//" + mockChildLevel); } @Test @@ -692,9 +702,15 @@ public class CategoriesImplTest final int childrenCount = 3; final List childAssociationRefMocks = prepareChildAssocMocks(childrenCount, parentCategoryNodeRef); final Path mockPath = new Path(); + final String mockRootLevel = "/{mockRootLevel}"; + final String mockChildLevel = "/{mockChild}"; + mockPath.append(PathHelper.stringToPath(mockRootLevel)); + mockPath.append(PathHelper.stringToPath(mockChildLevel)); + mockPath.append(PathHelper.stringToPath("/")); + final String resultPath = "//" + mockRootLevel + "//" + mockChildLevel; given(nodeServiceMock.getChildAssocs(parentCategoryNodeRef)).willReturn(childAssociationRefMocks); childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks); - given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); given(nodeServiceMock.getPath(any())).willReturn(mockPath); // when @@ -705,7 +721,7 @@ public class CategoriesImplTest .hasSize(3) .extracting(Category::getPath) .isNotNull() - .isEqualTo(List.of("", "", "")); + .isEqualTo(List.of(resultPath, resultPath, resultPath)); } @Test @@ -841,11 +857,16 @@ public class CategoriesImplTest final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName); final Path mockPath = new Path(); + final String mockRootLevel = "/{mockRootLevel}"; + final String mockChildLevel = "/{mockChild}"; + mockPath.append(PathHelper.stringToPath(mockRootLevel)); + mockPath.append(PathHelper.stringToPath(mockChildLevel)); + mockPath.append(PathHelper.stringToPath("/")); given(nodesMock.getNode(any())).willReturn(createNode(categoryNewName)); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); given(nodeServiceMock.moveNode(any(), any(), any(), any())).willReturn(createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, createCmQNameOf(categoryNewName))); - given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); - given(nodeServiceMock.getPath(CATEGORY_NODE_REF)).willReturn(mockPath); + given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); + given(nodeServiceMock.getPath(any())).willReturn(mockPath); // when final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, fixedCategory, parametersMock); @@ -854,7 +875,7 @@ public class CategoriesImplTest .isNotNull() .extracting(Category::getPath) .isNotNull() - .isEqualTo(""); + .isEqualTo("//" + mockRootLevel + "//" + mockChildLevel); } @Test @@ -1097,10 +1118,15 @@ public class CategoriesImplTest final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF); final Path mockPath = new Path(); + final String mockRootLevel = "/{mockRootLevel}"; + final String mockChildLevel = "/{mockChild}"; + mockPath.append(PathHelper.stringToPath(mockRootLevel)); + mockPath.append(PathHelper.stringToPath(mockChildLevel)); + mockPath.append(PathHelper.stringToPath("/")); given(nodesMock.getNode(any())).willReturn(createNode()); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); given(nodeServiceMock.hasAspect(any(), any())).willReturn(true); - given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); given(nodeServiceMock.getPath(any())).willReturn(mockPath); // when @@ -1116,7 +1142,7 @@ public class CategoriesImplTest then(nodeServiceMock).should().setProperty(CONTENT_NODE_REF, ContentModel.PROP_CATEGORIES, expectedCategories); then(nodeServiceMock).should().getParentAssocs(categoryParentNodeRef); final List expectedLinkedCategories = List.of(CATEGORY); - expectedLinkedCategories.get(0).setPath(""); + expectedLinkedCategories.get(0).setPath("//" + mockRootLevel + "//" + mockChildLevel); assertThat(actualLinkedCategories) .isNotNull().usingRecursiveComparison() .isEqualTo(expectedLinkedCategories); @@ -1318,10 +1344,15 @@ public class CategoriesImplTest final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF); final Path mockPath = new Path(); + final String mockRootLevel = "/{mockRootLevel}"; + final String mockChildLevel = "/{mockChild}"; + mockPath.append(PathHelper.stringToPath(mockRootLevel)); + mockPath.append(PathHelper.stringToPath(mockChildLevel)); + mockPath.append(PathHelper.stringToPath("/")); given(nodeServiceMock.getProperty(any(), eq(ContentModel.PROP_CATEGORIES))).willReturn((Serializable) List.of(CATEGORY_NODE_REF)); given(nodesMock.getNode(any())).willReturn(createNode()); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); - given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_PATH_PARAM)); + given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); given(nodeServiceMock.getPath(any())).willReturn(mockPath); // when @@ -1341,7 +1372,7 @@ public class CategoriesImplTest then(nodeServiceMock).should().getPath(any()); then(nodeServiceMock).shouldHaveNoMoreInteractions(); final List expectedCategories = List.of(CATEGORY); - expectedCategories.get(0).setPath(""); + expectedCategories.get(0).setPath("//" + mockRootLevel + "//" + mockChildLevel); assertThat(actualCategories) .isNotNull().usingRecursiveComparison() .isEqualTo(expectedCategories); From 8586d22b95ce392203296f26201a9d0b53d7039f Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Thu, 13 Apr 2023 09:28:23 +0200 Subject: [PATCH 09/21] ACS-4966 Correct categories creation --- .../java/org/alfresco/rest/categories/CategoriesPathTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index e958f893ec..23e45fc5dc 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -119,7 +119,7 @@ public class CategoriesPathTests extends CategoriesRestTest { STEP("Create parent and child categories and verify if child path contains parent name"); final RestCategoryModel parentCategory = createCategoryModelWithId(ROOT_CATEGORY_ID); - final RestCategoryModel childCategory = prepareCategoriesUnder(parentCategory, 2); + final List childCategories = prepareCategoriesUnder(parentCategory.getId(), 2); final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user) .withCoreAPI() .usingCategory(parentCategory) From e048278a2718463fcd82dda6c07b8e8c04c8949a Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Thu, 13 Apr 2023 09:38:01 +0200 Subject: [PATCH 10/21] ACS-4966 Missing import --- .../java/org/alfresco/rest/categories/CategoriesPathTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index 23e45fc5dc..e398726ce0 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -32,6 +32,8 @@ import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.OK; import static org.testng.Assert.assertTrue; +import java.util.List; + import org.alfresco.dataprep.CMISUtil; import org.alfresco.rest.model.RestCategoryLinkBodyModel; import org.alfresco.rest.model.RestCategoryModel; From baccde2663d5a2bb43aae7557d642041a849f73a Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Thu, 13 Apr 2023 10:23:32 +0200 Subject: [PATCH 11/21] ACS-4966 Restore user creation --- .../java/org/alfresco/rest/categories/CategoriesPathTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index e398726ce0..03ee0fdf95 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -55,7 +55,8 @@ public class CategoriesPathTests extends CategoriesRestTest @BeforeClass(alwaysRun = true) public void dataPreparation() throws Exception { - STEP("Create site"); + STEP("Create user and site"); + user = dataUser.createRandomTestUser(); SiteModel site = dataSite.usingUser(user).createPublicRandomSite(); STEP("Create a folder, file in it and a category"); From b0f767c1aef9bf4e4c8a2639f617558e80b434dd Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Thu, 13 Apr 2023 12:40:35 +0200 Subject: [PATCH 12/21] ACS-4966 CR fixes --- .../rest/categories/CategoriesPathTests.java | 1 + .../rest/api/impl/CategoriesImplTest.java | 73 ++++++------------- 2 files changed, 25 insertions(+), 49 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index 03ee0fdf95..ef343895d5 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -53,6 +53,7 @@ public class CategoriesPathTests extends CategoriesRestTest private RestCategoryModel anotherCategory; @BeforeClass(alwaysRun = true) + @Override public void dataPreparation() throws Exception { STEP("Create user and site"); 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 9b748d1bb5..296a768fc3 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 @@ -102,6 +102,9 @@ public class CategoriesImplTest private static final Category CATEGORY = createDefaultCategory(); private static final String CONTENT_NODE_ID = "content-node-id"; private static final NodeRef CONTENT_NODE_REF = createNodeRefWithId(CONTENT_NODE_ID); + private static final String MOCK_ROOT_LEVEL = "/{mockRootLevel}"; + private static final String MOCK_CHILD_LEVEL = "/{mockChild}"; + private static final String MOCK_CATEGORY_PATH = "//" + MOCK_ROOT_LEVEL + "//" + MOCK_CHILD_LEVEL; @Mock private Nodes nodesMock; @@ -260,16 +263,10 @@ public class CategoriesImplTest final QName categoryQName = createCmQNameOf(CATEGORY_NAME); final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName); - final Path mockPath = new Path(); - final String mockRootLevel = "/{mockRootLevel}"; - final String mockChildLevel = "/{mockChild}"; - mockPath.append(PathHelper.stringToPath(mockRootLevel)); - mockPath.append(PathHelper.stringToPath(mockChildLevel)); - mockPath.append(PathHelper.stringToPath("/")); given(nodesMock.getNode(any())).willReturn(createNode()); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); - given(nodeServiceMock.getPath(any())).willReturn(mockPath); + given(nodeServiceMock.getPath(any())).willReturn(mockCategoryPath()); // when final Category actualCategory = objectUnderTest.getCategoryById(CATEGORY_ID, parametersMock); @@ -278,7 +275,7 @@ public class CategoriesImplTest .isNotNull() .extracting(Category::getPath) .isNotNull() - .isEqualTo("//" + mockRootLevel + "//" + mockChildLevel); + .isEqualTo(MOCK_CATEGORY_PATH); } @Test @@ -515,18 +512,12 @@ public class CategoriesImplTest final NodeRef categoryNodeRef = createNodeRefWithId(CATEGORY_ID); final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName); - final Path mockPath = new Path(); - final String mockRootLevel = "/{mockRootLevel}"; - final String mockChildLevel = "/{mockChild}"; - mockPath.append(PathHelper.stringToPath(mockRootLevel)); - mockPath.append(PathHelper.stringToPath(mockChildLevel)); - mockPath.append(PathHelper.stringToPath("/")); given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef); given(categoryServiceMock.createCategory(parentCategoryNodeRef, CATEGORY_NAME)).willReturn(categoryNodeRef); given(nodesMock.getNode(any())).willReturn(createNode()); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); - given(nodeServiceMock.getPath(any())).willReturn(mockPath); + given(nodeServiceMock.getPath(any())).willReturn(mockCategoryPath()); final List categoryModels = new ArrayList<>(prepareCategories()); // when @@ -541,7 +532,7 @@ public class CategoriesImplTest .element(0) .extracting(Category::getPath) .isNotNull() - .isEqualTo("//" + mockRootLevel + "//" + mockChildLevel); + .isEqualTo(MOCK_CATEGORY_PATH); } @Test @@ -701,17 +692,10 @@ public class CategoriesImplTest given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true); final int childrenCount = 3; final List childAssociationRefMocks = prepareChildAssocMocks(childrenCount, parentCategoryNodeRef); - final Path mockPath = new Path(); - final String mockRootLevel = "/{mockRootLevel}"; - final String mockChildLevel = "/{mockChild}"; - mockPath.append(PathHelper.stringToPath(mockRootLevel)); - mockPath.append(PathHelper.stringToPath(mockChildLevel)); - mockPath.append(PathHelper.stringToPath("/")); - final String resultPath = "//" + mockRootLevel + "//" + mockChildLevel; given(nodeServiceMock.getChildAssocs(parentCategoryNodeRef)).willReturn(childAssociationRefMocks); childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks); given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); - given(nodeServiceMock.getPath(any())).willReturn(mockPath); + given(nodeServiceMock.getPath(any())).willReturn(mockCategoryPath()); // when final List actualCategoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock); @@ -721,7 +705,7 @@ public class CategoriesImplTest .hasSize(3) .extracting(Category::getPath) .isNotNull() - .isEqualTo(List.of(resultPath, resultPath, resultPath)); + .isEqualTo(List.of(MOCK_CATEGORY_PATH, MOCK_CATEGORY_PATH, MOCK_CATEGORY_PATH)); } @Test @@ -856,17 +840,11 @@ public class CategoriesImplTest final QName categoryQName = createCmQNameOf(CATEGORY_NAME); final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName); - final Path mockPath = new Path(); - final String mockRootLevel = "/{mockRootLevel}"; - final String mockChildLevel = "/{mockChild}"; - mockPath.append(PathHelper.stringToPath(mockRootLevel)); - mockPath.append(PathHelper.stringToPath(mockChildLevel)); - mockPath.append(PathHelper.stringToPath("/")); given(nodesMock.getNode(any())).willReturn(createNode(categoryNewName)); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); given(nodeServiceMock.moveNode(any(), any(), any(), any())).willReturn(createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, createCmQNameOf(categoryNewName))); given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); - given(nodeServiceMock.getPath(any())).willReturn(mockPath); + given(nodeServiceMock.getPath(any())).willReturn(mockCategoryPath()); // when final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, fixedCategory, parametersMock); @@ -875,7 +853,7 @@ public class CategoriesImplTest .isNotNull() .extracting(Category::getPath) .isNotNull() - .isEqualTo("//" + mockRootLevel + "//" + mockChildLevel); + .isEqualTo(MOCK_CATEGORY_PATH); } @Test @@ -1117,17 +1095,11 @@ public class CategoriesImplTest { final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF); - final Path mockPath = new Path(); - final String mockRootLevel = "/{mockRootLevel}"; - final String mockChildLevel = "/{mockChild}"; - mockPath.append(PathHelper.stringToPath(mockRootLevel)); - mockPath.append(PathHelper.stringToPath(mockChildLevel)); - mockPath.append(PathHelper.stringToPath("/")); given(nodesMock.getNode(any())).willReturn(createNode()); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); given(nodeServiceMock.hasAspect(any(), any())).willReturn(true); given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); - given(nodeServiceMock.getPath(any())).willReturn(mockPath); + given(nodeServiceMock.getPath(any())).willReturn(mockCategoryPath()); // when final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock); @@ -1142,7 +1114,7 @@ public class CategoriesImplTest then(nodeServiceMock).should().setProperty(CONTENT_NODE_REF, ContentModel.PROP_CATEGORIES, expectedCategories); then(nodeServiceMock).should().getParentAssocs(categoryParentNodeRef); final List expectedLinkedCategories = List.of(CATEGORY); - expectedLinkedCategories.get(0).setPath("//" + mockRootLevel + "//" + mockChildLevel); + expectedLinkedCategories.get(0).setPath(MOCK_CATEGORY_PATH); assertThat(actualLinkedCategories) .isNotNull().usingRecursiveComparison() .isEqualTo(expectedLinkedCategories); @@ -1343,17 +1315,11 @@ public class CategoriesImplTest { final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID); final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF); - final Path mockPath = new Path(); - final String mockRootLevel = "/{mockRootLevel}"; - final String mockChildLevel = "/{mockChild}"; - mockPath.append(PathHelper.stringToPath(mockRootLevel)); - mockPath.append(PathHelper.stringToPath(mockChildLevel)); - mockPath.append(PathHelper.stringToPath("/")); given(nodeServiceMock.getProperty(any(), eq(ContentModel.PROP_CATEGORIES))).willReturn((Serializable) List.of(CATEGORY_NODE_REF)); given(nodesMock.getNode(any())).willReturn(createNode()); given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation); given(parametersMock.getInclude()).willReturn(List.of(Nodes.PARAM_INCLUDE_PATH)); - given(nodeServiceMock.getPath(any())).willReturn(mockPath); + given(nodeServiceMock.getPath(any())).willReturn(mockCategoryPath()); // when final List actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock); @@ -1372,7 +1338,7 @@ public class CategoriesImplTest then(nodeServiceMock).should().getPath(any()); then(nodeServiceMock).shouldHaveNoMoreInteractions(); final List expectedCategories = List.of(CATEGORY); - expectedCategories.get(0).setPath("//" + mockRootLevel + "//" + mockChildLevel); + expectedCategories.get(0).setPath(MOCK_CATEGORY_PATH); assertThat(actualCategories) .isNotNull().usingRecursiveComparison() .isEqualTo(expectedCategories); @@ -1534,4 +1500,13 @@ public class CategoriesImplTest { return new ChildAssociationRef(ContentModel.ASSOC_SUBCATEGORIES, parentNode, childNodeName, childNode); } + + private Path mockCategoryPath() + { + final Path mockPath = new Path(); + mockPath.append(PathHelper.stringToPath(MOCK_ROOT_LEVEL)); + mockPath.append(PathHelper.stringToPath(MOCK_CHILD_LEVEL)); + mockPath.append(PathHelper.stringToPath("/")); + return mockPath; + } } From 14ba7f5d55210970d144067a9e01e540e5aec6ea Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Thu, 13 Apr 2023 19:00:35 +0200 Subject: [PATCH 13/21] ACS-4966 Explicit test result logging --- .../org/alfresco/rest/categories/CategoriesPathTests.java | 4 ++-- .../java/org/alfresco/rest/api/impl/CategoriesImplTest.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index ef343895d5..d5e5a7e648 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -131,9 +131,9 @@ public class CategoriesPathTests extends CategoriesRestTest .getCategoryChildren(); restClient.assertStatusCodeIs(OK); - assertTrue(actualCategories.getEntries().stream() + actualCategories.getEntries().stream() .map(RestCategoryModel::onModel) - .allMatch(cat -> cat.getPath().equals("/categories/General/" + parentCategory.getName()))); + .forEach(cat -> assertTrue(cat.getPath().equals("/categories/General/" + parentCategory.getName()))); } /** 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 296a768fc3..1ce88415ce 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 @@ -836,6 +836,7 @@ public class CategoriesImplTest { final String categoryNewName = "categoryNewName"; final Category fixedCategory = createCategoryOnlyWithName(categoryNewName); + // simulate path provided by client to check if it will be ignored fixedCategory.setPath("/test/TestCat"); final QName categoryQName = createCmQNameOf(CATEGORY_NAME); final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID); From 4f4d8210ef7a55b331156f5f7d4b67c364fb1e7f Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Thu, 13 Apr 2023 19:37:41 +0200 Subject: [PATCH 14/21] ACS-4966 Explicitly test path equality --- .../java/org/alfresco/rest/categories/CategoriesPathTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index d5e5a7e648..ac5dfba78c 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -133,7 +133,7 @@ public class CategoriesPathTests extends CategoriesRestTest restClient.assertStatusCodeIs(OK); actualCategories.getEntries().stream() .map(RestCategoryModel::onModel) - .forEach(cat -> assertTrue(cat.getPath().equals("/categories/General/" + parentCategory.getName()))); + .forEach(cat -> cat.assertThat().field(FIELD_PATH).is("/categories/General/" + parentCategory.getName())); } /** From 657318c6ae7f511ce721a9e43a3b1ab872f96a9b Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 14 Apr 2023 08:31:54 +0200 Subject: [PATCH 15/21] ACS-4966 Create Categories under the right parent --- .../rest/categories/CategoriesPathTests.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index ac5dfba78c..9e55081884 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -121,9 +121,22 @@ public class CategoriesPathTests extends CategoriesRestTest @Test(groups = { TestGroup.REST_API }) public void testGetChildCategory_includePath() { - STEP("Create parent and child categories and verify if child path contains parent name"); - final RestCategoryModel parentCategory = createCategoryModelWithId(ROOT_CATEGORY_ID); - final List childCategories = prepareCategoriesUnder(parentCategory.getId(), 2); + STEP("Create parent and child categories"); + final RestCategoryModel parentCategory = createCategoryModelWithIdAndName(ROOT_CATEGORY_ID, "TestCat"); + final List categoryModels = IntStream + .range(0, 2) + .mapToObj(i -> createCategoryModelWithName(getRandomName("TestName"))) + .collect(Collectors.toList()); + final List createdCategories = restClient.authenticateUser(dataUser.getAdminUser()) + .withCoreAPI() + .usingCategory(parentCategory) + .createCategoriesList(categoryModels) + .getEntries().stream() + .map(RestCategoryModel::onModel) + .collect(Collectors.toList()); + restClient.assertStatusCodeIs(CREATED); + + STEP("Verify path for created child categories"); final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user) .withCoreAPI() .usingCategory(parentCategory) From 93f7d06cf074fdd93c6b56b77c4e4a7943f66599 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 14 Apr 2023 08:37:49 +0200 Subject: [PATCH 16/21] ACS-4966 Missing imports --- .../java/org/alfresco/rest/categories/CategoriesPathTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index 9e55081884..622df1f127 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -33,6 +33,8 @@ import static org.springframework.http.HttpStatus.OK; import static org.testng.Assert.assertTrue; import java.util.List; +import java.util.stream.IntStream; +import java.util.stream.Collectors; import org.alfresco.dataprep.CMISUtil; import org.alfresco.rest.model.RestCategoryLinkBodyModel; From 70c490f26c8dc33efdcfbb2c782b22c392c77489 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 14 Apr 2023 09:15:07 +0200 Subject: [PATCH 17/21] ACS-4966 Parent category not as root --- .../java/org/alfresco/rest/categories/CategoriesPathTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index 622df1f127..f36515b9b1 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -124,7 +124,7 @@ public class CategoriesPathTests extends CategoriesRestTest public void testGetChildCategory_includePath() { STEP("Create parent and child categories"); - final RestCategoryModel parentCategory = createCategoryModelWithIdAndName(ROOT_CATEGORY_ID, "TestCat"); + final RestCategoryModel parentCategory = createCategoryModelWithIdAndName("testId", "TestCat"); final List categoryModels = IntStream .range(0, 2) .mapToObj(i -> createCategoryModelWithName(getRandomName("TestName"))) From 7592b637ccf2f9e082a035591bb4d88c04707b7b Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 14 Apr 2023 09:57:14 +0200 Subject: [PATCH 18/21] ACS-4966 Correct child category creation --- .../rest/categories/CategoriesPathTests.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index f36515b9b1..b15f456e0b 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -125,18 +125,7 @@ public class CategoriesPathTests extends CategoriesRestTest { STEP("Create parent and child categories"); final RestCategoryModel parentCategory = createCategoryModelWithIdAndName("testId", "TestCat"); - final List categoryModels = IntStream - .range(0, 2) - .mapToObj(i -> createCategoryModelWithName(getRandomName("TestName"))) - .collect(Collectors.toList()); - final List createdCategories = restClient.authenticateUser(dataUser.getAdminUser()) - .withCoreAPI() - .usingCategory(parentCategory) - .createCategoriesList(categoryModels) - .getEntries().stream() - .map(RestCategoryModel::onModel) - .collect(Collectors.toList()); - restClient.assertStatusCodeIs(CREATED); + final RestCategoryModel childCategory = prepareCategoryUnder(parentCategory); STEP("Verify path for created child categories"); final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user) From 25fa97bdd81653b5c1c4171c1b6c2224abb44843 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 14 Apr 2023 10:00:34 +0200 Subject: [PATCH 19/21] ACS-4966 Correct parent category creation --- .../org/alfresco/rest/categories/CategoriesPathTests.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index b15f456e0b..8a90a55433 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -124,20 +124,20 @@ public class CategoriesPathTests extends CategoriesRestTest public void testGetChildCategory_includePath() { STEP("Create parent and child categories"); - final RestCategoryModel parentCategory = createCategoryModelWithIdAndName("testId", "TestCat"); - final RestCategoryModel childCategory = prepareCategoryUnder(parentCategory); + final List parentCategories = prepareCategoriesUnderRoot(1); + final RestCategoryModel childCategory = prepareCategoryUnder(parentCategories.get(0)); STEP("Verify path for created child categories"); final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user) .withCoreAPI() - .usingCategory(parentCategory) + .usingCategory(parentCategories.get(0)) .include(INCLUDE_PATH_PARAM) .getCategoryChildren(); restClient.assertStatusCodeIs(OK); actualCategories.getEntries().stream() .map(RestCategoryModel::onModel) - .forEach(cat -> cat.assertThat().field(FIELD_PATH).is("/categories/General/" + parentCategory.getName())); + .forEach(cat -> cat.assertThat().field(FIELD_PATH).is("/categories/General/" + parentCategories.get(0).getName())); } /** From 7bdbc3a91a82722f017bb5c39ba65fc4ab421f95 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 14 Apr 2023 10:58:21 +0200 Subject: [PATCH 20/21] ACS-4966 Correct creation of categories --- .../org/alfresco/rest/categories/CategoriesPathTests.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index 8a90a55433..ca39f1dff5 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -124,20 +124,20 @@ public class CategoriesPathTests extends CategoriesRestTest public void testGetChildCategory_includePath() { STEP("Create parent and child categories"); - final List parentCategories = prepareCategoriesUnderRoot(1); - final RestCategoryModel childCategory = prepareCategoryUnder(parentCategories.get(0)); + final RestCategoryModel parentCategory = prepareCategoryUnderRoot(); + final RestCategoryModel childCategory = prepareCategoryUnder(parentCategory); STEP("Verify path for created child categories"); final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user) .withCoreAPI() - .usingCategory(parentCategories.get(0)) + .usingCategory(parentCategory) .include(INCLUDE_PATH_PARAM) .getCategoryChildren(); restClient.assertStatusCodeIs(OK); actualCategories.getEntries().stream() .map(RestCategoryModel::onModel) - .forEach(cat -> cat.assertThat().field(FIELD_PATH).is("/categories/General/" + parentCategories.get(0).getName())); + .forEach(cat -> cat.assertThat().field(FIELD_PATH).is("/categories/General/" + parentCategory.getName())); } /** From c0757f45a26a131b54ae653c95bbbb35cfe24ec4 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 14 Apr 2023 11:58:18 +0200 Subject: [PATCH 21/21] ACS-4966 Final cleanup --- .../org/alfresco/rest/categories/CategoriesPathTests.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java index ca39f1dff5..55d986276f 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesPathTests.java @@ -32,10 +32,6 @@ import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.OK; import static org.testng.Assert.assertTrue; -import java.util.List; -import java.util.stream.IntStream; -import java.util.stream.Collectors; - import org.alfresco.dataprep.CMISUtil; import org.alfresco.rest.model.RestCategoryLinkBodyModel; import org.alfresco.rest.model.RestCategoryModel; @@ -52,7 +48,6 @@ public class CategoriesPathTests extends CategoriesRestTest { private FileModel file; private RestCategoryModel category; - private RestCategoryModel anotherCategory; @BeforeClass(alwaysRun = true) @Override @@ -66,7 +61,6 @@ public class CategoriesPathTests extends CategoriesRestTest FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder(); file = dataContent.usingUser(user).usingResource(folder).createContent(CMISUtil.DocumentType.TEXT_PLAIN); category = prepareCategoryUnderRoot(); - anotherCategory = prepareCategoryUnderRoot(); STEP("Wait for indexing to complete"); Utility.sleep(1000, 60000, () -> restClient.authenticateUser(user)