diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesCountTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesCountTests.java
new file mode 100644
index 0000000000..e4ff3874b3
--- /dev/null
+++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CategoriesCountTests.java
@@ -0,0 +1,207 @@
+/*
+ * #%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 CategoriesCountTests extends CategoriesRestTest
+{
+
+ private RestCategoryModel categoryLinkedWithFolder;
+ private RestCategoryModel categoryLinkedWithFile;
+ private RestCategoryModel categoryLinkedWithBoth;
+ private RestCategoryModel notLinkedCategory;
+
+ @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);
+ categoryLinkedWithFolder = prepareCategoryUnderRoot();
+ categoryLinkedWithFile = prepareCategoryUnderRoot();
+ categoryLinkedWithBoth = prepareCategoryUnder(prepareCategoryUnderRoot());
+ notLinkedCategory = prepareCategoryUnderRoot();
+
+ STEP("Link folder and file to categories");
+ linkContentToCategories(folder, categoryLinkedWithFolder, categoryLinkedWithBoth);
+ linkContentToCategories(file, categoryLinkedWithFile, categoryLinkedWithBoth);
+
+ STEP("Wait for indexing to complete");
+ Utility.sleep(1000, 60000, () -> restClient.authenticateUser(user)
+ .withCoreAPI()
+ .usingCategory(categoryLinkedWithFolder)
+ .include(INCLUDE_COUNT_PARAM)
+ .getCategory()
+ .assertThat()
+ .field(FIELD_COUNT)
+ .isNot(0));
+ }
+
+ /**
+ * Verify count for a category linked with file and folder.
+ */
+ @Test(groups = { TestGroup.REST_API })
+ public void testGetCategoryById_includeCount()
+ {
+ STEP("Get linked category and verify if count is higher than 0");
+ final RestCategoryModel actualCategory = restClient.authenticateUser(user)
+ .withCoreAPI()
+ .usingCategory(categoryLinkedWithBoth)
+ .include(INCLUDE_COUNT_PARAM)
+ .getCategory();
+
+ restClient.assertStatusCodeIs(OK);
+ actualCategory.assertThat().field(FIELD_ID).is(categoryLinkedWithBoth.getId());
+ actualCategory.assertThat().field(FIELD_COUNT).is(2);
+ }
+
+ /**
+ * Verify count for a category not linked with any content.
+ */
+ @Test(groups = { TestGroup.REST_API })
+ public void testGetCategoryById_includeCountForNonLinkedCategory()
+ {
+ STEP("Get non-linked category and verify if count is 0");
+ final RestCategoryModel actualCategory = restClient.authenticateUser(user)
+ .withCoreAPI()
+ .usingCategory(notLinkedCategory)
+ .include(INCLUDE_COUNT_PARAM)
+ .getCategory();
+
+ restClient.assertStatusCodeIs(OK);
+ actualCategory.assertThat().field(FIELD_ID).is(notLinkedCategory.getId());
+ actualCategory.assertThat().field(FIELD_COUNT).is(0);
+ }
+
+ /**
+ * Verify count for three categories: linked with file, linked with folder and third not linked to any content.
+ */
+ @Test(groups = { TestGroup.REST_API })
+ public void testGetCategories_includeCount()
+ {
+ STEP("Get few categories and verify its counts");
+ final RestCategoryModel parentCategory = createCategoryModelWithId(ROOT_CATEGORY_ID);
+ final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user)
+ .withCoreAPI()
+ .usingCategory(parentCategory)
+ .include(INCLUDE_COUNT_PARAM)
+ .getCategoryChildren();
+
+ restClient.assertStatusCodeIs(OK);
+ assertTrue(actualCategories.getEntries().stream()
+ .map(RestCategoryModel::onModel)
+ .anyMatch(category -> category.getId().equals(categoryLinkedWithFolder.getId()) && category.getCount() == 1));
+ assertTrue(actualCategories.getEntries().stream()
+ .map(RestCategoryModel::onModel)
+ .anyMatch(category -> category.getId().equals(categoryLinkedWithFile.getId()) && category.getCount() == 1));
+ assertTrue(actualCategories.getEntries().stream()
+ .map(RestCategoryModel::onModel)
+ .anyMatch(category -> category.getId().equals(notLinkedCategory.getId()) && category.getCount() == 0));
+ }
+
+ /**
+ * Create category and verify that its count is 0.
+ */
+ @Test(groups = { TestGroup.REST_API })
+ public void testCreateCategory_includingCount()
+ {
+ STEP("Create a category under root and verify if count is 0");
+ 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_COUNT_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_COUNT).is(0);
+ }
+
+ /**
+ * Update category linked to file and folder and verify that its count is 2.
+ */
+ @Test(groups = { TestGroup.REST_API })
+ public void testUpdateCategory_includeCount()
+ {
+ STEP("Update linked category and verify if count is higher than 0");
+ final String categoryNewName = getRandomName("NewCategoryName");
+ final RestCategoryModel fixedCategoryModel = createCategoryModelWithName(categoryNewName);
+ final RestCategoryModel updatedCategory = restClient.authenticateUser(dataUser.getAdminUser())
+ .withCoreAPI()
+ .usingCategory(categoryLinkedWithBoth)
+ .include(INCLUDE_COUNT_PARAM)
+ .updateCategory(fixedCategoryModel);
+
+ restClient.assertStatusCodeIs(OK);
+ updatedCategory.assertThat().field(FIELD_ID).is(categoryLinkedWithBoth.getId());
+ updatedCategory.assertThat().field(FIELD_COUNT).is(2);
+ }
+
+ /**
+ * Update category not linked to any content and verify that its count is 0.
+ */
+ @Test(groups = { TestGroup.REST_API })
+ public void testUpdateCategory_includeCountForNonLinkedCategory()
+ {
+ STEP("Update non-linked category and verify if count is 0");
+ final String categoryNewName = getRandomName("NewCategoryName");
+ final RestCategoryModel fixedCategoryModel = createCategoryModelWithName(categoryNewName);
+ final RestCategoryModel updatedCategory = restClient.authenticateUser(dataUser.getAdminUser())
+ .withCoreAPI()
+ .usingCategory(notLinkedCategory)
+ .include(INCLUDE_COUNT_PARAM)
+ .updateCategory(fixedCategoryModel);
+
+ restClient.assertStatusCodeIs(OK);
+ updatedCategory.assertThat().field(FIELD_ID).is(notLinkedCategory.getId());
+ updatedCategory.assertThat().field(FIELD_COUNT).is(0);
+ }
+}
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 f424f5724b..c98c9802f7 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
@@ -30,6 +30,7 @@ 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 java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -37,18 +38,21 @@ import java.util.stream.IntStream;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestCategoryLinkBodyModel;
import org.alfresco.rest.model.RestCategoryModel;
+import org.alfresco.rest.model.RestCategoryModelsCollection;
import org.alfresco.utility.model.RepoTestModel;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.BeforeClass;
abstract class CategoriesRestTest extends RestTest
{
+ protected static final String INCLUDE_COUNT_PARAM = "count";
protected static final String ROOT_CATEGORY_ID = "-root-";
protected static final String CATEGORY_NAME_PREFIX = "CategoryName";
protected static final String FIELD_NAME = "name";
protected static final String FIELD_ID = "id";
protected static final String FIELD_PARENT_ID = "parentId";
protected static final String FIELD_HAS_CHILDREN = "hasChildren";
+ protected static final String FIELD_COUNT = "count";
protected UserModel user;
@@ -59,14 +63,26 @@ abstract class CategoriesRestTest extends RestTest
user = dataUser.createRandomTestUser();
}
- protected RestCategoryModel prepareCategoryUnderRoot()
+ protected RestCategoryModelsCollection linkContentToCategories(final RepoTestModel node, final RestCategoryModel... categories)
{
- return prepareCategoryUnder(ROOT_CATEGORY_ID);
+ final List categoryLinkModels = Arrays.stream(categories)
+ .map(RestCategoryModel::getId)
+ .map(this::createCategoryLinkModelWithId)
+ .collect(Collectors.toList());
+ final RestCategoryModelsCollection linkedCategories = restClient.authenticateUser(user).withCoreAPI().usingNode(node).linkToCategories(categoryLinkModels);
+
+ restClient.assertStatusCodeIs(CREATED);
+
+ return linkedCategories;
}
- protected RestCategoryModel prepareCategoryUnder(final String parentId)
+ protected RestCategoryModel prepareCategoryUnderRoot()
+ {
+ return prepareCategoryUnder(createCategoryModelWithId(ROOT_CATEGORY_ID));
+ }
+
+ protected RestCategoryModel prepareCategoryUnder(final RestCategoryModel parentCategory)
{
- final RestCategoryModel parentCategory = createCategoryModelWithId(parentId);
final RestCategoryModel categoryModel = createCategoryModelWithName(getRandomName(CATEGORY_NAME_PREFIX));
final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
.withCoreAPI()
diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CreateCategoriesTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CreateCategoriesTests.java
index 92ccb56d44..53b4a5d952 100644
--- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CreateCategoriesTests.java
+++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/CreateCategoriesTests.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2022 Alfresco Software Limited
+ * 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
@@ -26,6 +26,7 @@
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.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
@@ -38,7 +39,6 @@ import java.util.stream.IntStream;
import org.alfresco.rest.model.RestCategoryModel;
import org.alfresco.rest.model.RestCategoryModelsCollection;
-import org.alfresco.utility.data.RandomData;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.TestGroup;
@@ -56,7 +56,7 @@ public class CreateCategoriesTests extends CategoriesRestTest
{
STEP("Create a category under root category (as admin)");
final RestCategoryModel rootCategory = createCategoryModelWithId(ROOT_CATEGORY_ID);
- final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.getRandomName("Category"));
+ final RestCategoryModel aCategory = createCategoryModelWithName(getRandomName("Category"));
final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
.withCoreAPI()
.usingCategory(rootCategory)
@@ -92,7 +92,7 @@ public class CreateCategoriesTests extends CategoriesRestTest
{
STEP("Create a category under root category (as admin)");
final RestCategoryModel rootCategory = createCategoryModelWithId(ROOT_CATEGORY_ID);
- final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.getRandomName("Category"));
+ final RestCategoryModel aCategory = createCategoryModelWithName(getRandomName("Category"));
final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
.withCoreAPI()
.usingCategory(rootCategory)
@@ -140,7 +140,7 @@ public class CreateCategoriesTests extends CategoriesRestTest
{
STEP("Create a category under root category (as admin)");
final RestCategoryModel rootCategory = createCategoryModelWithId(ROOT_CATEGORY_ID);
- final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.getRandomName("Category"));
+ final RestCategoryModel aCategory = createCategoryModelWithName(getRandomName("Category"));
final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
.withCoreAPI()
.usingCategory(rootCategory)
@@ -186,7 +186,7 @@ public class CreateCategoriesTests extends CategoriesRestTest
{
STEP("Create a category under root category (as user)");
final RestCategoryModel rootCategory = createCategoryModelWithId(ROOT_CATEGORY_ID);
- final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.getRandomName("Category"));
+ final RestCategoryModel aCategory = createCategoryModelWithName(getRandomName("Category"));
restClient.authenticateUser(user)
.withCoreAPI()
.usingCategory(rootCategory)
@@ -203,7 +203,7 @@ public class CreateCategoriesTests extends CategoriesRestTest
STEP("Create a category under non existing category node (as admin)");
final String id = "non-existing-node-id";
final RestCategoryModel rootCategory = createCategoryModelWithId(id);
- final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.getRandomName("Category"));
+ final RestCategoryModel aCategory = createCategoryModelWithName(getRandomName("Category"));
restClient.authenticateUser(dataUser.getAdminUser())
.withCoreAPI()
.usingCategory(rootCategory)
@@ -223,7 +223,7 @@ public class CreateCategoriesTests extends CategoriesRestTest
STEP("Create a category under folder node (as admin)");
final RestCategoryModel rootCategory = createCategoryModelWithId(folder.getNodeRef());
- final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.getRandomName("Category"));
+ final RestCategoryModel aCategory = createCategoryModelWithName(getRandomName("Category"));
restClient.authenticateUser(dataUser.getAdminUser())
.withCoreAPI()
.usingCategory(rootCategory)
@@ -231,10 +231,31 @@ public class CreateCategoriesTests extends CategoriesRestTest
restClient.assertStatusCodeIs(BAD_REQUEST).assertLastError().containsSummary("Node id does not refer to a valid category");
}
+ /**
+ * Check weather count present in create category request will be ignored.
+ */
+ @Test(groups = { TestGroup.REST_API })
+ public void testCreateCategoryUnderRoot_verifyIfCountInRequestIsIgnored()
+ {
+ STEP("Try to create a category with filled count under root");
+ final RestCategoryModel rootCategory = createCategoryModelWithId(ROOT_CATEGORY_ID);
+ final RestCategoryModel aCategory = createCategoryModelWithName(getRandomName("Category"));
+ aCategory.setCount(2);
+ final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
+ .withCoreAPI()
+ .usingCategory(rootCategory)
+ .include(INCLUDE_COUNT_PARAM)
+ .createSingleCategory(aCategory);
+
+ restClient.assertStatusCodeIs(CREATED);
+ createdCategory.assertThat().field(FIELD_NAME).is(aCategory.getName());
+ createdCategory.assertThat().field(FIELD_COUNT).is(0);
+ }
+
static List getCategoriesToCreate(final int count)
{
return IntStream.range(0, count)
- .mapToObj(i -> RestCategoryModel.builder().name(RandomData.getRandomName("SubCategory")).create())
+ .mapToObj(i -> RestCategoryModel.builder().name(getRandomName("SubCategory")).create())
.collect(Collectors.toList());
}
}
diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/UpdateCategoriesTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/UpdateCategoriesTests.java
index 969990c7de..8b4c81d115 100644
--- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/UpdateCategoriesTests.java
+++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/categories/UpdateCategoriesTests.java
@@ -79,7 +79,7 @@ public class UpdateCategoriesTests extends CategoriesRestTest
final RestCategoryModel createdCategory = prepareCategoryUnderRoot();
STEP("Prepare as admin a subcategory of root's child category");
- final RestCategoryModel createdSubcategory = prepareCategoryUnder(createdCategory.getId());
+ final RestCategoryModel createdSubcategory = prepareCategoryUnder(createdCategory);
STEP("Update as admin newly created subcategory");
final String categoryNewName = getRandomName(CATEGORY_NEW_NAME_PREFIX);
@@ -233,4 +233,27 @@ public class UpdateCategoriesTests extends CategoriesRestTest
restClient.assertStatusCodeIs(OK);
updatedCategory.assertThat().field(FIELD_NAME).is(categoryNewName);
}
+
+ /**
+ * Check whether count present in update category request will be ignored.
+ */
+ @Test(groups = { TestGroup.REST_API })
+ public void testUpdateCategory_verifyIfCountInRequestIsIgnored()
+ {
+ STEP("Prepare a category under root category");
+ final RestCategoryModel createdCategory = prepareCategoryUnderRoot();
+
+ STEP("Try to update newly created category providing new name and count number");
+ final RestCategoryModel fixedCategoryModel = createCategoryModelWithName(getRandomName(CATEGORY_NEW_NAME_PREFIX));
+ fixedCategoryModel.setCount(2);
+ final RestCategoryModel updatedCategory = restClient.authenticateUser(dataUser.getAdminUser())
+ .withCoreAPI()
+ .usingCategory(createdCategory)
+ .include(INCLUDE_COUNT_PARAM)
+ .updateCategory(fixedCategoryModel);
+
+ restClient.assertStatusCodeIs(OK);
+ updatedCategory.assertThat().field(FIELD_ID).is(createdCategory.getId());
+ updatedCategory.assertThat().field(FIELD_COUNT).is(0);
+ }
}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/Categories.java b/remote-api/src/main/java/org/alfresco/rest/api/Categories.java
index e591bf9dd5..08ec10e4ec 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/Categories.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/Categories.java
@@ -26,57 +26,101 @@
package org.alfresco.rest.api;
+import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
+
import java.util.List;
import org.alfresco.rest.api.model.Category;
-import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.Experimental;
+import org.alfresco.service.cmr.repository.StoreRef;
@Experimental
public interface Categories
{
- Category getCategoryById(String id, Parameters parameters);
+ Category getCategoryById(StoreRef storeRef, String id, Parameters parameters);
- List createSubcategories(String parentCategoryId, List categories, Parameters parameters);
+ default Category getCategoryById(String id, Parameters parameters)
+ {
+ return getCategoryById(STORE_REF_WORKSPACE_SPACESSTORE, id, parameters);
+ }
- CollectionWithPagingInfo getCategoryChildren(String parentCategoryId, Parameters parameters);
+ List createSubcategories(StoreRef storeRef, String parentCategoryId, List categories, Parameters parameters);
+
+ default List createSubcategories(String parentCategoryId, List categories, Parameters parameters)
+ {
+ return createSubcategories(STORE_REF_WORKSPACE_SPACESSTORE, parentCategoryId, categories, parameters);
+ }
+
+ List getCategoryChildren(StoreRef storeRef, String parentCategoryId, Parameters parameters);
+
+ default List getCategoryChildren(String parentCategoryId, Parameters parameters)
+ {
+ return getCategoryChildren(STORE_REF_WORKSPACE_SPACESSTORE, parentCategoryId, parameters);
+ }
/**
* Update category by ID. Currently, it's possible only to update the name of category.
*
+ * @param storeRef Reference to node store.
* @param id Category ID.
* @param fixedCategoryModel Fixed category model.
+ * @param parameters Additional parameters.
* @return Updated category.
*/
- Category updateCategoryById(String id, Category fixedCategoryModel);
+ Category updateCategoryById(StoreRef storeRef, String id, Category fixedCategoryModel, Parameters parameters);
- void deleteCategoryById(String id, Parameters parameters);
+ default Category updateCategoryById(String id, Category fixedCategoryModel, Parameters parameters)
+ {
+ return updateCategoryById(STORE_REF_WORKSPACE_SPACESSTORE, id, fixedCategoryModel, parameters);
+ }
+
+ void deleteCategoryById(StoreRef storeRef, String id, Parameters parameters);
+
+ default void deleteCategoryById(String id, Parameters parameters)
+ {
+ deleteCategoryById(STORE_REF_WORKSPACE_SPACESSTORE, id, parameters);
+ }
/**
* Get categories linked from node. Read permission on node is required.
* Node type is restricted to specified vales from: {@link org.alfresco.util.TypeConstraint}.
*
* @param nodeId Node ID.
+ * @param parameters Additional parameters.
* @return Categories linked from node.
*/
- List listCategoriesForNode(String nodeId);
+ List listCategoriesForNode(String nodeId, Parameters parameters);
/**
* Link node to categories. Change permission on node is required.
* Node types allowed for categorization are specified within {@link org.alfresco.util.TypeConstraint}.
*
+ * @param storeRef Reference to node store.
* @param nodeId Node ID.
* @param categoryLinks Category IDs to which content should be linked to.
+ * @param parameters Additional parameters.
* @return Linked to categories.
*/
- List linkNodeToCategories(String nodeId, List categoryLinks);
+ List linkNodeToCategories(StoreRef storeRef, String nodeId, List categoryLinks, Parameters parameters);
+
+ default List linkNodeToCategories(String nodeId, List categoryLinks, Parameters parameters)
+ {
+ return linkNodeToCategories(STORE_REF_WORKSPACE_SPACESSTORE, nodeId, categoryLinks, parameters);
+ }
/**
* Unlink node from a category.
*
+ * @param storeRef Reference to node store.
* @param nodeId Node ID.
* @param categoryId Category ID from which content node should be unlinked from.
+ * @param parameters Additional parameters.
*/
- void unlinkNodeFromCategory(String nodeId, String categoryId, Parameters parameters);
+ void unlinkNodeFromCategory(StoreRef storeRef, String nodeId, String categoryId, Parameters parameters);
+
+ default void unlinkNodeFromCategory(String nodeId, String categoryId, Parameters parameters)
+ {
+ unlinkNodeFromCategory(STORE_REF_WORKSPACE_SPACESSTORE, nodeId, categoryId, parameters);
+ }
}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/categories/CategoriesEntityResource.java b/remote-api/src/main/java/org/alfresco/rest/api/categories/CategoriesEntityResource.java
index 23b79067ac..e67bf9801f 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/categories/CategoriesEntityResource.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/categories/CategoriesEntityResource.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * 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
@@ -45,6 +45,7 @@ public class CategoriesEntityResource implements EntityResourceAction.ReadById,
EntityResourceAction.Delete
{
+
private final Categories categories;
public CategoriesEntityResource(Categories categories)
@@ -77,7 +78,7 @@ public class CategoriesEntityResource implements EntityResourceAction.ReadById readAll(String nodeId, Parameters parameters)
{
- return ListPage.of(categories.listCategoriesForNode(nodeId), parameters.getPaging());
+ return ListPage.of(categories.listCategoriesForNode(nodeId, parameters), parameters.getPaging());
}
/**
@@ -77,7 +77,7 @@ public class NodesCategoryLinksRelation implements RelationshipResourceAction.Cr
@Override
public List create(String nodeId, List categoryLinks, Parameters parameters)
{
- return categories.linkNodeToCategories(nodeId, categoryLinks);
+ return categories.linkNodeToCategories(nodeId, categoryLinks, parameters);
}
/**
@@ -93,5 +93,4 @@ public class NodesCategoryLinksRelation implements RelationshipResourceAction.Cr
{
categories.unlinkNodeFromCategory(nodeId, categoryId, parameters);
}
-
}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/categories/SubcategoriesRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/categories/SubcategoriesRelation.java
index 8ef264ea35..7214597916 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/categories/SubcategoriesRelation.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/categories/SubcategoriesRelation.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2022 Alfresco Software Limited
+ * 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
@@ -26,9 +26,8 @@
package org.alfresco.rest.api.categories;
-import java.util.List;
-
import javax.servlet.http.HttpServletResponse;
+import java.util.List;
import org.alfresco.rest.api.Categories;
import org.alfresco.rest.api.model.Category;
@@ -36,6 +35,7 @@ import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.ListPage;
import org.alfresco.rest.framework.resource.parameters.Parameters;
@RelationshipResource(name = "subcategories", entityResource = CategoriesEntityResource.class, title = "Subcategories")
@@ -69,8 +69,8 @@ public class SubcategoriesRelation implements RelationshipResourceAction.Create<
description = "Lists direct children of a parent category",
successStatus = HttpServletResponse.SC_OK)
@Override
- public CollectionWithPagingInfo readAll(String parentCategoryId, Parameters params)
+ public CollectionWithPagingInfo readAll(String parentCategoryId, Parameters parameters)
{
- return categories.getCategoryChildren(parentCategoryId, params);
+ return ListPage.of(categories.getCategoryChildren(parentCategoryId, parameters), parameters.getPaging());
}
}
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 e8e6ff4470..e78f7856d4 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
@@ -46,10 +46,8 @@ import org.alfresco.rest.api.model.Category;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
-import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.core.exceptions.InvalidNodeTypeException;
-import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
-import org.alfresco.rest.framework.resource.parameters.ListPage;
+import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -62,6 +60,7 @@ import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
+import org.alfresco.util.Pair;
import org.alfresco.util.TypeConstraint;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -69,6 +68,7 @@ import org.apache.commons.lang3.StringUtils;
@Experimental
public class CategoriesImpl implements Categories
{
+ static final String INCLUDE_COUNT_PARAM = "count";
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";
@@ -83,8 +83,8 @@ public class CategoriesImpl implements Categories
private final PermissionService permissionService;
private final TypeConstraint typeConstraint;
- public CategoriesImpl(AuthorityService authorityService, CategoryService categoryService, Nodes nodes, NodeService nodeService, PermissionService permissionService,
- TypeConstraint typeConstraint)
+ public CategoriesImpl(AuthorityService authorityService, CategoryService categoryService, Nodes nodes, NodeService nodeService,
+ PermissionService permissionService, TypeConstraint typeConstraint)
{
this.authorityService = authorityService;
this.categoryService = categoryService;
@@ -95,63 +95,89 @@ public class CategoriesImpl implements Categories
}
@Override
- public Category getCategoryById(final String id, final Parameters params)
+ public Category getCategoryById(final StoreRef storeRef, final String id, final Parameters parameters)
{
- final NodeRef nodeRef = getCategoryNodeRef(id);
+ final NodeRef nodeRef = getCategoryNodeRef(storeRef, id);
if (isRootCategory(nodeRef))
{
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
}
- return mapToCategory(nodeRef);
+ final Category category = mapToCategory(nodeRef);
+
+ if (parameters.getInclude().contains(INCLUDE_COUNT_PARAM))
+ {
+ final Map categoriesCount = getCategoriesCount(storeRef);
+ category.setCount(categoriesCount.getOrDefault(category.getId(), 0));
+ }
+
+ return category;
}
@Override
- public List createSubcategories(String parentCategoryId, List categories, Parameters parameters)
+ public List createSubcategories(final StoreRef storeRef, final String parentCategoryId, final List categories, final Parameters parameters)
{
verifyAdminAuthority();
- final NodeRef parentNodeRef = getCategoryNodeRef(parentCategoryId);
- final List categoryNodeRefs = categories.stream()
+ final NodeRef parentNodeRef = getCategoryNodeRef(storeRef, parentCategoryId);
+
+ return categories.stream()
.map(c -> createCategoryNodeRef(parentNodeRef, c))
- .collect(Collectors.toList());
- return categoryNodeRefs.stream()
.map(this::mapToCategory)
+ .peek(category -> {
+ if (parameters.getInclude().contains(INCLUDE_COUNT_PARAM))
+ {
+ category.setCount(0);
+ }
+ })
.collect(Collectors.toList());
}
@Override
- public CollectionWithPagingInfo getCategoryChildren(String parentCategoryId, Parameters params)
+ public List getCategoryChildren(final StoreRef storeRef, final String parentCategoryId, final Parameters parameters)
{
- final NodeRef parentNodeRef = getCategoryNodeRef(parentCategoryId);
- final List childCategoriesAssocs = nodeService.getChildAssocs(parentNodeRef).stream()
- .filter(ca -> ContentModel.ASSOC_SUBCATEGORIES.equals(ca.getTypeQName()))
- .collect(Collectors.toList());
- final List categories = childCategoriesAssocs.stream()
- .map(c -> mapToCategory(c.getChildRef()))
- .collect(Collectors.toList());
- return ListPage.of(categories, params.getPaging());
+ 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());
+
+ if (parameters.getInclude().contains(INCLUDE_COUNT_PARAM))
+ {
+ final Map categoriesCount = getCategoriesCount(storeRef);
+ categories.forEach(category -> category.setCount(categoriesCount.getOrDefault(category.getId(), 0)));
+ }
+
+ return categories;
}
@Override
- public Category updateCategoryById(final String id, final Category fixedCategoryModel)
+ public Category updateCategoryById(final StoreRef storeRef, final String id, final Category fixedCategoryModel, final Parameters parameters)
{
verifyAdminAuthority();
- final NodeRef categoryNodeRef = getCategoryNodeRef(id);
+ final NodeRef categoryNodeRef = getCategoryNodeRef(storeRef, id);
if (isRootCategory(categoryNodeRef))
{
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
}
validateCategoryFields(fixedCategoryModel);
+ final Category category = mapToCategory(changeCategoryName(categoryNodeRef, fixedCategoryModel.getName()));
- return mapToCategory(changeCategoryName(categoryNodeRef, fixedCategoryModel.getName()));
+ if (parameters.getInclude().contains(INCLUDE_COUNT_PARAM))
+ {
+ final Map categoriesCount = getCategoriesCount(storeRef);
+ category.setCount(categoriesCount.getOrDefault(category.getId(), 0));
+ }
+
+ return category;
}
@Override
- public void deleteCategoryById(String id, Parameters parameters)
+ public void deleteCategoryById(final StoreRef storeRef, final String id, final Parameters parameters)
{
verifyAdminAuthority();
- final NodeRef nodeRef = getCategoryNodeRef(id);
+ final NodeRef nodeRef = getCategoryNodeRef(storeRef, id);
if (isRootCategory(nodeRef))
{
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
@@ -161,7 +187,7 @@ public class CategoriesImpl implements Categories
}
@Override
- public List listCategoriesForNode(final String nodeId)
+ public List listCategoriesForNode(final String nodeId, final Parameters parameters)
{
final NodeRef contentNodeRef = nodes.validateNode(nodeId);
verifyReadPermission(contentNodeRef);
@@ -178,7 +204,7 @@ public class CategoriesImpl implements Categories
}
@Override
- public List linkNodeToCategories(final String nodeId, final List categoryLinks)
+ public List linkNodeToCategories(final StoreRef storeRef, final String nodeId, final List categoryLinks, final Parameters parameters)
{
if (CollectionUtils.isEmpty(categoryLinks))
{
@@ -194,7 +220,7 @@ public class CategoriesImpl implements Categories
.map(Category::getId)
.filter(StringUtils::isNotEmpty)
.distinct()
- .map(this::getCategoryNodeRef)
+ .map(id -> getCategoryNodeRef(storeRef, id))
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(categoryNodeRefs) || isRootCategoryPresent(categoryNodeRefs))
@@ -208,9 +234,9 @@ public class CategoriesImpl implements Categories
}
@Override
- public void unlinkNodeFromCategory(final String nodeId, final String categoryId, Parameters parameters)
+ public void unlinkNodeFromCategory(final StoreRef storeRef, final String nodeId, final String categoryId, final Parameters parameters)
{
- final NodeRef categoryNodeRef = getCategoryNodeRef(categoryId);
+ final NodeRef categoryNodeRef = getCategoryNodeRef(storeRef, categoryId);
final NodeRef contentNodeRef = nodes.validateNode(nodeId);
verifyChangePermission(contentNodeRef);
verifyNodeType(contentNodeRef);
@@ -272,13 +298,14 @@ public class CategoriesImpl implements Categories
* This method gets category NodeRef for a given category id.
* If '-root-' is passed as category id, then it's retrieved as a call to {@link org.alfresco.service.cmr.search.CategoryService#getRootCategoryNodeRef}
* In all other cases it's retrieved as a node of a category type {@link #validateCategoryNode(String)}
+ * @param storeRef Reference to node store.
* @param nodeId category node id
* @return NodRef of category node
*/
- private NodeRef getCategoryNodeRef(String nodeId)
+ private NodeRef getCategoryNodeRef(StoreRef storeRef, String nodeId)
{
return PATH_ROOT.equals(nodeId) ?
- categoryService.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE)
+ categoryService.getRootCategoryNodeRef(storeRef)
.orElseThrow(() -> new EntityNotFoundException(nodeId)) :
validateCategoryNode(nodeId);
}
@@ -434,4 +461,18 @@ public class CategoriesImpl implements Categories
nodeService.setProperty(nodeRef, ContentModel.PROP_CATEGORIES, (Serializable) allCategories);
}
}
+
+ /**
+ * Get categories by usage count. Result is a map of category IDs (short form - UUID) as key and usage count as value.
+ *
+ * @param storeRef Reference to node store.
+ * @return Map of categories IDs and usage count.
+ */
+ private Map getCategoriesCount(final StoreRef storeRef)
+ {
+ final String idPrefix = storeRef + "/";
+ return categoryService.getTopCategories(storeRef, ContentModel.ASPECT_GEN_CLASSIFIABLE, Integer.MAX_VALUE)
+ .stream()
+ .collect(Collectors.toMap(pair -> pair.getFirst().toString().replace(idPrefix, StringUtils.EMPTY), Pair::getSecond));
+ }
}
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 1d80e34410..812d362a96 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
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2022 Alfresco Software Limited
+ * 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
@@ -34,6 +34,7 @@ public class Category
private String name;
private String parentId;
private boolean hasChildren;
+ private Integer count;
public String getId()
{
@@ -80,20 +81,38 @@ public class Category
this.hasChildren = hasChildren;
}
+ public Integer getCount()
+ {
+ return count;
+ }
+
+ public void setCount(Integer count)
+ {
+ this.count = count;
+ }
+
@Override
public boolean equals(Object o)
{
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
Category category = (Category) o;
- return hasChildren == category.hasChildren && Objects.equals(id, category.id) && name.equals(category.name) &&
- Objects.equals(parentId, category.parentId);
+ return hasChildren == category.hasChildren && Objects.equals(id, category.id) && Objects.equals(name, category.name) && Objects.equals(parentId, category.parentId)
+ && Objects.equals(count, category.count);
}
@Override
public int hashCode()
{
- return Objects.hash(id, name, parentId, hasChildren);
+ return Objects.hash(id, name, parentId, hasChildren, count);
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Category{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", parentId='" + parentId + '\'' + ", hasChildren=" + hasChildren + ", count=" + count + '}';
}
public static Builder builder()
@@ -107,6 +126,7 @@ public class Category
private String name;
private String parentId;
private boolean hasChildren;
+ private Integer count;
public Builder id(String id)
{
@@ -132,6 +152,12 @@ public class Category
return this;
}
+ public Builder count(Integer count)
+ {
+ this.count = count;
+ return this;
+ }
+
public Category create()
{
final Category category = new Category();
@@ -139,6 +165,7 @@ public class Category
category.setName(name);
category.setParentId(parentId);
category.setHasChildren(hasChildren);
+ category.setCount(count);
return category;
}
}
diff --git a/remote-api/src/test/java/org/alfresco/AppContextExtraTestSuite.java b/remote-api/src/test/java/org/alfresco/AppContextExtraTestSuite.java
index 4dcdda433a..1963f197c6 100644
--- a/remote-api/src/test/java/org/alfresco/AppContextExtraTestSuite.java
+++ b/remote-api/src/test/java/org/alfresco/AppContextExtraTestSuite.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
- * Copyright (C) 2005 - 2022 Alfresco Software Limited
+ * 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
@@ -49,6 +49,7 @@ import org.junit.runners.Suite;
org.alfresco.repo.webdav.WebDAVHelperTest.class,
org.alfresco.repo.webdav.WebDAVLockServiceImplTest.class,
org.alfresco.rest.api.RulesUnitTests.class,
+ org.alfresco.rest.api.CategoriesUnitTests.class,
org.alfresco.rest.api.impl.ContentStorageInformationImplTest.class,
org.alfresco.rest.api.nodes.NodeStorageInfoRelationTest.class,
org.alfresco.rest.api.search.ResultMapperTests.class,
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/CategoriesUnitTests.java b/remote-api/src/test/java/org/alfresco/rest/api/CategoriesUnitTests.java
new file mode 100644
index 0000000000..9f79b10a5a
--- /dev/null
+++ b/remote-api/src/test/java/org/alfresco/rest/api/CategoriesUnitTests.java
@@ -0,0 +1,47 @@
+/*
+ * #%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.api;
+
+import org.alfresco.rest.api.categories.CategoriesEntityResourceTest;
+import org.alfresco.rest.api.categories.NodesCategoryLinksRelationTest;
+import org.alfresco.rest.api.categories.SubcategoriesRelationTest;
+import org.alfresco.rest.api.impl.CategoriesImplTest;
+import org.alfresco.service.Experimental;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@Experimental
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ CategoriesImplTest.class,
+ CategoriesEntityResourceTest.class,
+ SubcategoriesRelationTest.class,
+ NodesCategoryLinksRelationTest.class
+})
+public class CategoriesUnitTests
+{
+}
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/categories/CategoriesEntityResourceTest.java b/remote-api/src/test/java/org/alfresco/rest/api/categories/CategoriesEntityResourceTest.java
index 56d2e72eca..990852f623 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/categories/CategoriesEntityResourceTest.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/categories/CategoriesEntityResourceTest.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2022 Alfresco Software Limited
+ * 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
@@ -26,15 +26,21 @@
package org.alfresco.rest.api.categories;
+import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
+import static org.mockito.BDDMockito.willCallRealMethod;
+
+import java.util.List;
import org.alfresco.rest.api.Categories;
import org.alfresco.rest.api.model.Category;
import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
@@ -45,6 +51,7 @@ import org.mockito.junit.MockitoJUnitRunner;
public class CategoriesEntityResourceTest
{
private static final String CATEGORY_ID = "category-node-id";
+
@Mock
private Categories categoriesMock;
@Mock
@@ -58,26 +65,37 @@ public class CategoriesEntityResourceTest
@Test
public void testReadCategoryById()
{
- given(categoriesMock.getCategoryById(CATEGORY_ID, parametersMock)).willReturn(categoryMock);
+ given(categoriesMock.getCategoryById(any(), any())).willCallRealMethod();
+ given(categoriesMock.getCategoryById(any(), any(), any())).willReturn(categoryMock);
//when
final Category category = objectUnderTest.readById(CATEGORY_ID, parametersMock);
- then(categoriesMock).should().getCategoryById(CATEGORY_ID, parametersMock);
- then(categoriesMock).shouldHaveNoMoreInteractions();
+ then(categoriesMock).should().getCategoryById(STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID, parametersMock);
assertEquals(categoryMock, category);
}
@Test
public void testUpdateCategoryById()
{
- given(categoriesMock.updateCategoryById(any(), any())).willReturn(categoryMock);
+ given(categoriesMock.updateCategoryById(any(), any(), any())).willCallRealMethod();
+ given(categoriesMock.updateCategoryById(any(), any(), any(), any())).willReturn(categoryMock);
// when
final Category actualCategory = objectUnderTest.update(CATEGORY_ID, categoryMock, parametersMock);
- then(categoriesMock).should().updateCategoryById(CATEGORY_ID, categoryMock);
- then(categoriesMock).shouldHaveNoMoreInteractions();
+ then(categoriesMock).should().updateCategoryById(STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID, categoryMock, parametersMock);
assertThat(actualCategory).isNotNull();
}
+
+ @Test
+ public void testDeleteCategoryById()
+ {
+ willCallRealMethod().given(categoriesMock).deleteCategoryById(any(), any());
+
+ // when
+ objectUnderTest.delete(CATEGORY_ID, parametersMock);
+
+ then(categoriesMock).should().deleteCategoryById(STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID, parametersMock);
+ }
}
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/categories/NodesCategoryLinksRelationTest.java b/remote-api/src/test/java/org/alfresco/rest/api/categories/NodesCategoryLinksRelationTest.java
index 6aa9b4afde..08152d478f 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/categories/NodesCategoryLinksRelationTest.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/categories/NodesCategoryLinksRelationTest.java
@@ -47,6 +47,7 @@ import org.mockito.junit.MockitoJUnitRunner;
public class NodesCategoryLinksRelationTest
{
private static final String CONTENT_ID = "content-node-id";
+ private static final String CATEGORY_ID = "category-id";
@Mock
private Categories categoriesMock;
@@ -61,12 +62,12 @@ public class NodesCategoryLinksRelationTest
@Test
public void testReadAll()
{
- given(categoriesMock.listCategoriesForNode(any())).willReturn(List.of(categoryMock));
+ given(categoriesMock.listCategoriesForNode(any(), any())).willReturn(List.of(categoryMock));
// when
final CollectionWithPagingInfo actualCategoriesPage = objectUnderTest.readAll(CONTENT_ID, parametersMock);
- then(categoriesMock).should().listCategoriesForNode(CONTENT_ID);
+ then(categoriesMock).should().listCategoriesForNode(CONTENT_ID, parametersMock);
then(categoriesMock).shouldHaveNoMoreInteractions();
assertThat(actualCategoriesPage)
.isNotNull()
@@ -77,15 +78,25 @@ public class NodesCategoryLinksRelationTest
@Test
public void testCreate()
{
- given(categoriesMock.linkNodeToCategories(any(), any())).willReturn(List.of(categoryMock));
+ given(categoriesMock.linkNodeToCategories(any(), any(), any())).willReturn(List.of(categoryMock));
// when
final List actualCategories = objectUnderTest.create(CONTENT_ID, List.of(categoryMock), parametersMock);
- then(categoriesMock).should().linkNodeToCategories(CONTENT_ID, List.of(categoryMock));
+ then(categoriesMock).should().linkNodeToCategories(CONTENT_ID, List.of(categoryMock), parametersMock);
then(categoriesMock).shouldHaveNoMoreInteractions();
assertThat(actualCategories)
.isNotNull()
.isEqualTo(List.of(categoryMock));
}
+
+ @Test
+ public void testDelete()
+ {
+ // when
+ objectUnderTest.delete(CONTENT_ID, CATEGORY_ID, parametersMock);
+
+ then(categoriesMock).should().unlinkNodeFromCategory(CONTENT_ID, CATEGORY_ID, parametersMock);
+ then(categoriesMock).shouldHaveNoMoreInteractions();
+ }
}
\ No newline at end of file
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/categories/SubcategoriesRelationTest.java b/remote-api/src/test/java/org/alfresco/rest/api/categories/SubcategoriesRelationTest.java
index 7b1948f7d2..8592017d63 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/categories/SubcategoriesRelationTest.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/categories/SubcategoriesRelationTest.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2022 Alfresco Software Limited
+ * 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
@@ -26,7 +26,10 @@
package org.alfresco.rest.api.categories;
+import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
@@ -37,8 +40,8 @@ import java.util.stream.IntStream;
import org.alfresco.rest.api.Categories;
import org.alfresco.rest.api.model.Category;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
-import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
@@ -67,39 +70,37 @@ public class SubcategoriesRelationTest
final Category categoryToCreate = Category.builder().name(CATEGORY_NAME).create();
final Category category = Category.builder().name(CATEGORY_NAME).parentId(PARENT_CATEGORY_ID).hasChildren(false).id(CATEGORY_ID).create();
final List categoriesToCreate = List.of(categoryToCreate);
- given(categoriesMock.createSubcategories(PARENT_CATEGORY_ID, categoriesToCreate, parametersMock)).willReturn(List.of(category));
+ given(categoriesMock.createSubcategories(any(), any(), any())).willCallRealMethod();
+ given(categoriesMock.createSubcategories(any(), any(), any(), any())).willReturn(List.of(category));
//when
List categories = objectUnderTest.create(PARENT_CATEGORY_ID, categoriesToCreate, parametersMock);
- then(categoriesMock).should().createSubcategories(PARENT_CATEGORY_ID, categoriesToCreate, parametersMock);
- then(categoriesMock).shouldHaveNoMoreInteractions();
+ then(categoriesMock).should().createSubcategories(STORE_REF_WORKSPACE_SPACESSTORE, PARENT_CATEGORY_ID, categoriesToCreate, parametersMock);
assertEquals(List.of(category), categories);
}
@Test
public void testGetCategoryChildren() {
- final CollectionWithPagingInfo categoryChildren = getCategories(3);
- given(categoriesMock.getCategoryChildren(PARENT_CATEGORY_ID, parametersMock)).willReturn(categoryChildren);
+ final List categoryChildren = getCategories(3);
+ given(categoriesMock.getCategoryChildren(any(), any())).willCallRealMethod();
+ given(categoriesMock.getCategoryChildren(any(), any(), any())).willReturn(categoryChildren);
//when
final CollectionWithPagingInfo returnedChildren = objectUnderTest.readAll(PARENT_CATEGORY_ID, parametersMock);
- then(categoriesMock).should().getCategoryChildren(PARENT_CATEGORY_ID, parametersMock);
- then(categoriesMock).shouldHaveNoMoreInteractions();
- assertEquals(categoryChildren, returnedChildren);
+ then(categoriesMock).should().getCategoryChildren(STORE_REF_WORKSPACE_SPACESSTORE, PARENT_CATEGORY_ID, parametersMock);
+ assertEquals(categoryChildren, returnedChildren.getCollection());
}
- private CollectionWithPagingInfo getCategories(final int count)
+ private List getCategories(final int count)
{
- return CollectionWithPagingInfo.asPaged(Paging.DEFAULT,
- IntStream.range(0, count)
- .mapToObj(i -> Category.builder().name(SUBCATEGORY_NAME_PREFIX + "-" + i)
- .parentId(PARENT_CATEGORY_ID)
- .hasChildren(false)
- .id(CATEGORY_ID + "-" + i)
- .create())
- .collect(Collectors.toList())
- );
+ return IntStream.range(0, count)
+ .mapToObj(i -> Category.builder().name(SUBCATEGORY_NAME_PREFIX + "-" + i)
+ .parentId(PARENT_CATEGORY_ID)
+ .hasChildren(false)
+ .id(CATEGORY_ID + "-" + i)
+ .create())
+ .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 80d110571a..9852d7da91 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
@@ -27,11 +27,13 @@
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.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;
import static org.alfresco.rest.api.impl.CategoriesImpl.NO_PERMISSION_TO_CHANGE_CONTENT;
import static org.alfresco.rest.api.impl.CategoriesImpl.NO_PERMISSION_TO_READ_CONTENT;
+import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.catchThrowable;
@@ -39,6 +41,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
@@ -64,7 +67,6 @@ import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.InvalidNodeTypeException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
-import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -77,6 +79,7 @@ import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
+import org.alfresco.util.Pair;
import org.alfresco.util.TypeConstraint;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
@@ -94,7 +97,7 @@ public class CategoriesImplTest
private static final String PARENT_ID = "parent-node-id";
private static final String CAT_ROOT_NODE_ID = "cat-root-node-id";
private static final NodeRef CATEGORY_NODE_REF = createNodeRefWithId(CATEGORY_ID);
- private static final Category CATEGORY = createDefaultCategoryWithName(CATEGORY_NAME);
+ 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);
@@ -103,8 +106,6 @@ public class CategoriesImplTest
@Mock
private NodeService nodeServiceMock;
@Mock
- private Parameters parametersMock;
- @Mock
private AuthorityService authorityServiceMock;
@Mock
private CategoryService categoryServiceMock;
@@ -116,6 +117,8 @@ public class CategoriesImplTest
private PermissionService permissionServiceMock;
@Mock
private TypeConstraint typeConstraint;
+ @Mock
+ private Parameters parametersMock;
@InjectMocks
private CategoriesImpl objectUnderTest;
@@ -130,12 +133,13 @@ public class CategoriesImplTest
given(typeConstraint.matches(any())).willReturn(true);
given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.ALLOWED);
given(permissionServiceMock.hasPermission(any(), any())).willReturn(AccessStatus.ALLOWED);
+ //given(parametersMock.getInclude()).willReturn(Co);
}
@Test
public void shouldNotGetRootCategoryById()
{
- final NodeRef categoryRootNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CAT_ROOT_NODE_ID);
+ final NodeRef categoryRootNodeRef = createNodeRefWithId(CAT_ROOT_NODE_ID);
given(nodesMock.validateNode(CAT_ROOT_NODE_ID)).willReturn(categoryRootNodeRef);
given(categoryChildAssociationRefMock.getQName()).willReturn(ContentModel.ASPECT_GEN_CLASSIFIABLE);
given(nodeServiceMock.getParentAssocs(categoryRootNodeRef)).willReturn(List.of(categoryChildAssociationRefMock));
@@ -155,31 +159,26 @@ public class CategoriesImplTest
@Test
public void testGetCategoryById_withChildren()
{
- final NodeRef categoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID);
- given(nodesMock.validateNode(CATEGORY_ID)).willReturn(categoryNodeRef);
- final Node categoryNode = new Node();
- categoryNode.setName(CATEGORY_NAME);
- categoryNode.setNodeId(CATEGORY_ID);
- final NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
- categoryNode.setParentId(parentNodeRef);
+ final NodeRef parentNodeRef = createNodeRefWithId(PARENT_ID);
+ final Node categoryNode = createNode(CATEGORY_NAME, CATEGORY_ID, parentNodeRef);
given(nodesMock.getNode(CATEGORY_ID)).willReturn(categoryNode);
- final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentNodeRef, null, categoryNodeRef);
- given(nodeServiceMock.getPrimaryParent(categoryNodeRef)).willReturn(parentAssoc);
+ final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentNodeRef, null, CATEGORY_NODE_REF);
+ given(nodeServiceMock.getPrimaryParent(CATEGORY_NODE_REF)).willReturn(parentAssoc);
final List dummyChildren = List.of(dummyChildAssociationRefMock);
- given(nodeServiceMock.getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
+ given(nodeServiceMock.getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
.willReturn(dummyChildren);
//when
final Category category = objectUnderTest.getCategoryById(CATEGORY_ID, parametersMock);
then(nodesMock).should().validateNode(CATEGORY_ID);
- then(nodesMock).should().isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false);
+ then(nodesMock).should().isSubClass(CATEGORY_NODE_REF, ContentModel.TYPE_CATEGORY, false);
then(nodesMock).should().getNode(CATEGORY_ID);
then(nodesMock).shouldHaveNoMoreInteractions();
- then(nodeServiceMock).should().getPrimaryParent(categoryNodeRef);
+ then(nodeServiceMock).should().getPrimaryParent(CATEGORY_NODE_REF);
then(nodeServiceMock).should().getParentAssocs(parentNodeRef);
- then(nodeServiceMock).should().getParentAssocs(categoryNodeRef);
- then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
+ then(nodeServiceMock).should().getParentAssocs(CATEGORY_NODE_REF);
+ then(nodeServiceMock).should().getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
then(nodeServiceMock).shouldHaveNoMoreInteractions();
then(categoryServiceMock).shouldHaveNoInteractions();
@@ -197,30 +196,25 @@ public class CategoriesImplTest
@Test
public void testGetCategoryById_withoutChildren()
{
- final NodeRef categoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID);
- given(nodesMock.validateNode(CATEGORY_ID)).willReturn(categoryNodeRef);
- final Node categoryNode = new Node();
- categoryNode.setName(CATEGORY_NAME);
- categoryNode.setNodeId(CATEGORY_ID);
- final NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
- categoryNode.setParentId(parentNodeRef);
+ final NodeRef parentNodeRef = createNodeRefWithId(PARENT_ID);
+ final Node categoryNode = createNode(CATEGORY_NAME, CATEGORY_ID, parentNodeRef);
given(nodesMock.getNode(CATEGORY_ID)).willReturn(categoryNode);
- final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentNodeRef, null, categoryNodeRef);
- given(nodeServiceMock.getPrimaryParent(categoryNodeRef)).willReturn(parentAssoc);
- given(nodeServiceMock.getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
+ final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentNodeRef, null, CATEGORY_NODE_REF);
+ given(nodeServiceMock.getPrimaryParent(CATEGORY_NODE_REF)).willReturn(parentAssoc);
+ given(nodeServiceMock.getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
.willReturn(Collections.emptyList());
//when
final Category category = objectUnderTest.getCategoryById(CATEGORY_ID, parametersMock);
then(nodesMock).should().validateNode(CATEGORY_ID);
- then(nodesMock).should().isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false);
+ then(nodesMock).should().isSubClass(CATEGORY_NODE_REF, ContentModel.TYPE_CATEGORY, false);
then(nodesMock).should().getNode(CATEGORY_ID);
then(nodesMock).shouldHaveNoMoreInteractions();
- then(nodeServiceMock).should().getPrimaryParent(categoryNodeRef);
+ then(nodeServiceMock).should().getPrimaryParent(CATEGORY_NODE_REF);
then(nodeServiceMock).should().getParentAssocs(parentNodeRef);
- then(nodeServiceMock).should().getParentAssocs(categoryNodeRef);
- then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
+ then(nodeServiceMock).should().getParentAssocs(CATEGORY_NODE_REF);
+ then(nodeServiceMock).should().getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
then(nodeServiceMock).shouldHaveNoMoreInteractions();
then(categoryServiceMock).shouldHaveNoInteractions();
@@ -235,6 +229,30 @@ public class CategoriesImplTest
assertEquals(expectedCategory, category);
}
+ @Test
+ public void testGetCategoryById_includeCount()
+ {
+ final QName categoryQName = createCmQNameOf(CATEGORY_NAME);
+ final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
+ final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName);
+ given(nodesMock.getNode(any())).willReturn(createNode());
+ given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
+ given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_COUNT_PARAM));
+ given(categoryServiceMock.getTopCategories(any(), any(), anyInt())).willReturn(List.of(new Pair<>(CATEGORY_NODE_REF, 1)));
+
+ // when
+ final Category actualCategory = objectUnderTest.getCategoryById(CATEGORY_ID, parametersMock);
+
+ then(categoryServiceMock).should().getTopCategories(STORE_REF_WORKSPACE_SPACESSTORE, ContentModel.ASPECT_GEN_CLASSIFIABLE, Integer.MAX_VALUE);
+ then(categoryServiceMock).shouldHaveNoMoreInteractions();
+
+ assertThat(actualCategory)
+ .isNotNull()
+ .extracting(Category::getCount)
+ .isNotNull()
+ .isEqualTo(1);
+ }
+
@Test
public void testGetCategoryById_notACategory()
{
@@ -274,14 +292,9 @@ public class CategoriesImplTest
public void testDeleteCategoryById_asAdmin()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
- final NodeRef categoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID);
+ final NodeRef categoryNodeRef = createNodeRefWithId(CATEGORY_ID);
given(nodesMock.validateNode(CATEGORY_ID)).willReturn(categoryNodeRef);
given(nodesMock.isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
- final Node categoryNode = new Node();
- categoryNode.setName(CATEGORY_NAME);
- categoryNode.setNodeId(CATEGORY_ID);
- final NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
- categoryNode.setParentId(parentNodeRef);
//when
objectUnderTest.deleteCategoryById(CATEGORY_ID, parametersMock);
@@ -317,7 +330,7 @@ public class CategoriesImplTest
public void testDeleteCategoryById_nonCategoryId()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
- final NodeRef categoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID);
+ final NodeRef categoryNodeRef = createNodeRefWithId(CATEGORY_ID);
given(nodesMock.validateNode(CATEGORY_ID)).willReturn(categoryNodeRef);
given(nodesMock.isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(false);
@@ -336,7 +349,7 @@ public class CategoriesImplTest
public void testDeleteCategoryById_rootCategory()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
- final NodeRef categoryRootNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CAT_ROOT_NODE_ID);
+ final NodeRef categoryRootNodeRef = createNodeRefWithId(CAT_ROOT_NODE_ID);
given(nodesMock.validateNode(CAT_ROOT_NODE_ID)).willReturn(categoryRootNodeRef);
given(nodesMock.isSubClass(categoryRootNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
given(categoryChildAssociationRefMock.getQName()).willReturn(ContentModel.ASPECT_GEN_CLASSIFIABLE);
@@ -359,13 +372,13 @@ public class CategoriesImplTest
@Test
public void testCreateCategoryUnderRoot()
{
- final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PATH_ROOT);
+ final NodeRef parentCategoryNodeRef = createNodeRefWithId(PATH_ROOT);
given(categoryServiceMock.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE))
.willReturn(Optional.of(parentCategoryNodeRef));
final NodeRef categoryNodeRef = createNodeRefWithId(CATEGORY_ID);
given(categoryServiceMock.createCategory(parentCategoryNodeRef, CATEGORY_NAME)).willReturn(categoryNodeRef);
- given(nodesMock.getNode(CATEGORY_ID)).willReturn(prepareCategoryNode());
- final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentCategoryNodeRef, null, categoryNodeRef);
+ given(nodesMock.getNode(CATEGORY_ID)).willReturn(createNode());
+ final ChildAssociationRef parentAssoc = createAssociationOf(parentCategoryNodeRef, categoryNodeRef);
given(nodeServiceMock.getPrimaryParent(categoryNodeRef)).willReturn(parentAssoc);
given(nodeServiceMock.getParentAssocs(parentCategoryNodeRef)).willReturn(List.of(parentAssoc));
given(nodeServiceMock.getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
@@ -400,12 +413,12 @@ public class CategoriesImplTest
@Test
public void testCreateCategory()
{
- final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
+ final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
final NodeRef categoryNodeRef = createNodeRefWithId(CATEGORY_ID);
given(categoryServiceMock.createCategory(parentCategoryNodeRef, CATEGORY_NAME)).willReturn(categoryNodeRef);
- given(nodesMock.getNode(CATEGORY_ID)).willReturn(prepareCategoryNode());
- final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentCategoryNodeRef, null, categoryNodeRef);
+ given(nodesMock.getNode(CATEGORY_ID)).willReturn(createNode());
+ final ChildAssociationRef parentAssoc = createAssociationOf(parentCategoryNodeRef, categoryNodeRef);
given(nodeServiceMock.getPrimaryParent(categoryNodeRef)).willReturn(parentAssoc);
given(nodeServiceMock.getParentAssocs(parentCategoryNodeRef)).willReturn(List.of(parentAssoc));
given(nodeServiceMock.getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
@@ -438,6 +451,35 @@ public class CategoriesImplTest
assertEquals(expectedCategory, createdCategory);
}
+ @Test
+ public void testCreateCategory_includeCount()
+ {
+ 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);
+ 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_COUNT_PARAM));
+ final List categoryModels = prepareCategories().stream().peek(category -> category.setCount(1)).collect(Collectors.toList());
+
+ // 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::getCount)
+ .isNotNull()
+ .isEqualTo(0);
+ }
+
@Test
public void testCreateCategories_noPermissions()
{
@@ -494,7 +536,7 @@ public class CategoriesImplTest
@Test
public void testGetRootCategoryChildren()
{
- final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PATH_ROOT);
+ final NodeRef parentCategoryNodeRef = createNodeRefWithId(PATH_ROOT);
given(categoryServiceMock.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE))
.willReturn(Optional.of(parentCategoryNodeRef));
final int childrenCount = 3;
@@ -503,7 +545,7 @@ public class CategoriesImplTest
childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks);
//when
- final CollectionWithPagingInfo categoryChildren = objectUnderTest.getCategoryChildren(PATH_ROOT, parametersMock);
+ final List categoryChildren = objectUnderTest.getCategoryChildren(PATH_ROOT, parametersMock);
then(categoryServiceMock).should().getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
then(categoryServiceMock).shouldHaveNoMoreInteractions();
@@ -521,16 +563,14 @@ public class CategoriesImplTest
then(authorityServiceMock).shouldHaveNoInteractions();
- assertEquals(childAssociationRefMocks.size(), categoryChildren.getTotalItems().intValue());
- final List categoryChildrenList = new ArrayList<>(categoryChildren.getCollection());
- assertEquals(childAssociationRefMocks.size(), categoryChildrenList.size());
- IntStream.range(0, childrenCount).forEach(i -> doCategoryAssertions(categoryChildrenList.get(i), i, PATH_ROOT));
+ assertEquals(childAssociationRefMocks.size(), categoryChildren.size());
+ IntStream.range(0, childrenCount).forEach(i -> doCategoryAssertions(categoryChildren.get(i), i, PATH_ROOT));
}
@Test
public void testGetCategoryChildren()
{
- final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
+ 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;
@@ -539,7 +579,7 @@ public class CategoriesImplTest
childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks);
//when
- final CollectionWithPagingInfo categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
+ final List categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
then(nodesMock).should().validateNode(PARENT_ID);
then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
@@ -558,24 +598,47 @@ public class CategoriesImplTest
then(authorityServiceMock).shouldHaveNoInteractions();
then(categoryServiceMock).shouldHaveNoInteractions();
- assertEquals(childAssociationRefMocks.size(), categoryChildren.getTotalItems().intValue());
- final List categoryChildrenList = new ArrayList<>(categoryChildren.getCollection());
- assertEquals(childAssociationRefMocks.size(), categoryChildrenList.size());
- IntStream.range(0, childrenCount).forEach(i -> doCategoryAssertions(categoryChildrenList.get(i), i, PARENT_ID));
+ assertEquals(childAssociationRefMocks.size(), categoryChildren.size());
+ IntStream.range(0, childrenCount).forEach(i -> doCategoryAssertions(categoryChildren.get(i), i, PARENT_ID));
+ }
+
+ @Test
+ public void testGetCategoryChildren_includeCount()
+ {
+ 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);
+ given(nodeServiceMock.getChildAssocs(parentCategoryNodeRef)).willReturn(childAssociationRefMocks);
+ childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks);
+ given(parametersMock.getInclude()).willReturn(List.of(INCLUDE_COUNT_PARAM));
+ given(categoryServiceMock.getTopCategories(any(), any(), anyInt())).willReturn(List.of(new Pair<>(createNodeRefWithId(CATEGORY_ID.concat("-1")), 2)));
+
+ // when
+ final List actualCategoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
+
+ then(categoryServiceMock).should().getTopCategories(STORE_REF_WORKSPACE_SPACESSTORE, ContentModel.ASPECT_GEN_CLASSIFIABLE, Integer.MAX_VALUE);
+ then(categoryServiceMock).shouldHaveNoMoreInteractions();
+
+ assertThat(actualCategoryChildren)
+ .isNotNull()
+ .hasSize(3)
+ .extracting(Category::getCount)
+ .isNotNull()
+ .isEqualTo(List.of(0, 2, 0));
}
@Test
public void testGetCategoryChildren_noChildren()
{
- final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
+ final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
-
given(nodeServiceMock.getChildAssocs(parentCategoryNodeRef)).willReturn(Collections.emptyList());
-
//when
- final CollectionWithPagingInfo categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
+ final List categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
then(nodesMock).should().validateNode(PARENT_ID);
then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
@@ -586,13 +649,13 @@ public class CategoriesImplTest
then(authorityServiceMock).shouldHaveNoInteractions();
then(categoryServiceMock).shouldHaveNoInteractions();
- assertEquals(0, categoryChildren.getTotalItems().intValue());
+ assertEquals(0, categoryChildren.size());
}
@Test
public void testGetCategoryChildren_wrongParentNodeType()
{
- final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
+ final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(false);
@@ -633,12 +696,12 @@ public class CategoriesImplTest
final QName categoryQName = createCmQNameOf(CATEGORY_NAME);
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName);
- given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(categoryNewName));
+ 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)));
// when
- final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, fixedCategory);
+ final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, fixedCategory, parametersMock);
then(authorityServiceMock).should().hasAdminAuthority();
then(authorityServiceMock).shouldHaveNoMoreInteractions();
@@ -661,13 +724,41 @@ public class CategoriesImplTest
.isEqualTo(expectedCategory);
}
+ @Test
+ public void testUpdateCategoryById_includeCount()
+ {
+ final String categoryNewName = "categoryNewName";
+ final Category fixedCategory = createCategoryOnlyWithName(categoryNewName);
+ fixedCategory.setCount(9);
+ final QName categoryQName = createCmQNameOf(CATEGORY_NAME);
+ final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
+ final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName);
+ 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_COUNT_PARAM));
+ given(categoryServiceMock.getTopCategories(any(), any(), anyInt())).willReturn(List.of(new Pair<>(CATEGORY_NODE_REF, 1)));
+
+ // when
+ final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, fixedCategory, parametersMock);
+
+ then(categoryServiceMock).should().getTopCategories(STORE_REF_WORKSPACE_SPACESSTORE, ContentModel.ASPECT_GEN_CLASSIFIABLE, Integer.MAX_VALUE);
+ then(categoryServiceMock).shouldHaveNoMoreInteractions();
+
+ assertThat(actualCategory)
+ .isNotNull()
+ .extracting(Category::getCount)
+ .isNotNull()
+ .isEqualTo(1);
+ }
+
@Test
public void testUpdateCategoryById_noPermission()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(false);
// when
- assertThatExceptionOfType(PermissionDeniedException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY));
+ assertThatExceptionOfType(PermissionDeniedException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY, parametersMock));
then(nodesMock).shouldHaveNoInteractions();
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -679,7 +770,7 @@ public class CategoriesImplTest
given(nodesMock.validateNode(any(String.class))).willThrow(EntityNotFoundException.class);
// when
- assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY));
+ assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY, parametersMock));
then(nodeServiceMock).shouldHaveNoInteractions();
}
@@ -690,7 +781,7 @@ public class CategoriesImplTest
given(nodesMock.isSubClass(any(), any(), eq(false))).willReturn(false);
// when
- assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY))
+ assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY, parametersMock))
.withMessageContaining(NOT_A_VALID_CATEGORY);
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -704,7 +795,7 @@ public class CategoriesImplTest
given(categoryChildAssociationRefMock.getQName()).willReturn(ContentModel.ASPECT_GEN_CLASSIFIABLE);
// when
- assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(PATH_ROOT, CATEGORY))
+ assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(PATH_ROOT, CATEGORY, parametersMock))
.withMessageContaining(NOT_A_VALID_CATEGORY);
then(categoryServiceMock).should().getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
@@ -727,7 +818,7 @@ public class CategoriesImplTest
final Category categoryWithoutName = createCategoryOnlyWithName(invalidName);
// when
- assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithoutName))
+ assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithoutName, parametersMock))
.withMessageContaining(NOT_NULL_OR_EMPTY);
}
}
@@ -741,12 +832,12 @@ public class CategoriesImplTest
final QName categoryQName = createCmQNameOf(CATEGORY_NAME);
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName);
- given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(categoryNewName));
+ 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)));
// when
- final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithInvalidId);
+ final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithInvalidId, parametersMock);
final Category expectedCategory = createDefaultCategoryWithName(categoryNewName);
assertThat(actualCategory)
@@ -763,12 +854,12 @@ public class CategoriesImplTest
final QName categoryQName = createCmQNameOf(CATEGORY_NAME);
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName);
- given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(categoryNewName));
+ 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)));
// when
- final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithInvalidParentId);
+ final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithInvalidParentId, parametersMock);
final Category expectedCategory = createDefaultCategoryWithName(categoryNewName);
assertThat(actualCategory)
@@ -785,12 +876,12 @@ public class CategoriesImplTest
final QName categoryQName = createCmQNameOf(CATEGORY_NAME);
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(parentCategoryNodeRef, CATEGORY_NODE_REF, categoryQName);
- given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(categoryNewName));
+ 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)));
// when
- final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithInvalidHasChildren);
+ final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithInvalidHasChildren, parametersMock);
final Category expectedCategory = createDefaultCategoryWithName(categoryNewName);
assertThat(actualCategory)
@@ -804,11 +895,11 @@ public class CategoriesImplTest
final List categoryLinks = List.of(CATEGORY);
final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF);
- given(nodesMock.getNode(any())).willReturn(prepareCategoryNode());
+ given(nodesMock.getNode(any())).willReturn(createNode());
given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
// when
- final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks);
+ final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock);
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS);
@@ -838,12 +929,12 @@ public class CategoriesImplTest
{
final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF);
- given(nodesMock.getNode(any())).willReturn(prepareCategoryNode());
+ given(nodesMock.getNode(any())).willReturn(createNode());
given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
given(nodeServiceMock.hasAspect(any(), any())).willReturn(true);
// when
- final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY));
+ final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock);
then(nodesMock).should().getNode(CATEGORY_ID);
then(nodeServiceMock).should().getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
@@ -873,11 +964,11 @@ public class CategoriesImplTest
final ChildAssociationRef categoryParentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF);
final ChildAssociationRef secondCategoryParentAssociation = createAssociationOf(categoryParentNodeRef, secondCategoryNodeRef);
given(nodesMock.validateNode(secondCategoryId)).willReturn(secondCategoryNodeRef);
- given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(), prepareCategoryNode(secondCategoryName));
+ given(nodesMock.getNode(any())).willReturn(createNode(), createNode(secondCategoryName));
given(nodeServiceMock.getPrimaryParent(any())).willReturn(categoryParentAssociation, secondCategoryParentAssociation);
// when
- final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks);
+ final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock);
then(nodesMock).should().validateNode(CATEGORY_ID);
then(nodesMock).should().validateNode(secondCategoryId);
@@ -902,13 +993,13 @@ public class CategoriesImplTest
final Serializable previousCategories = (Serializable) List.of(otherCategoryNodeRef);
final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF);
- given(nodesMock.getNode(any())).willReturn(prepareCategoryNode());
+ given(nodesMock.getNode(any())).willReturn(createNode());
given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
given(nodeServiceMock.hasAspect(any(), any())).willReturn(true);
given(nodeServiceMock.getProperty(any(), eq(ContentModel.PROP_CATEGORIES))).willReturn(previousCategories);
// when
- final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY));
+ final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock);
final Serializable expectedCategories = (Serializable) Set.of(otherCategoryNodeRef, CATEGORY_NODE_REF);
then(nodeServiceMock).should().setProperty(CONTENT_NODE_REF, ContentModel.PROP_CATEGORIES, expectedCategories);
@@ -924,7 +1015,7 @@ public class CategoriesImplTest
given(nodesMock.validateNode(CONTENT_NODE_ID)).willThrow(EntityNotFoundException.class);
// when
- final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY)));
+ final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock));
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).shouldHaveNoInteractions();
@@ -939,7 +1030,7 @@ public class CategoriesImplTest
given(permissionServiceMock.hasPermission(any(), any())).willReturn(AccessStatus.DENIED);
// when
- final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY)));
+ final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock));
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS);
@@ -954,9 +1045,8 @@ public class CategoriesImplTest
{
given(typeConstraint.matches(any())).willReturn(false);
-
// when
- final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY)));
+ final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock));
then(typeConstraint).should().matches(CONTENT_NODE_REF);
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -971,7 +1061,7 @@ public class CategoriesImplTest
final List categoryLinks = Collections.emptyList();
// when
- final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks));
+ final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock));
then(nodesMock).shouldHaveNoInteractions();
then(permissionServiceMock).shouldHaveNoInteractions();
@@ -992,7 +1082,7 @@ public class CategoriesImplTest
categoryLinks.add(categoryLinkWithEmptyId);
// when
- final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks));
+ final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock));
then(nodeServiceMock).shouldHaveNoInteractions();
assertThat(actualException)
@@ -1006,11 +1096,11 @@ public class CategoriesImplTest
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(nodesMock.getNode(any())).willReturn(createNode());
given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
// when
- final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks);
+ final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock);
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);
@@ -1045,7 +1135,7 @@ public class CategoriesImplTest
given(nodeServiceMock.hasAspect(CONTENT_NODE_REF, ContentModel.ASPECT_GEN_CLASSIFIABLE)).willReturn(false);
//when
- final Throwable actualException = catchThrowable(() -> objectUnderTest.unlinkNodeFromCategory(CONTENT_NODE_ID,CATEGORY_ID, parametersMock));
+ final Throwable actualException = catchThrowable(() -> objectUnderTest.unlinkNodeFromCategory(CONTENT_NODE_ID, CATEGORY_ID, parametersMock));
then(nodeServiceMock).should().hasAspect(CONTENT_NODE_REF,ContentModel.ASPECT_GEN_CLASSIFIABLE);
then(nodeServiceMock).shouldHaveNoMoreInteractions();
@@ -1060,11 +1150,11 @@ public class CategoriesImplTest
final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF);
given(nodeServiceMock.getProperty(any(), eq(ContentModel.PROP_CATEGORIES))).willReturn((Serializable) List.of(CATEGORY_NODE_REF));
- given(nodesMock.getNode(any())).willReturn(prepareCategoryNode());
+ given(nodesMock.getNode(any())).willReturn(createNode());
given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
// when
- final List actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID);
+ final List actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock);
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF);
@@ -1090,7 +1180,7 @@ public class CategoriesImplTest
given(nodesMock.validateNode(CONTENT_NODE_ID)).willThrow(EntityNotFoundException.class);
// when
- final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID));
+ final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock));
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -1104,7 +1194,7 @@ public class CategoriesImplTest
given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.DENIED);
// when
- final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID));
+ final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock));
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF);
@@ -1120,7 +1210,7 @@ public class CategoriesImplTest
given(typeConstraint.matches(any())).willReturn(false);
// when
- final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID));
+ final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock));
then(typeConstraint).should().matches(CONTENT_NODE_REF);
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -1136,45 +1226,19 @@ public class CategoriesImplTest
given(nodeServiceMock.getProperty(any(), eq(ContentModel.PROP_CATEGORIES))).willReturn((Serializable) nullOrEmptyList);
// when
- final List actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID);
+ final List actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock);
assertThat(actualCategories).isNotNull().isEmpty();
});
}
- private Node prepareCategoryNode(final String name, final String id, final NodeRef parentNodeRef)
- {
- final Node categoryNode = new Node();
- categoryNode.setName(name);
- categoryNode.setNodeId(id);
- categoryNode.setParentId(parentNodeRef);
- return categoryNode;
- }
-
- private Node prepareCategoryNode(final String name)
- {
- return prepareCategoryNode(name, CATEGORY_ID, createNodeRefWithId(PARENT_ID));
- }
-
- private Node prepareCategoryNode()
- {
- return prepareCategoryNode(CATEGORY_NAME);
- }
-
- private List prepareCategories()
- {
- return List.of(Category.builder()
- .name(CATEGORY_NAME)
- .create());
- }
-
private List prepareChildAssocMocks(final int count, NodeRef parentCategoryNodeRef)
{
return IntStream.range(0, count).mapToObj(i -> {
ChildAssociationRef dummyChildAssocMock = mock(ChildAssociationRef.class);
given(dummyChildAssocMock.getTypeQName()).willReturn(ContentModel.ASSOC_SUBCATEGORIES);
given(dummyChildAssocMock.getChildRef())
- .willReturn(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID + "-" + i));
+ .willReturn(createNodeRefWithId(CATEGORY_ID + "-" + i));
given(dummyChildAssocMock.getParentRef()).willReturn(parentCategoryNodeRef);
return dummyChildAssocMock;
}).collect(Collectors.toList());
@@ -1186,8 +1250,8 @@ public class CategoriesImplTest
final String id = childRef.getId();
final String name = id.replace(CATEGORY_ID, CATEGORY_NAME);
final NodeRef parentRef = childAssociationRef.getParentRef();
- given(nodesMock.getNode(id)).willReturn(prepareCategoryNode(name, id, parentRef));
- final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentRef, null, childRef);
+ given(nodesMock.getNode(id)).willReturn(createNode(name, id, parentRef));
+ final ChildAssociationRef parentAssoc = createAssociationOf(parentRef, childRef);
given(nodeServiceMock.getPrimaryParent(childRef)).willReturn(parentAssoc);
given(nodeServiceMock.getParentAssocs(parentRef)).willReturn(List.of(parentAssoc));
}
@@ -1195,14 +1259,38 @@ public class CategoriesImplTest
private void doCategoryAssertions(final Category category, final int index, final String parentId)
{
final Category expectedCategory = Category.builder()
- .id(CATEGORY_ID + "-" + index)
- .name(CATEGORY_NAME + "-" + index)
- .parentId(parentId)
- .hasChildren(false)
- .create();
+ .id(CATEGORY_ID + "-" + index)
+ .name(CATEGORY_NAME + "-" + index)
+ .parentId(parentId)
+ .hasChildren(false)
+ .create();
assertEquals(expectedCategory, category);
}
+ private List prepareCategories()
+ {
+ return List.of(createCategoryOnlyWithName(CATEGORY_NAME));
+ }
+
+ private static Node createNode(final String name, final String id, final NodeRef parentNodeRef)
+ {
+ final Node categoryNode = new Node();
+ categoryNode.setName(name);
+ categoryNode.setNodeId(id);
+ categoryNode.setParentId(parentNodeRef);
+ return categoryNode;
+ }
+
+ private static Node createNode(final String name)
+ {
+ return createNode(name, CATEGORY_ID, createNodeRefWithId(PARENT_ID));
+ }
+
+ private static Node createNode()
+ {
+ return createNode(CATEGORY_NAME);
+ }
+
private static NodeRef createNodeRefWithId(final String id)
{
return new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id);
@@ -1213,6 +1301,11 @@ public class CategoriesImplTest
return Category.builder().name(name).create();
}
+ private static Category createDefaultCategory()
+ {
+ return createDefaultCategoryWithName(CATEGORY_NAME);
+ }
+
private static Category createDefaultCategoryWithName(final String name)
{
return Category.builder()
diff --git a/repository/src/main/java/org/alfresco/service/cmr/search/CategoryService.java b/repository/src/main/java/org/alfresco/service/cmr/search/CategoryService.java
index 410221f23d..91c9853aea 100644
--- a/repository/src/main/java/org/alfresco/service/cmr/search/CategoryService.java
+++ b/repository/src/main/java/org/alfresco/service/cmr/search/CategoryService.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * 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