mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
ACS-4032 Create category (POST) (#1606)
* ACS-4028 Get category by id (#1591) * ACS-4028: Get category by id endpoint. * ACS-4028: Get category by id endpoint. * ACS-4028: Get category by id endpoint - integration TAS tests. * ACS-4028: Get category by id endpoint - refactoring. * ACS-4028: Adding test to test suite. * ACS-4028: Fixes after code review. * ACS-4032: Initial code for POST category endpoint. * ACS-4032: Full implementation for POST category endpoint + tests. * ACS-4032: Some fixes and refactors after code review.
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package org.alfresco.rest.model;
|
package org.alfresco.rest.model;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.alfresco.rest.core.IRestModel;
|
import org.alfresco.rest.core.IRestModel;
|
||||||
import org.alfresco.utility.model.TestModel;
|
import org.alfresco.utility.model.TestModel;
|
||||||
@@ -47,8 +49,7 @@ This must be unique within the parent category.
|
|||||||
private boolean hasChildren;
|
private boolean hasChildren;
|
||||||
/**
|
/**
|
||||||
The number of nodes that are assigned to this category.
|
The number of nodes that are assigned to this category.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private long count;
|
private long count;
|
||||||
|
|
||||||
public String getId()
|
public String getId()
|
||||||
@@ -99,6 +100,33 @@ This must be unique within the parent category.
|
|||||||
public void setCount(long count)
|
public void setCount(long count)
|
||||||
{
|
{
|
||||||
this.count = count;
|
this.count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
RestCategoryModel that = (RestCategoryModel) o;
|
||||||
|
return Objects.equals(id, that.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "RestCategoryModel{" +
|
||||||
|
"id='" + id + '\'' +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", parentId='" + parentId + '\'' +
|
||||||
|
", hasChildren=" + hasChildren +
|
||||||
|
", count=" + count +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Remote API
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.rest.model;
|
||||||
|
|
||||||
|
import org.alfresco.rest.core.RestModels;
|
||||||
|
|
||||||
|
public class RestCategoryModelsCollection extends RestModels<RestCategoryModel, RestCandidateModelsCollection>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@@ -25,9 +25,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.rest.requests;
|
package org.alfresco.rest.requests;
|
||||||
|
|
||||||
|
import static org.alfresco.rest.core.JsonBodyGenerator.arrayToJson;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.alfresco.rest.core.RestRequest;
|
import org.alfresco.rest.core.RestRequest;
|
||||||
import org.alfresco.rest.core.RestWrapper;
|
import org.alfresco.rest.core.RestWrapper;
|
||||||
import org.alfresco.rest.model.RestCategoryModel;
|
import org.alfresco.rest.model.RestCategoryModel;
|
||||||
|
import org.alfresco.rest.model.RestCategoryModelsCollection;
|
||||||
|
import org.alfresco.rest.model.RestRuleModelsCollection;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
public class Categories extends ModelRequest<Categories>
|
public class Categories extends ModelRequest<Categories>
|
||||||
@@ -43,7 +49,7 @@ public class Categories extends ModelRequest<Categories>
|
|||||||
/**
|
/**
|
||||||
* Retrieves a category with ID using GET call on using GET call on "/tags/{tagId}"
|
* Retrieves a category with ID using GET call on using GET call on "/tags/{tagId}"
|
||||||
*
|
*
|
||||||
* @return
|
* @return RestCategoryModel
|
||||||
*/
|
*/
|
||||||
public RestCategoryModel getCategory()
|
public RestCategoryModel getCategory()
|
||||||
{
|
{
|
||||||
@@ -52,4 +58,26 @@ public class Categories extends ModelRequest<Categories>
|
|||||||
return restWrapper.processModel(RestCategoryModel.class, request);
|
return restWrapper.processModel(RestCategoryModel.class, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create several categories in one request.
|
||||||
|
*
|
||||||
|
* @param restCategoryModels The list of categories to create.
|
||||||
|
* @return The list of created categories with additional data populated by the repository.
|
||||||
|
*/
|
||||||
|
public RestCategoryModelsCollection createCategoriesList(List<RestCategoryModel> restCategoryModels) {
|
||||||
|
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, arrayToJson(restCategoryModels), "categories/{categoryId}/subcategories", category.getId());
|
||||||
|
return restWrapper.processModels(RestCategoryModelsCollection.class, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create single category.
|
||||||
|
*
|
||||||
|
* @param restCategoryModel The categories to create.
|
||||||
|
* @return Created category with additional data populated by the repository.
|
||||||
|
*/
|
||||||
|
public RestCategoryModel createSingleCategory(RestCategoryModel restCategoryModel) {
|
||||||
|
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, restCategoryModel.toJson(), "categories/{categoryId}/subcategories", category.getId());
|
||||||
|
return restWrapper.processModel(RestCategoryModel.class, request);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Remote API
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.rest.categories;
|
||||||
|
|
||||||
|
import static org.alfresco.utility.report.log.Step.STEP;
|
||||||
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
|
import static org.springframework.http.HttpStatus.CREATED;
|
||||||
|
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
||||||
|
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import org.alfresco.rest.RestTest;
|
||||||
|
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;
|
||||||
|
import org.alfresco.utility.model.UserModel;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class CreateCategoriesTests extends RestTest
|
||||||
|
{
|
||||||
|
private static final String FIELD_NAME = "name";
|
||||||
|
private static final String FIELD_PARENT_ID = "parentId";
|
||||||
|
private static final String FIELD_HAS_CHILDREN = "hasChildren";
|
||||||
|
private static final String FIELD_ID = "id";
|
||||||
|
private UserModel user;
|
||||||
|
|
||||||
|
@BeforeClass(alwaysRun = true)
|
||||||
|
public void dataPreparation() throws Exception
|
||||||
|
{
|
||||||
|
STEP("Create a user");
|
||||||
|
user = dataUser.createRandomTestUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check we can create a category as direct child of root category
|
||||||
|
*/
|
||||||
|
@Test(groups = {TestGroup.REST_API})
|
||||||
|
public void testCreateCategoryUnderRoot()
|
||||||
|
{
|
||||||
|
STEP("Create a category under root category (as admin)");
|
||||||
|
final RestCategoryModel rootCategory = new RestCategoryModel();
|
||||||
|
rootCategory.setId("-root-");
|
||||||
|
final RestCategoryModel aCategory = new RestCategoryModel();
|
||||||
|
aCategory.setName(RandomData.getRandomName("Category"));
|
||||||
|
final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
|
||||||
|
.withCoreAPI()
|
||||||
|
.usingCategory(rootCategory)
|
||||||
|
.createSingleCategory(aCategory);
|
||||||
|
restClient.assertStatusCodeIs(CREATED);
|
||||||
|
|
||||||
|
createdCategory.assertThat().field(FIELD_NAME).is(aCategory.getName());
|
||||||
|
createdCategory.assertThat().field(FIELD_PARENT_ID).is(rootCategory.getId());
|
||||||
|
createdCategory.assertThat().field(FIELD_HAS_CHILDREN).is(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check we can create several categories as children of a created category
|
||||||
|
*/
|
||||||
|
@Test(groups = {TestGroup.REST_API})
|
||||||
|
public void testCreateSeveralSubCategories()
|
||||||
|
{
|
||||||
|
STEP("Create a category under root category (as admin)");
|
||||||
|
final RestCategoryModel rootCategory = new RestCategoryModel();
|
||||||
|
rootCategory.setId("-root-");
|
||||||
|
final RestCategoryModel aCategory = new RestCategoryModel();
|
||||||
|
aCategory.setName(RandomData.getRandomName("Category"));
|
||||||
|
final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
|
||||||
|
.withCoreAPI()
|
||||||
|
.usingCategory(rootCategory)
|
||||||
|
.createSingleCategory(aCategory);
|
||||||
|
restClient.assertStatusCodeIs(CREATED);
|
||||||
|
|
||||||
|
createdCategory.assertThat().field(FIELD_NAME).is(aCategory.getName())
|
||||||
|
.assertThat().field(FIELD_PARENT_ID).is(rootCategory.getId())
|
||||||
|
.assertThat().field(FIELD_HAS_CHILDREN).is(false)
|
||||||
|
.assertThat().field(FIELD_ID).isNotEmpty();
|
||||||
|
|
||||||
|
STEP("Create two categories under the previously created (as admin)");
|
||||||
|
final int categoriesNumber = 2;
|
||||||
|
final List<RestCategoryModel> categoriesToCreate = getCategoriesToCreate(categoriesNumber);
|
||||||
|
final RestCategoryModelsCollection createdSubCategories = restClient.authenticateUser(dataUser.getAdminUser())
|
||||||
|
.withCoreAPI()
|
||||||
|
.usingCategory(createdCategory)
|
||||||
|
.createCategoriesList(categoriesToCreate);
|
||||||
|
restClient.assertStatusCodeIs(CREATED);
|
||||||
|
|
||||||
|
createdSubCategories.assertThat()
|
||||||
|
.entriesListCountIs(categoriesToCreate.size());
|
||||||
|
IntStream.range(0, categoriesNumber)
|
||||||
|
.forEach(i -> createdSubCategories.getEntries().get(i).onModel()
|
||||||
|
.assertThat().field(FIELD_NAME).is(categoriesToCreate.get(i).getName())
|
||||||
|
.assertThat().field(FIELD_PARENT_ID).is(createdCategory.getId())
|
||||||
|
.assertThat().field(FIELD_HAS_CHILDREN).is(false)
|
||||||
|
.assertThat().field(FIELD_ID).isNotEmpty()
|
||||||
|
);
|
||||||
|
|
||||||
|
STEP("Get the parent category and check if it now has children (as regular user)");
|
||||||
|
final RestCategoryModel parentCategoryFromGet = restClient.authenticateUser(user)
|
||||||
|
.withCoreAPI()
|
||||||
|
.usingCategory(createdCategory)
|
||||||
|
.getCategory();
|
||||||
|
|
||||||
|
parentCategoryFromGet.assertThat().field(FIELD_HAS_CHILDREN).is(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check we cannot create a category as direct child of root category as non-admin user
|
||||||
|
*/
|
||||||
|
@Test(groups = {TestGroup.REST_API})
|
||||||
|
public void testCreateCategoryUnderRootAsRegularUser_andFail()
|
||||||
|
{
|
||||||
|
STEP("Create a category under root category (as user)");
|
||||||
|
final RestCategoryModel rootCategory = new RestCategoryModel();
|
||||||
|
rootCategory.setId("-root-");
|
||||||
|
final RestCategoryModel aCategory = new RestCategoryModel();
|
||||||
|
aCategory.setName(RandomData.getRandomName("Category"));
|
||||||
|
restClient.authenticateUser(user)
|
||||||
|
.withCoreAPI()
|
||||||
|
.usingCategory(rootCategory)
|
||||||
|
.createSingleCategory(aCategory);
|
||||||
|
restClient.assertStatusCodeIs(FORBIDDEN).assertLastError().containsSummary("Current user does not have permission to create a category");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check we cannot create a category under non existing parent node
|
||||||
|
*/
|
||||||
|
@Test(groups = {TestGroup.REST_API})
|
||||||
|
public void testCreateCategoryUnderNonExistingParent_andFail()
|
||||||
|
{
|
||||||
|
STEP("Create a category under non existing category node (as admin)");
|
||||||
|
final RestCategoryModel rootCategory = new RestCategoryModel();
|
||||||
|
final String id = "non-existing-node-id";
|
||||||
|
rootCategory.setId(id);
|
||||||
|
final RestCategoryModel aCategory = new RestCategoryModel();
|
||||||
|
aCategory.setName(RandomData.getRandomName("Category"));
|
||||||
|
restClient.authenticateUser(dataUser.getAdminUser())
|
||||||
|
.withCoreAPI()
|
||||||
|
.usingCategory(rootCategory)
|
||||||
|
.createSingleCategory(aCategory);
|
||||||
|
restClient.assertStatusCodeIs(NOT_FOUND).assertLastError().containsSummary("The entity with id: " + id + " was not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check we cannot create a category under a node which is not a category
|
||||||
|
*/
|
||||||
|
@Test(groups = {TestGroup.REST_API})
|
||||||
|
public void testCreateCategoryUnderFolderNode_andFail()
|
||||||
|
{
|
||||||
|
STEP("Create a site and a folder inside it");
|
||||||
|
final SiteModel site = dataSite.usingUser(user).createPublicRandomSite();
|
||||||
|
final FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||||
|
|
||||||
|
STEP("Create a category under folder node (as admin)");
|
||||||
|
final RestCategoryModel rootCategory = new RestCategoryModel();
|
||||||
|
rootCategory.setId(folder.getNodeRef());
|
||||||
|
final RestCategoryModel aCategory = new RestCategoryModel();
|
||||||
|
aCategory.setName(RandomData.getRandomName("Category"));
|
||||||
|
restClient.authenticateUser(dataUser.getAdminUser())
|
||||||
|
.withCoreAPI()
|
||||||
|
.usingCategory(rootCategory)
|
||||||
|
.createSingleCategory(aCategory);
|
||||||
|
restClient.assertStatusCodeIs(BAD_REQUEST).assertLastError().containsSummary("Node id does not refer to a valid category");
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<RestCategoryModel> getCategoriesToCreate(final int count)
|
||||||
|
{
|
||||||
|
return IntStream.range(0, count)
|
||||||
|
.mapToObj(i -> {
|
||||||
|
final RestCategoryModel aSubCategory = new RestCategoryModel();
|
||||||
|
aSubCategory.setName((RandomData.getRandomName("SubCategory")));
|
||||||
|
return aSubCategory;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@@ -29,6 +29,7 @@ package org.alfresco.rest.categories;
|
|||||||
import static org.alfresco.utility.report.log.Step.STEP;
|
import static org.alfresco.utility.report.log.Step.STEP;
|
||||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||||
|
import static org.springframework.http.HttpStatus.OK;
|
||||||
|
|
||||||
import org.alfresco.rest.RestTest;
|
import org.alfresco.rest.RestTest;
|
||||||
import org.alfresco.rest.model.RestCategoryModel;
|
import org.alfresco.rest.model.RestCategoryModel;
|
||||||
@@ -50,6 +51,19 @@ public class GetCategoriesTests extends RestTest
|
|||||||
user = dataUser.createRandomTestUser();
|
user = dataUser.createRandomTestUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check we can get a category which we just created in as direct child of root category
|
||||||
|
*/
|
||||||
|
@Test(groups = {TestGroup.REST_API})
|
||||||
|
public void testGetCategoryById()
|
||||||
|
{
|
||||||
|
STEP("Get category with -root- as id (which does not exist)");
|
||||||
|
final RestCategoryModel rootCategory = new RestCategoryModel();
|
||||||
|
rootCategory.setId("-root-");
|
||||||
|
restClient.authenticateUser(user).withCoreAPI().usingCategory(rootCategory).getCategory();
|
||||||
|
restClient.assertStatusCodeIs(NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check we get an error when passing -root- as category id
|
* Check we get an error when passing -root- as category id
|
||||||
*/
|
*/
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
package org.alfresco.rest.api;
|
package org.alfresco.rest.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.alfresco.rest.api.model.Category;
|
import org.alfresco.rest.api.model.Category;
|
||||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||||
import org.alfresco.service.Experimental;
|
import org.alfresco.service.Experimental;
|
||||||
@@ -35,4 +37,6 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
public interface Categories
|
public interface Categories
|
||||||
{
|
{
|
||||||
Category getCategoryById(String id, Parameters params);
|
Category getCategoryById(String id, Parameters params);
|
||||||
|
|
||||||
|
List<Category> createSubcategories(String parentCategoryId, List<Category> categories, Parameters parameters);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Remote API
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.rest.api.categories;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.alfresco.rest.api.Categories;
|
||||||
|
import org.alfresco.rest.api.model.Category;
|
||||||
|
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.Parameters;
|
||||||
|
|
||||||
|
@RelationshipResource(name = "subcategories", entityResource = CategoriesEntityResource.class, title = "Subcategories")
|
||||||
|
public class SubcategoriesRelation implements RelationshipResourceAction.Create<Category>
|
||||||
|
{
|
||||||
|
|
||||||
|
private final Categories categories;
|
||||||
|
|
||||||
|
public SubcategoriesRelation(Categories categories)
|
||||||
|
{
|
||||||
|
this.categories = categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
@WebApiDescription(title = "Create a category",
|
||||||
|
description = "Creates one or more categories under a parent category",
|
||||||
|
successStatus = HttpServletResponse.SC_CREATED)
|
||||||
|
@Override
|
||||||
|
public List<Category> create(String parentCategoryId, List<Category> categoryList, Parameters parameters)
|
||||||
|
{
|
||||||
|
return categories.createSubcategories(parentCategoryId, categoryList, parameters);
|
||||||
|
}
|
||||||
|
}
|
@@ -29,18 +29,24 @@ package org.alfresco.rest.api.impl;
|
|||||||
import static org.alfresco.rest.api.Nodes.PATH_ROOT;
|
import static org.alfresco.rest.api.Nodes.PATH_ROOT;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.rest.api.Categories;
|
import org.alfresco.rest.api.Categories;
|
||||||
import org.alfresco.rest.api.Nodes;
|
import org.alfresco.rest.api.Nodes;
|
||||||
import org.alfresco.rest.api.model.Category;
|
import org.alfresco.rest.api.model.Category;
|
||||||
import org.alfresco.rest.api.model.Node;
|
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.InvalidArgumentException;
|
||||||
|
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
||||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||||
import org.alfresco.service.Experimental;
|
import org.alfresco.service.Experimental;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.CategoryService;
|
||||||
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
@@ -48,12 +54,17 @@ import org.apache.commons.collections.CollectionUtils;
|
|||||||
public class CategoriesImpl implements Categories
|
public class CategoriesImpl implements Categories
|
||||||
{
|
{
|
||||||
static final String NOT_A_VALID_CATEGORY = "Node id does not refer to a valid category";
|
static final String NOT_A_VALID_CATEGORY = "Node id does not refer to a valid category";
|
||||||
|
static final String NO_PERMISSION_TO_CREATE_A_CATEGORY = "Current user does not have permission to create a category";
|
||||||
|
|
||||||
|
private final AuthorityService authorityService;
|
||||||
|
private final CategoryService categoryService;
|
||||||
private final Nodes nodes;
|
private final Nodes nodes;
|
||||||
private final NodeService nodeService;
|
private final NodeService nodeService;
|
||||||
|
|
||||||
public CategoriesImpl(Nodes nodes, NodeService nodeService)
|
public CategoriesImpl(AuthorityService authorityService, CategoryService categoryService, Nodes nodes, NodeService nodeService)
|
||||||
{
|
{
|
||||||
|
this.authorityService = authorityService;
|
||||||
|
this.categoryService = categoryService;
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
this.nodeService = nodeService;
|
this.nodeService = nodeService;
|
||||||
}
|
}
|
||||||
@@ -62,27 +73,59 @@ public class CategoriesImpl implements Categories
|
|||||||
public Category getCategoryById(final String id, final Parameters params)
|
public Category getCategoryById(final String id, final Parameters params)
|
||||||
{
|
{
|
||||||
final NodeRef nodeRef = nodes.validateNode(id);
|
final NodeRef nodeRef = nodes.validateNode(id);
|
||||||
final boolean isCategory = nodes.isSubClass(nodeRef, ContentModel.TYPE_CATEGORY, false);
|
if (isNotACategory(nodeRef) || isRootCategory(nodeRef))
|
||||||
if (!isCategory || isRootCategory(nodeRef))
|
|
||||||
{
|
{
|
||||||
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
|
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return mapToCategory(nodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Category> createSubcategories(String parentCategoryId, List<Category> categories, Parameters parameters)
|
||||||
|
{
|
||||||
|
if (!authorityService.hasAdminAuthority())
|
||||||
|
{
|
||||||
|
throw new PermissionDeniedException(NO_PERMISSION_TO_CREATE_A_CATEGORY);
|
||||||
|
}
|
||||||
|
final NodeRef parentNodeRef = PATH_ROOT.equals(parentCategoryId) ?
|
||||||
|
categoryService.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE)
|
||||||
|
.orElseThrow(() -> new EntityNotFoundException(parentCategoryId)) :
|
||||||
|
nodes.validateNode(parentCategoryId);
|
||||||
|
if (isNotACategory(parentNodeRef))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{parentCategoryId});
|
||||||
|
}
|
||||||
|
final List<NodeRef> categoryNodeRefs = categories.stream()
|
||||||
|
.map(c -> categoryService.createCategory(parentNodeRef, c.getName()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return categoryNodeRefs.stream()
|
||||||
|
.map(this::mapToCategory)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNotACategory(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
return !nodes.isSubClass(nodeRef, ContentModel.TYPE_CATEGORY, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Category mapToCategory(NodeRef nodeRef)
|
||||||
|
{
|
||||||
final Node categoryNode = nodes.getNode(nodeRef.getId());
|
final Node categoryNode = nodes.getNode(nodeRef.getId());
|
||||||
final Category category = new Category();
|
|
||||||
category.setId(nodeRef.getId());
|
|
||||||
category.setName(categoryNode.getName());
|
|
||||||
category.setParentId(getParentId(nodeRef));
|
|
||||||
final boolean hasChildren = CollectionUtils
|
final boolean hasChildren = CollectionUtils
|
||||||
.isNotEmpty(nodeService.getChildAssocs(nodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false));
|
.isNotEmpty(nodeService.getChildAssocs(nodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false));
|
||||||
category.setHasChildren(hasChildren);
|
return Category.builder()
|
||||||
|
.id(nodeRef.getId())
|
||||||
return category;
|
.name(categoryNode.getName())
|
||||||
|
.parentId(getParentId(nodeRef))
|
||||||
|
.hasChildren(hasChildren)
|
||||||
|
.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRootCategory(final NodeRef nodeRef)
|
private boolean isRootCategory(final NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
final List<ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(nodeRef);
|
final List<ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(nodeRef);
|
||||||
return parentAssocs.stream().anyMatch(pa -> pa.getQName().equals(ContentModel.ASPECT_GEN_CLASSIFIABLE));
|
return parentAssocs.stream().anyMatch(pa -> ContentModel.ASPECT_GEN_CLASSIFIABLE.equals(pa.getQName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getParentId(final NodeRef nodeRef)
|
private String getParentId(final NodeRef nodeRef)
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
package org.alfresco.rest.api.model;
|
package org.alfresco.rest.api.model;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class Category
|
public class Category
|
||||||
{
|
{
|
||||||
private String id;
|
private String id;
|
||||||
@@ -72,4 +74,68 @@ public class Category
|
|||||||
{
|
{
|
||||||
this.hasChildren = hasChildren;
|
this.hasChildren = hasChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Objects.hash(id, name, parentId, hasChildren);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder()
|
||||||
|
{
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder
|
||||||
|
{
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String parentId;
|
||||||
|
private boolean hasChildren;
|
||||||
|
|
||||||
|
public Builder id(String id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder name(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parentId(String parentId)
|
||||||
|
{
|
||||||
|
this.parentId = parentId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hasChildren(boolean hasChildren)
|
||||||
|
{
|
||||||
|
this.hasChildren = hasChildren;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category create()
|
||||||
|
{
|
||||||
|
final Category category = new Category();
|
||||||
|
category.setId(id);
|
||||||
|
category.setName(name);
|
||||||
|
category.setParentId(parentId);
|
||||||
|
category.setHasChildren(hasChildren);
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -830,6 +830,8 @@
|
|||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="categories" class="org.alfresco.rest.api.impl.CategoriesImpl">
|
<bean id="categories" class="org.alfresco.rest.api.impl.CategoriesImpl">
|
||||||
|
<constructor-arg name="authorityService" ref="AuthorityService"/>
|
||||||
|
<constructor-arg name="categoryService" ref="CategoryService"/>
|
||||||
<constructor-arg name="nodes" ref="nodes"/>
|
<constructor-arg name="nodes" ref="nodes"/>
|
||||||
<constructor-arg name="nodeService" ref="NodeService"/>
|
<constructor-arg name="nodeService" ref="NodeService"/>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -1099,10 +1101,14 @@
|
|||||||
<constructor-arg name="categories" ref="Categories"/>
|
<constructor-arg name="categories" ref="Categories"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean class="org.alfresco.rest.api.categories.SubcategoriesRelation">
|
||||||
|
<constructor-arg name="categories" ref="Categories"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean class="org.alfresco.rest.api.tags.TagsEntityResource">
|
<bean class="org.alfresco.rest.api.tags.TagsEntityResource">
|
||||||
<property name="tags" ref="Tags" />
|
<property name="tags" ref="Tags" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean class="org.alfresco.rest.api.people.PersonSitesRelation">
|
<bean class="org.alfresco.rest.api.people.PersonSitesRelation">
|
||||||
<property name="sites" ref="Sites" />
|
<property name="sites" ref="Sites" />
|
||||||
</bean>
|
</bean>
|
||||||
|
@@ -26,15 +26,15 @@
|
|||||||
|
|
||||||
package org.alfresco.rest.api.impl;
|
package org.alfresco.rest.api.impl;
|
||||||
|
|
||||||
|
import static org.alfresco.rest.api.Nodes.PATH_ROOT;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertThrows;
|
import static org.junit.Assert.assertThrows;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
import static org.mockito.BDDMockito.then;
|
import static org.mockito.BDDMockito.then;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.rest.api.Nodes;
|
import org.alfresco.rest.api.Nodes;
|
||||||
@@ -42,11 +42,14 @@ import org.alfresco.rest.api.model.Category;
|
|||||||
import org.alfresco.rest.api.model.Node;
|
import org.alfresco.rest.api.model.Node;
|
||||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||||
|
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
||||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.CategoryService;
|
||||||
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -69,6 +72,10 @@ public class CategoriesImplTest
|
|||||||
@Mock
|
@Mock
|
||||||
private Parameters parametersMock;
|
private Parameters parametersMock;
|
||||||
@Mock
|
@Mock
|
||||||
|
private AuthorityService authorityServiceMock;
|
||||||
|
@Mock
|
||||||
|
private CategoryService categoryServiceMock;
|
||||||
|
@Mock
|
||||||
private ChildAssociationRef dummyChildAssociationRefMock;
|
private ChildAssociationRef dummyChildAssociationRefMock;
|
||||||
@Mock
|
@Mock
|
||||||
private ChildAssociationRef categoryChildAssociationRefMock;
|
private ChildAssociationRef categoryChildAssociationRefMock;
|
||||||
@@ -93,6 +100,8 @@ public class CategoriesImplTest
|
|||||||
then(nodesMock).shouldHaveNoMoreInteractions();
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
then(nodeServiceMock).should().getParentAssocs(categoryRootNodeRef);
|
then(nodeServiceMock).should().getParentAssocs(categoryRootNodeRef);
|
||||||
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(categoryServiceMock).shouldHaveNoInteractions();
|
||||||
|
then(authorityServiceMock).shouldHaveNoMoreInteractions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -126,10 +135,16 @@ public class CategoriesImplTest
|
|||||||
then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
|
then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
|
||||||
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
|
||||||
assertEquals(categoryNode.getName(), category.getName());
|
then(categoryServiceMock).shouldHaveNoInteractions();
|
||||||
assertEquals(CATEGORY_ID, category.getId());
|
then(authorityServiceMock).shouldHaveNoInteractions();
|
||||||
assertEquals(PARENT_ID, category.getParentId());
|
|
||||||
assertTrue(category.getHasChildren());
|
final Category expectedCategory = Category.builder()
|
||||||
|
.id(CATEGORY_ID)
|
||||||
|
.name(categoryNode.getName())
|
||||||
|
.hasChildren(true)
|
||||||
|
.parentId(PARENT_ID)
|
||||||
|
.create();
|
||||||
|
assertEquals(expectedCategory, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -162,10 +177,16 @@ public class CategoriesImplTest
|
|||||||
then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
|
then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
|
||||||
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
|
||||||
assertEquals(categoryNode.getName(), category.getName());
|
then(categoryServiceMock).shouldHaveNoInteractions();
|
||||||
assertEquals(CATEGORY_ID, category.getId());
|
then(authorityServiceMock).shouldHaveNoInteractions();
|
||||||
assertEquals(PARENT_ID, category.getParentId());
|
|
||||||
assertFalse(category.getHasChildren());
|
final Category expectedCategory = Category.builder()
|
||||||
|
.id(CATEGORY_ID)
|
||||||
|
.name(categoryNode.getName())
|
||||||
|
.hasChildren(false)
|
||||||
|
.parentId(PARENT_ID)
|
||||||
|
.create();
|
||||||
|
assertEquals(expectedCategory, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -183,6 +204,8 @@ public class CategoriesImplTest
|
|||||||
then(nodesMock).shouldHaveNoMoreInteractions();
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
|
||||||
then(nodeServiceMock).shouldHaveNoInteractions();
|
then(nodeServiceMock).shouldHaveNoInteractions();
|
||||||
|
then(categoryServiceMock).shouldHaveNoInteractions();
|
||||||
|
then(authorityServiceMock).shouldHaveNoInteractions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -197,5 +220,171 @@ public class CategoriesImplTest
|
|||||||
then(nodesMock).shouldHaveNoMoreInteractions();
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
|
||||||
then(nodeServiceMock).shouldHaveNoInteractions();
|
then(nodeServiceMock).shouldHaveNoInteractions();
|
||||||
|
then(categoryServiceMock).shouldHaveNoInteractions();
|
||||||
|
then(authorityServiceMock).shouldHaveNoInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateCategoryUnderRoot()
|
||||||
|
{
|
||||||
|
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
|
||||||
|
final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PATH_ROOT);
|
||||||
|
given(categoryServiceMock.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE))
|
||||||
|
.willReturn(Optional.of(parentCategoryNodeRef));
|
||||||
|
given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
|
||||||
|
final NodeRef categoryNodeRef = prepareCategoryNodeRef();
|
||||||
|
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(nodeServiceMock.getPrimaryParent(categoryNodeRef)).willReturn(parentAssoc);
|
||||||
|
given(nodeServiceMock.getParentAssocs(parentCategoryNodeRef)).willReturn(List.of(parentAssoc));
|
||||||
|
given(nodeServiceMock.getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
|
||||||
|
.willReturn(Collections.emptyList());
|
||||||
|
|
||||||
|
//when
|
||||||
|
final List<Category> createdCategories = objectUnderTest.createSubcategories(PATH_ROOT, prepareCategories(), parametersMock);
|
||||||
|
|
||||||
|
then(authorityServiceMock).should().hasAdminAuthority();
|
||||||
|
then(authorityServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
|
||||||
|
then(nodesMock).should().getNode(CATEGORY_ID);
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(nodeServiceMock).should().getPrimaryParent(categoryNodeRef);
|
||||||
|
then(nodeServiceMock).should().getParentAssocs(parentCategoryNodeRef);
|
||||||
|
then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
|
||||||
|
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(categoryServiceMock).should().getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||||
|
then(categoryServiceMock).should().createCategory(parentCategoryNodeRef, CATEGORY_NAME);
|
||||||
|
then(categoryServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
|
||||||
|
assertEquals(1, createdCategories.size());
|
||||||
|
final Category expectedCategory = Category.builder()
|
||||||
|
.id(CATEGORY_ID)
|
||||||
|
.name(CATEGORY_NAME)
|
||||||
|
.hasChildren(false)
|
||||||
|
.parentId(PATH_ROOT)
|
||||||
|
.create();
|
||||||
|
final Category createdCategory = createdCategories.iterator().next();
|
||||||
|
assertEquals(expectedCategory, createdCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateCategory()
|
||||||
|
{
|
||||||
|
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
|
||||||
|
final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
|
||||||
|
given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
|
||||||
|
given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
|
||||||
|
final NodeRef categoryNodeRef = prepareCategoryNodeRef();
|
||||||
|
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(nodeServiceMock.getPrimaryParent(categoryNodeRef)).willReturn(parentAssoc);
|
||||||
|
given(nodeServiceMock.getParentAssocs(parentCategoryNodeRef)).willReturn(List.of(parentAssoc));
|
||||||
|
given(nodeServiceMock.getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
|
||||||
|
.willReturn(Collections.emptyList());
|
||||||
|
|
||||||
|
//when
|
||||||
|
final List<Category> createdCategories = objectUnderTest.createSubcategories(PARENT_ID, prepareCategories(), parametersMock);
|
||||||
|
|
||||||
|
then(authorityServiceMock).should().hasAdminAuthority();
|
||||||
|
then(authorityServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(nodesMock).should().validateNode(PARENT_ID);
|
||||||
|
then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
|
||||||
|
then(nodesMock).should().getNode(CATEGORY_ID);
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(nodeServiceMock).should().getPrimaryParent(categoryNodeRef);
|
||||||
|
then(nodeServiceMock).should().getParentAssocs(parentCategoryNodeRef);
|
||||||
|
then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
|
||||||
|
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(categoryServiceMock).should().createCategory(parentCategoryNodeRef, CATEGORY_NAME);
|
||||||
|
then(categoryServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
|
||||||
|
assertEquals(1, createdCategories.size());
|
||||||
|
final Category expectedCategory = Category.builder()
|
||||||
|
.id(CATEGORY_ID)
|
||||||
|
.name(CATEGORY_NAME)
|
||||||
|
.hasChildren(false)
|
||||||
|
.parentId(PARENT_ID)
|
||||||
|
.create();
|
||||||
|
final Category createdCategory = createdCategories.iterator().next();
|
||||||
|
assertEquals(expectedCategory, createdCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateCategories_noPermissions()
|
||||||
|
{
|
||||||
|
given(authorityServiceMock.hasAdminAuthority()).willReturn(false);
|
||||||
|
|
||||||
|
//when
|
||||||
|
assertThrows(PermissionDeniedException.class,
|
||||||
|
() -> objectUnderTest.createSubcategories(PARENT_ID, prepareCategories(), parametersMock));
|
||||||
|
|
||||||
|
then(authorityServiceMock).should().hasAdminAuthority();
|
||||||
|
then(authorityServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(nodesMock).shouldHaveNoInteractions();
|
||||||
|
then(nodeServiceMock).shouldHaveNoInteractions();
|
||||||
|
then(categoryServiceMock).shouldHaveNoInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateCategories_wrongParentNodeType()
|
||||||
|
{
|
||||||
|
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
|
||||||
|
final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
|
||||||
|
given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
|
||||||
|
given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(false);
|
||||||
|
|
||||||
|
//when
|
||||||
|
assertThrows(InvalidArgumentException.class,
|
||||||
|
() -> objectUnderTest.createSubcategories(PARENT_ID, prepareCategories(), parametersMock));
|
||||||
|
|
||||||
|
then(authorityServiceMock).should().hasAdminAuthority();
|
||||||
|
then(authorityServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(nodesMock).should().validateNode(PARENT_ID);
|
||||||
|
then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(nodeServiceMock).shouldHaveNoInteractions();
|
||||||
|
then(categoryServiceMock).shouldHaveNoInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateCategories_nonExistingParentNode()
|
||||||
|
{
|
||||||
|
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
|
||||||
|
given(nodesMock.validateNode(PARENT_ID)).willThrow(EntityNotFoundException.class);
|
||||||
|
|
||||||
|
//when
|
||||||
|
assertThrows(EntityNotFoundException.class,
|
||||||
|
() -> objectUnderTest.createSubcategories(PARENT_ID, prepareCategories(), parametersMock));
|
||||||
|
|
||||||
|
then(authorityServiceMock).should().hasAdminAuthority();
|
||||||
|
then(authorityServiceMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(nodesMock).should().validateNode(PARENT_ID);
|
||||||
|
then(nodesMock).shouldHaveNoMoreInteractions();
|
||||||
|
then(nodeServiceMock).shouldHaveNoInteractions();
|
||||||
|
then(categoryServiceMock).shouldHaveNoInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node prepareCategoryNode()
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
return categoryNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef prepareCategoryNodeRef()
|
||||||
|
{
|
||||||
|
return new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Category> prepareCategories()
|
||||||
|
{
|
||||||
|
return List.of(Category.builder()
|
||||||
|
.name(CATEGORY_NAME)
|
||||||
|
.create());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -573,6 +573,7 @@
|
|||||||
org.alfresco.service.cmr.search.CategoryService.deleteClassification=ACL_ALLOW
|
org.alfresco.service.cmr.search.CategoryService.deleteClassification=ACL_ALLOW
|
||||||
org.alfresco.service.cmr.search.CategoryService.deleteCategory=ACL_ALLOW
|
org.alfresco.service.cmr.search.CategoryService.deleteCategory=ACL_ALLOW
|
||||||
org.alfresco.service.cmr.search.CategoryService.getTopCategories=ACL_ALLOW
|
org.alfresco.service.cmr.search.CategoryService.getTopCategories=ACL_ALLOW
|
||||||
|
org.alfresco.service.cmr.search.CategoryService.getRootCategoryNodeRef=ACL_ALLOW
|
||||||
org.alfresco.service.cmr.search.CategoryService.*=ACL_DENY
|
org.alfresco.service.cmr.search.CategoryService.*=ACL_DENY
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
|
Reference in New Issue
Block a user