Compare commits

..

4 Commits

Author SHA1 Message Date
suneet.gupta
06004e207d Changed formatting 2023-02-08 15:46:49 +05:30
suneet.gupta
a7c35ae391 Changed formatting 2023-02-08 15:43:56 +05:30
suneet.gupta
324e2f619d Changed formatting 2023-02-08 15:36:10 +05:30
atkumar14
5d269e05ab Update TagsImpl.java
[ACS-3916] Changes done for Get tag by id does not validate the node is a tag.
2023-02-06 16:02:09 +05:30
68 changed files with 868 additions and 2372 deletions

View File

@@ -27,13 +27,11 @@ jobs:
runs-on: ubuntu-latest
needs: [run_ci]
if: >
!(failure() || cancelled()) &&
!failure() &&
!contains(github.event.head_commit.message, '[no release]') &&
github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v3
with:
persist-credentials: false
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v1.33.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v1.33.0
- name: "Init"
@@ -55,13 +53,11 @@ jobs:
runs-on: ubuntu-latest
needs: [push_to_nexus]
if: >
!(failure() || cancelled()) &&
!failure() &&
!contains(github.event.head_commit.message, '[no downstream]') &&
github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v3
with:
persist-credentials: false
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v1.33.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v1.33.0
- name: "Init"
@@ -76,4 +72,4 @@ jobs:
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
- name: "Clean Maven cache"
run: bash ./scripts/ci/cleanup_cache.sh
run: bash ./scripts/ci/cleanup_cache.sh

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<build>

View File

@@ -33,9 +33,7 @@ import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.v0.RecordsAPI;
import org.alfresco.utility.Utility;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.data.RandomData;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
import org.json.JSONObject;
@@ -99,10 +97,9 @@ public class InplaceRecordSearchTests extends BaseRMRestTest {
@Test
public void searchForInplaceRecord() {
// And a document that isn't a record
final String fileName = "File" + RandomData.getRandomAlphanumeric();
uploadedDocbyCollabUser = dataContent.usingSite(privateSite)
.usingUser(siteCollaborator)
.createContent(new FileModel(fileName, FileType.fromName(fileName + "." + CMISUtil.DocumentType.TEXT_PLAIN.extention)));
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
assertNotNull(uploadedDocbyCollabUser.getNodeRef());

View File

@@ -72,7 +72,7 @@ public class SearchDocumentsV1Test extends BaseRMRestTest
cmisQueryModel.setLanguage("cmis");
RestRequestQueryModel aftsQueryModel = new RestRequestQueryModel();
aftsQueryModel.setQuery("cm:name:*" + SEARCH_TERM + ".txt");
aftsQueryModel.setQuery("cm:name:*" + SEARCH_TERM);
aftsQueryModel.setLanguage("afts");
return new RestRequestQueryModel[][] {
@@ -107,7 +107,7 @@ public class SearchDocumentsV1Test extends BaseRMRestTest
private void waitIndexing() throws Exception
{
RestRequestQueryModel queryType = new RestRequestQueryModel();
queryType.setQuery("cm:name:*" + SEARCH_TERM + ".txt");
queryType.setQuery("cm:name:*" + SEARCH_TERM);
queryType.setLanguage("afts");
Utility.sleep(1000, 80000, () ->
{

View File

@@ -66,6 +66,7 @@ import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanCo
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.CUT_OFF_ASPECT;
import static org.alfresco.rest.rm.community.model.recordcategory.RetentionPeriodProperty.*;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -83,29 +84,26 @@ public class DispositionScheduleLinkedRecordsTest extends BaseRMRestTest {
@Autowired
private RecordFoldersAPI recordFoldersAPI;
private final static String TEST_PREFIX = generateTestPrefix(DispositionScheduleLinkedRecordsTest.class);
private RecordCategory Category1;
private RecordCategory Category1,catsameLevel1,catsameLevel2;
private RecordCategoryChild CopyCatFolder,folder1,CatFolder,folder2;
private static final String categoryRM3077 = TEST_PREFIX + "RM-3077_manager_sees_me";
private static final String copyCategoryRM3077 = "Copy_of_" + categoryRM3077;
private static final String folderRM3077 = "RM-3077_folder_"+ categoryRM3077;
private static final String copyFolderRM3077 = "Copy_of_" + folderRM3077;
private final String electronicRecord = "RM-2937 electronic 2 record";
private final String folder = TEST_PREFIX + "RM-2937 folder ghosting";
private static final String categoryRecordsRM2526 = TEST_PREFIX + "RM-2526_category_records_immediately";
private static final String category2RecordsRM2526 = TEST_PREFIX + "RM-2526_category_2_records_1_day";
private static final String firstCategoryRM3060 = TEST_PREFIX + "RM-3060_category_record";
private static final String secondCategoryRM3060 = "Copy_of_" + firstCategoryRM3060;
private static final String firstFolderRM3060 = TEST_PREFIX + "RM-3060_folder";
private static final String secondFolderRM3060 = TEST_PREFIX + "RM-3060_disposition_on_Record_Level";
private static final String electronicRecordRM3060 = TEST_PREFIX + "RM-3060_electronic_1_record";
private static final String nonElectronicRecordRM3060 = TEST_PREFIX + "RM-3060_non-electronic_record";
private static final String firstCategoryRM1622 = TEST_PREFIX + "RM-1622_category_record";
private static final String secondCategoryRM1622 = "Copy_of_" + firstCategoryRM1622;;
private static final String firstFolderRM1622 = TEST_PREFIX + "RM-1622_folder";
private static final String electronicRecordRM1622 = TEST_PREFIX + "RM-1622_electronic_1_record";
private static final String secondFolderRM1622 = TEST_PREFIX + "RM-1622_disposition_on_Record_Level";
private static final String TRANSFER_LOCATION = TEST_PREFIX + "RM-3060_transferred_records";
public static final String TRANSFER_TYPE = "rma:transferred";
private FilePlan filePlanModel;
private UserModel rmAdmin, rmManager;
@BeforeClass(alwaysRun = true)
public void setupDispositionScheduleLinkedRecordsTest() {
createRMSiteIfNotExists();
@@ -370,35 +368,35 @@ public class DispositionScheduleLinkedRecordsTest extends BaseRMRestTest {
// create a category with retention applied on records level
RecordCategory catsameLevel1 = getRestAPIFactory().getFilePlansAPI(rmAdmin)
.createRootRecordCategory(RecordCategory.builder().name(firstCategoryRM1622).build(),
RecordCategory.DEFAULT_FILE_PLAN_ALIAS);
.createRootRecordCategory(RecordCategory.builder().name(firstCategoryRM3060).build(),
RecordCategory.DEFAULT_FILE_PLAN_ALIAS);
RecordCategory catsameLevel2 = getRestAPIFactory().getFilePlansAPI(rmAdmin)
.createRootRecordCategory(RecordCategory.builder().name(secondCategoryRM1622).build(),
RecordCategory.DEFAULT_FILE_PLAN_ALIAS);
.createRootRecordCategory(RecordCategory.builder().name(secondCategoryRM3060).build(),
RecordCategory.DEFAULT_FILE_PLAN_ALIAS);
// create retention schedule applied on records for category 1
dispositionScheduleService.createCategoryRetentionSchedule(firstCategoryRM1622, true);
dispositionScheduleService.createCategoryRetentionSchedule(firstCategoryRM3060, true);
// with retain immediately after record creation date and cut 1 day after record creation date
dispositionScheduleService.addCutOffAfterPeriodStep(firstCategoryRM1622, "day|1", DATE_FILED);
dispositionScheduleService.addCutOffAfterPeriodStep(firstCategoryRM3060, "day|1", DATE_FILED);
// create a folder on the category firstCategoryRM1622 with a complete electronic record
RecordCategoryChild firstFolderRecordCategoryChild = createRecordFolder(catsameLevel1.getId(),firstFolderRM1622);
Record firstElectronicRecord = createElectronicRecord(firstFolderRecordCategoryChild.getId(),electronicRecordRM1622);
// create a folder on the category firstCategoryRM3060 with a complete electronic record
RecordCategoryChild firstFolderRecordCategoryChild = createRecordFolder(catsameLevel1.getId(),firstFolderRM3060);
Record firstElectronicRecord = createElectronicRecord(firstFolderRecordCategoryChild.getId(),electronicRecordRM3060);
String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().getAdminUser().getUsername(),
getDataUser().getAdminUser().getPassword(),firstFolderRM1622, electronicRecordRM1622);
getDataUser().getAdminUser().getPassword(),firstFolderRM3060, electronicRecordRM3060);
String elRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM1622 + "/" + firstFolderRM1622);
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060);
recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(),
getDataUser().getAdminUser().getPassword(), elRecordFullName);
// create a folder on the category secondCategoryRM1622 with a non electronic record
RecordCategoryChild secondFolderRecordCategoryChild = createRecordFolder(catsameLevel2.getId(),secondFolderRM1622);
// create a folder on the category secondCategoryRM3060 with a non electronic record
RecordCategoryChild secondFolderRecordCategoryChild = createRecordFolder(catsameLevel2.getId(),secondFolderRM3060);
String elRecordNameNodeRefs = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM1622 + "/" + firstFolderRM1622);
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060);
// link it to the folder in second category through the details page
@@ -406,8 +404,8 @@ public class DispositionScheduleLinkedRecordsTest extends BaseRMRestTest {
recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + firstElectronicRecord.getId());
linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM1622 + "/" +
secondFolderRM1622, recordLists);
getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" +
secondFolderRM3060, recordLists);
// edit disposition date
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<build>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -9,6 +9,6 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
</project>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<organization>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -2,7 +2,7 @@
* #%L
* alfresco-tas-restapi
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -27,8 +27,6 @@ package org.alfresco.rest.model;
import static org.alfresco.utility.report.log.Step.STEP;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.core.IRestModel;
@@ -75,65 +73,4 @@ public class RestTagModel extends TagModel implements IRestModel<RestTagModel>
this.count = count;
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
RestTagModel tagModel = (RestTagModel) o;
return Objects.equals(id, tagModel.id) && Objects.equals(tag, tagModel.tag) && Objects.equals(count, tagModel.count);
}
@Override
public int hashCode()
{
return Objects.hash(id, tag, count);
}
@Override
public String toString()
{
return "RestTagModel{" + "id='" + id + ", tag='" + tag + '\'' + ", count=" + count + '\'' + '}';
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private String id;
private String tag;
private Integer count;
public Builder id(String id)
{
this.id = id;
return this;
}
public Builder tag(String tag)
{
this.tag = tag;
return this;
}
public Builder count(Integer count)
{
this.count = count;
return this;
}
public RestTagModel create()
{
final RestTagModel tag = new RestTagModel();
tag.setId(id);
tag.setTag(this.tag);
tag.setCount(count);
return tag;
}
}
}

View File

@@ -82,15 +82,4 @@ public class Tags extends ModelRequest<Tags>
return restWrapper.processModel(RestTagModel.class, request);
}
/**
* Delete tag.
* - DELETE /tags/{tagId}
*/
public void deleteTag()
{
RestRequest request = RestRequest.
simpleRequest(HttpMethod.DELETE, "/tags/{tagId}", tag.getId());
restWrapper.processEmptyModel(request);
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* alfresco-tas-restapi
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -25,12 +25,6 @@
*/
package org.alfresco.rest.requests.coreAPI;
import static org.alfresco.rest.core.JsonBodyGenerator.arrayToJson;
import java.util.List;
import io.restassured.RestAssured;
import org.alfresco.rest.core.RestRequest;
import org.alfresco.rest.core.RestWrapper;
import org.alfresco.rest.model.RestCategoryModel;
import org.alfresco.rest.model.RestDownloadsModel;
@@ -55,7 +49,8 @@ import org.alfresco.rest.requests.Trashcan;
import org.alfresco.utility.model.RepoTestModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
import org.springframework.http.HttpMethod;
import io.restassured.RestAssured;
/**
* Defines the entire Rest Core API
@@ -177,30 +172,6 @@ public class RestCoreAPI extends ModelRequest<RestCoreAPI>
return new Networks(restWrapper);
}
/**
* Create a single orphan tag.
*
* @param tag Tag model to create.
* @return Created tag.
*/
public RestTagModel createSingleTag(RestTagModel tag)
{
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, tag.toJson(), "tags/");
return restWrapper.processModel(RestTagModel.class, request);
}
/**
* Create several orphan tags in one request.
*
* @param tags Tags models to create.
* @return Created tags.
*/
public RestTagModelsCollection createTags(List<RestTagModel> tags)
{
RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, arrayToJson(tags), "tags/");
return restWrapper.processModels(RestTagModelsCollection.class, request);
}
public Tags usingTag(RestTagModel tag)
{
return new Tags(tag, restWrapper);

View File

@@ -1,207 +0,0 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #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);
}
}

View File

@@ -30,7 +30,6 @@ 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;
@@ -38,21 +37,18 @@ 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;
@@ -63,26 +59,14 @@ abstract class CategoriesRestTest extends RestTest
user = dataUser.createRandomTestUser();
}
protected RestCategoryModelsCollection linkContentToCategories(final RepoTestModel node, final RestCategoryModel... categories)
{
final List<RestCategoryLinkBodyModel> 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 prepareCategoryUnderRoot()
{
return prepareCategoryUnder(createCategoryModelWithId(ROOT_CATEGORY_ID));
return prepareCategoryUnder(ROOT_CATEGORY_ID);
}
protected RestCategoryModel prepareCategoryUnder(final RestCategoryModel parentCategory)
protected RestCategoryModel prepareCategoryUnder(final String parentId)
{
final RestCategoryModel parentCategory = createCategoryModelWithId(parentId);
final RestCategoryModel categoryModel = createCategoryModelWithName(getRandomName(CATEGORY_NAME_PREFIX));
final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
.withCoreAPI()

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -26,7 +26,6 @@
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;
@@ -39,6 +38,7 @@ 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(getRandomName("Category"));
final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.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(getRandomName("Category"));
final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.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(getRandomName("Category"));
final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.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(getRandomName("Category"));
final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.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(getRandomName("Category"));
final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.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(getRandomName("Category"));
final RestCategoryModel aCategory = createCategoryModelWithName(RandomData.getRandomName("Category"));
restClient.authenticateUser(dataUser.getAdminUser())
.withCoreAPI()
.usingCategory(rootCategory)
@@ -231,31 +231,10 @@ 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<RestCategoryModel> getCategoriesToCreate(final int count)
{
return IntStream.range(0, count)
.mapToObj(i -> RestCategoryModel.builder().name(getRandomName("SubCategory")).create())
.mapToObj(i -> RestCategoryModel.builder().name(RandomData.getRandomName("SubCategory")).create())
.collect(Collectors.toList());
}
}

View File

@@ -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);
final RestCategoryModel createdSubcategory = prepareCategoryUnder(createdCategory.getId());
STEP("Update as admin newly created subcategory");
final String categoryNewName = getRandomName(CATEGORY_NEW_NAME_PREFIX);
@@ -233,27 +233,4 @@ 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);
}
}

View File

@@ -14,6 +14,7 @@ import org.alfresco.utility.testrail.annotation.TestRail;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Ignore;
import org.testng.annotations.Test;
public class AddFavoritesTests extends RestTest
@@ -354,6 +355,7 @@ public class AddFavoritesTests extends RestTest
@TestRail(section = { TestGroup.REST_API, TestGroup.FAVORITES }, executionType = ExecutionType.REGRESSION,
description = "Verify add file favorite with tag id returns status code 404")
@Test(groups = { TestGroup.REST_API, TestGroup.FAVORITES, TestGroup.REGRESSION })
@Ignore
public void addFileFavoriteUsingTagId() throws Exception
{
FileModel file = dataContent.usingSite(siteModel).usingUser(adminUserModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);

View File

@@ -1,226 +0,0 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.tags;
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.CONFLICT;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.OK;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestTagModel;
import org.alfresco.rest.model.RestTagModelsCollection;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class CreateTagsTests extends RestTest
{
private static final String FIELD_ID = "id";
private static final String FIELD_TAG = "tag";
private static final String FIELD_COUNT = "count";
private static final String TAG_NAME_PREFIX = "tag-name";
private UserModel admin;
private UserModel user;
@BeforeClass
public void init()
{
admin = dataUser.getAdminUser();
user = dataUser.createRandomTestUser();
}
/**
* Verify if tag does not exist in the system, create one as admin and check if now it's there.
*/
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS })
public void testCreateSingleTag()
{
STEP("Create single tag as admin");
final RestTagModel tagModel = createTagModelWithName(getRandomName("99gat").toLowerCase());
final RestTagModel createdTag = restClient.authenticateUser(admin).withCoreAPI().createSingleTag(tagModel);
restClient.assertStatusCodeIs(CREATED);
createdTag.assertThat().field(FIELD_TAG).is(tagModel.getTag())
.assertThat().field(FIELD_ID).isNotEmpty();
STEP("Verify that tag does exist in the system");
RestTagModel tag = restClient.authenticateUser(admin).withCoreAPI().getTag(createdTag);
restClient.assertStatusCodeIs(OK);
tag.assertThat().isEqualTo(createdTag);
}
/**
* Create multiple orphan tags.
*/
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS })
public void testCreateMultipleTags()
{
STEP("Create several tags as admin");
final List<RestTagModel> tagModels = IntStream.range(0, 3)
.mapToObj(i -> createTagModelWithName(getRandomName(TAG_NAME_PREFIX + "-" + i).toLowerCase()))
.collect(Collectors.toList());
final RestTagModelsCollection createdTags = restClient.authenticateUser(admin).withCoreAPI().createTags(tagModels);
restClient.assertStatusCodeIs(CREATED);
IntStream.range(0, tagModels.size())
.forEach(i -> createdTags.getEntries().get(i).onModel()
.assertThat().field(FIELD_TAG).is(tagModels.get(i).getTag())
.assertThat().field(FIELD_ID).isNotEmpty()
);
}
/**
* Verify that tag name's case will be lowered.
*/
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS })
public void testCreateSingleTag_usingUppercaseName()
{
STEP("Create single tag as admin using uppercase name");
final RestTagModel tagModel = createTagModelWithName(getRandomName(TAG_NAME_PREFIX).toUpperCase());
final RestTagModel createdTag = restClient.authenticateUser(admin).withCoreAPI().createSingleTag(tagModel);
restClient.assertStatusCodeIs(CREATED);
createdTag.assertThat().field(FIELD_TAG).is(tagModel.getTag().toLowerCase())
.assertThat().field(FIELD_ID).isNotEmpty();
}
/**
* Try to create few tags including repeating ones. Repeated tags should be omitted.
*/
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS })
public void testCreateMultipleTags_withRepeatedName()
{
STEP("Create models of tags");
final String repeatedTagName = getRandomName(TAG_NAME_PREFIX).toLowerCase();
final List<RestTagModel> tagModels = List.of(
createTagModelWithName(repeatedTagName),
createTagModelWithName(getRandomName(TAG_NAME_PREFIX).toLowerCase()),
createTagModelWithName(repeatedTagName)
);
STEP("Create several tags skipping repeating names");
final RestTagModelsCollection createdTags = restClient.authenticateUser(admin).withCoreAPI().createTags(tagModels);
restClient.assertStatusCodeIs(CREATED);
createdTags.assertThat().entriesListCountIs(2);
createdTags.assertThat().entriesListContains(FIELD_TAG, tagModels.get(0).getTag())
.and().entriesListContains(FIELD_TAG, tagModels.get(1).getTag());
}
/**
* Try to create a tag as a common user and expect 403 (Forbidden)
*/
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS })
public void testCreateTag_asUser()
{
STEP("Try to create single tag as a common user and expect 403");
final RestTagModel tagModel = createTagModelWithRandomName();
restClient.authenticateUser(user).withCoreAPI().createSingleTag(tagModel);
restClient.assertStatusCodeIs(FORBIDDEN);
}
/**
* Try to call create tag API passing empty list and expect 400 (Bad Request)
*/
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS })
public void testCreateTags_passingEmptyList()
{
STEP("Pass empty list while creating tags and expect 400");
restClient.authenticateUser(admin).withCoreAPI().createTags(Collections.emptyList());
restClient.assertStatusCodeIs(BAD_REQUEST);
}
/**
* Try to create a tag, which already exists in the system and expect 409 (Conflict)
*/
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS })
public void testCreateTag_usingAlreadyExistingTagName()
{
STEP("Create some tag in the system");
final RestTagModel tagToCreate = createTagModelWithRandomName();
final RestTagModel alreadyExistingTag = prepareOrphanTag(tagToCreate);
// set original name instead the case lowered one
alreadyExistingTag.setTag(tagToCreate.getTag());
STEP("Try to use already existing tag to create duplicate and expect 409");
restClient.authenticateUser(admin).withCoreAPI().createSingleTag(alreadyExistingTag);
restClient
.assertStatusCodeIs(CONFLICT)
.assertLastError().containsSummary("Duplicate child name not allowed: " + alreadyExistingTag.getTag().toLowerCase());
}
/**
* Verify if count field is 0 for newly created tags.
*/
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS })
public void testCreateTag_includingCount()
{
STEP("Create single tag as admin including count and verify if it is 0");
final RestTagModel tagModel = createTagModelWithName(getRandomName(TAG_NAME_PREFIX).toLowerCase());
final RestTagModel createdTag = restClient.authenticateUser(admin).withCoreAPI().include(FIELD_COUNT).createSingleTag(tagModel);
restClient.assertStatusCodeIs(CREATED);
createdTag.assertThat().field(FIELD_TAG).is(tagModel.getTag())
.assertThat().field(FIELD_ID).isNotEmpty()
.assertThat().field(FIELD_COUNT).is(0);
}
private RestTagModel prepareOrphanTagWithRandomName()
{
return prepareOrphanTag(createTagModelWithRandomName());
}
private RestTagModel prepareOrphanTag(final RestTagModel tagModel)
{
final RestTagModel tag = restClient.authenticateUser(admin).withCoreAPI().createSingleTag(tagModel);
restClient.assertStatusCodeIs(CREATED);
return tag;
}
private static RestTagModel createTagModelWithRandomName()
{
return createTagModelWithName(getRandomName(TAG_NAME_PREFIX));
}
private static RestTagModel createTagModelWithName(final String tagName)
{
return RestTagModel.builder().tag(tagName).create();
}
}

View File

@@ -1,88 +0,0 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.tags;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.model.RestTagModel;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.TestGroup;
import org.testng.annotations.Test;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.NO_CONTENT;
public class DeleteTagsTests extends TagsDataPrep
{
/**
* Check we can delete a tag by its id.
*/
@Test(groups = {TestGroup.REST_API})
public void testDeleteTag()
{
STEP("Create a tag assigned to a document and send a request to delete it.");
document = dataContent.usingUser(adminUserModel).usingSite(siteModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
RestTagModel aTag = createTagForDocument(document);
restClient.authenticateUser(dataUser.getAdminUser()).withCoreAPI().usingTag(aTag).deleteTag();
restClient.assertStatusCodeIs(NO_CONTENT);
STEP("Ensure that the tag has been deleted by sending a GET request and receiving 404.");
restClient.authenticateUser(dataUser.getAdminUser()).withCoreAPI().getTag(aTag);
restClient.assertStatusCodeIs(NOT_FOUND);
}
/**
* Attempt to delete a tag as a site manager and receive 403 error.
* Other user roles have fewer permissions than a SiteManager and thus would also be forbidden from deleting a tag.
*/
@Test(groups = {TestGroup.REST_API})
public void testDeleteTagAsSiteManager_andFail()
{
STEP("Create a tag assigned to a document and attempt to delete as a site manager");
document = dataContent.usingUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).usingSite(siteModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
RestTagModel aTag = createTagForDocument(document);
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).withCoreAPI().usingTag(aTag).deleteTag();
restClient.assertStatusCodeIs(FORBIDDEN).assertLastError().containsSummary("Current user does not have permission to manage a tag");
}
/**
* Check we receive 404 error when trying to delete a tag with a non-existent id
*/
@Test(groups = {TestGroup.REST_API})
public void testDeleteNonExistentTag()
{
STEP("Attempt to delete tag with non-existent id and receive 404 error");
final String id = "non-existing-dummy-id";
final RestTagModel tagModel = createTagModelWithId(id);
restClient.authenticateUser(dataUser.getAdminUser()).withCoreAPI().usingTag(tagModel).deleteTag();
restClient.assertStatusCodeIs(NOT_FOUND);
}
}

View File

@@ -1,5 +1,6 @@
package org.alfresco.rest.tags;
import java.util.Date;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestTagModel;
@@ -11,9 +12,12 @@ import org.alfresco.utility.data.RandomData;
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.alfresco.utility.model.UserModel;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@Test(groups = {TestGroup.REQUIRE_SOLR})
public class TagsDataPrep extends RestTest
{
@@ -30,9 +34,7 @@ public class TagsDataPrep extends RestTest
@BeforeClass
public void init() throws Exception
{
//Create users
adminUserModel = dataUser.getAdminUser();
userModel = dataUser.createRandomTestUser();
//Create public site
siteModel = dataSite.usingUser(adminUserModel).createPublicRandomSite();
usersWithRoles = dataUser.usingAdmin().addUsersWithRolesToSite(siteModel, UserRole.SiteManager, UserRole.SiteCollaborator, UserRole.SiteConsumer, UserRole.SiteContributor);
@@ -58,23 +60,4 @@ public class TagsDataPrep extends RestTest
});
}
protected RestTagModel createTagForDocument(FileModel document)
{
String documentTagValue = RandomData.getRandomName("tag");
return restClient.withCoreAPI().usingResource(document).addTag(documentTagValue);
}
protected RestTagModel createTagModelWithId(final String id)
{
return createTagModelWithIdAndName(id, RandomData.getRandomName("tag"));
}
protected RestTagModel createTagModelWithIdAndName(final String id, final String tag)
{
return RestTagModel.builder()
.id(id)
.tag(tag)
.create();
}
}

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<properties>

14
pom.xml
View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -64,7 +64,7 @@
<dependency.bouncycastle.version>1.70</dependency.bouncycastle.version>
<dependency.mockito-core.version>4.9.0</dependency.mockito-core.version>
<dependency.assertj.version>3.24.2</dependency.assertj.version>
<dependency.org-json.version>20230227</dependency.org-json.version>
<dependency.org-json.version>20220320</dependency.org-json.version>
<dependency.commons-dbcp.version>2.9.0</dependency.commons-dbcp.version>
<dependency.commons-io.version>2.11.0</dependency.commons-io.version>
<dependency.gson.version>2.8.9</dependency.gson.version>
@@ -87,7 +87,7 @@
<dependency.netty.version>4.1.79.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
<dependency.netty.qpid.version>4.1.72.Final</dependency.netty.qpid.version> <!-- must be in sync with camels transitive dependencies: native-unix-common/native-epoll/native-kqueue -->
<dependency.netty-tcnative.version>2.0.53.Final</dependency.netty-tcnative.version> <!-- must be in sync with camels transitive dependencies -->
<dependency.activemq.version>5.17.4</dependency.activemq.version>
<dependency.activemq.version>5.17.1</dependency.activemq.version>
<dependency.apache-compress.version>1.22</dependency.apache-compress.version>
<dependency.apache.taglibs.version>1.2.5</dependency.apache.taglibs.version>
<dependency.awaitility.version>4.2.0</dependency.awaitility.version>
@@ -120,7 +120,7 @@
<dependency.mysql.version>8.0.30</dependency.mysql.version>
<dependency.mysql-image.version>8</dependency.mysql-image.version>
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
<dependency.tas-utility.version>3.0.61</dependency.tas-utility.version>
<dependency.tas-utility.version>3.0.58</dependency.tas-utility.version>
<dependency.rest-assured.version>5.2.0</dependency.rest-assured.version>
<dependency.tas-email.version>1.11</dependency.tas-email.version>
<dependency.tas-webdav.version>1.7</dependency.tas-webdav.version>
@@ -148,7 +148,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>20.93</tag>
<tag>HEAD</tag>
</scm>
<distributionManagement>
@@ -384,7 +384,7 @@
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.5</version>
<version>1.4</version>
</dependency>
<dependency>
@@ -916,7 +916,7 @@
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.42.0</version>
<version>0.40.2</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -26,101 +26,57 @@
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(StoreRef storeRef, String id, Parameters parameters);
Category getCategoryById(String id, Parameters parameters);
default Category getCategoryById(String id, Parameters parameters)
{
return getCategoryById(STORE_REF_WORKSPACE_SPACESSTORE, id, parameters);
}
List<Category> createSubcategories(String parentCategoryId, List<Category> categories, Parameters parameters);
List<Category> createSubcategories(StoreRef storeRef, String parentCategoryId, List<Category> categories, Parameters parameters);
default List<Category> createSubcategories(String parentCategoryId, List<Category> categories, Parameters parameters)
{
return createSubcategories(STORE_REF_WORKSPACE_SPACESSTORE, parentCategoryId, categories, parameters);
}
List<Category> getCategoryChildren(StoreRef storeRef, String parentCategoryId, Parameters parameters);
default List<Category> getCategoryChildren(String parentCategoryId, Parameters parameters)
{
return getCategoryChildren(STORE_REF_WORKSPACE_SPACESSTORE, parentCategoryId, parameters);
}
CollectionWithPagingInfo<Category> getCategoryChildren(String parentCategoryId, Parameters 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(StoreRef storeRef, String id, Category fixedCategoryModel, Parameters parameters);
Category updateCategoryById(String id, Category fixedCategoryModel);
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);
}
void deleteCategoryById(String id, Parameters 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<Category> listCategoriesForNode(String nodeId, Parameters parameters);
List<Category> listCategoriesForNode(String nodeId);
/**
* 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<Category> linkNodeToCategories(StoreRef storeRef, String nodeId, List<Category> categoryLinks, Parameters parameters);
default List<Category> linkNodeToCategories(String nodeId, List<Category> categoryLinks, Parameters parameters)
{
return linkNodeToCategories(STORE_REF_WORKSPACE_SPACESSTORE, nodeId, categoryLinks, parameters);
}
List<Category> linkNodeToCategories(String nodeId, List<Category> categoryLinks);
/**
* 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(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);
}
void unlinkNodeFromCategory(String nodeId, String categoryId, Parameters parameters);
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -23,35 +23,22 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
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.Tag;
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;
public interface Tags
{
List<Tag> addTags(String nodeId, List<Tag> tags);
Tag getTag(StoreRef storeRef, String tagId);
void deleteTag(String nodeId, String tagId);
CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Parameters params);
Tag changeTag(StoreRef storeRef, String tagId, Tag tag);
CollectionWithPagingInfo<Tag> getTags(String nodeId, Parameters params);
@Experimental
List<Tag> createTags(StoreRef storeRef, List<Tag> tags, Parameters parameters);
@Experimental
default List<Tag> createTags(List<Tag> tags, Parameters parameters)
{
return createTags(STORE_REF_WORKSPACE_SPACESSTORE, tags, parameters);
}
void deleteTagById(StoreRef storeRef, String tagId);
}
package org.alfresco.rest.api;
import java.util.List;
import org.alfresco.rest.api.model.Tag;
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.alfresco.service.cmr.repository.StoreRef;
public interface Tags
{
public List<Tag> addTags(String nodeId, List<Tag> tags);
public Tag getTag(StoreRef storeRef, String tagId);
public void deleteTag(String nodeId, String tagId);
public CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Parameters params);
public Tag changeTag(StoreRef storeRef, String tagId, Tag tag);
public CollectionWithPagingInfo<Tag> getTags(String nodeId, Parameters params);
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* Copyright (C) 2005 - 2016 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,7 +45,6 @@ public class CategoriesEntityResource implements EntityResourceAction.ReadById<C
EntityResourceAction.Update<Category>,
EntityResourceAction.Delete
{
private final Categories categories;
public CategoriesEntityResource(Categories categories)
@@ -78,7 +77,7 @@ public class CategoriesEntityResource implements EntityResourceAction.ReadById<C
@Override
public Category update(String id, Category categoryModel, Parameters parameters)
{
return categories.updateCategoryById(id, categoryModel, parameters);
return categories.updateCategoryById(id, categoryModel);
}
/**

View File

@@ -63,7 +63,7 @@ public class NodesCategoryLinksRelation implements RelationshipResourceAction.Cr
@Override
public CollectionWithPagingInfo<Category> readAll(String nodeId, Parameters parameters)
{
return ListPage.of(categories.listCategoriesForNode(nodeId, parameters), parameters.getPaging());
return ListPage.of(categories.listCategoriesForNode(nodeId), parameters.getPaging());
}
/**
@@ -77,7 +77,7 @@ public class NodesCategoryLinksRelation implements RelationshipResourceAction.Cr
@Override
public List<Category> create(String nodeId, List<Category> categoryLinks, Parameters parameters)
{
return categories.linkNodeToCategories(nodeId, categoryLinks, parameters);
return categories.linkNodeToCategories(nodeId, categoryLinks);
}
/**
@@ -93,4 +93,5 @@ public class NodesCategoryLinksRelation implements RelationshipResourceAction.Cr
{
categories.unlinkNodeFromCategory(nodeId, categoryId, parameters);
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -26,16 +26,16 @@
package org.alfresco.rest.api.categories;
import javax.servlet.http.HttpServletResponse;
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.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<Category> readAll(String parentCategoryId, Parameters parameters)
public CollectionWithPagingInfo<Category> readAll(String parentCategoryId, Parameters params)
{
return ListPage.of(categories.getCategoryChildren(parentCategoryId, parameters), parameters.getPaging());
return categories.getCategoryChildren(parentCategoryId, params);
}
}

View File

@@ -46,8 +46,10 @@ 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.InvalidNodeTypeException;
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.resource.parameters.Parameters;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -60,7 +62,6 @@ 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;
@@ -68,7 +69,6 @@ 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,89 +95,63 @@ public class CategoriesImpl implements Categories
}
@Override
public Category getCategoryById(final StoreRef storeRef, final String id, final Parameters parameters)
public Category getCategoryById(final String id, final Parameters params)
{
final NodeRef nodeRef = getCategoryNodeRef(storeRef, id);
final NodeRef nodeRef = getCategoryNodeRef(id);
if (isRootCategory(nodeRef))
{
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
}
final Category category = mapToCategory(nodeRef);
if (parameters.getInclude().contains(INCLUDE_COUNT_PARAM))
{
final Map<String, Integer> categoriesCount = getCategoriesCount(storeRef);
category.setCount(categoriesCount.getOrDefault(category.getId(), 0));
}
return category;
return mapToCategory(nodeRef);
}
@Override
public List<Category> createSubcategories(final StoreRef storeRef, final String parentCategoryId, final List<Category> categories, final Parameters parameters)
public List<Category> createSubcategories(String parentCategoryId, List<Category> categories, Parameters parameters)
{
verifyAdminAuthority();
final NodeRef parentNodeRef = getCategoryNodeRef(storeRef, parentCategoryId);
return categories.stream()
final NodeRef parentNodeRef = getCategoryNodeRef(parentCategoryId);
final List<NodeRef> categoryNodeRefs = 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 List<Category> getCategoryChildren(final StoreRef storeRef, final String parentCategoryId, final Parameters parameters)
public CollectionWithPagingInfo<Category> getCategoryChildren(String parentCategoryId, Parameters params)
{
final NodeRef parentNodeRef = getCategoryNodeRef(storeRef, parentCategoryId);
final List<Category> 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<String, Integer> categoriesCount = getCategoriesCount(storeRef);
categories.forEach(category -> category.setCount(categoriesCount.getOrDefault(category.getId(), 0)));
}
return categories;
final NodeRef parentNodeRef = getCategoryNodeRef(parentCategoryId);
final List<ChildAssociationRef> childCategoriesAssocs = nodeService.getChildAssocs(parentNodeRef).stream()
.filter(ca -> ContentModel.ASSOC_SUBCATEGORIES.equals(ca.getTypeQName()))
.collect(Collectors.toList());
final List<Category> categories = childCategoriesAssocs.stream()
.map(c -> mapToCategory(c.getChildRef()))
.collect(Collectors.toList());
return ListPage.of(categories, params.getPaging());
}
@Override
public Category updateCategoryById(final StoreRef storeRef, final String id, final Category fixedCategoryModel, final Parameters parameters)
public Category updateCategoryById(final String id, final Category fixedCategoryModel)
{
verifyAdminAuthority();
final NodeRef categoryNodeRef = getCategoryNodeRef(storeRef, id);
final NodeRef categoryNodeRef = getCategoryNodeRef(id);
if (isRootCategory(categoryNodeRef))
{
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
}
validateCategoryFields(fixedCategoryModel);
final Category category = mapToCategory(changeCategoryName(categoryNodeRef, fixedCategoryModel.getName()));
if (parameters.getInclude().contains(INCLUDE_COUNT_PARAM))
{
final Map<String, Integer> categoriesCount = getCategoriesCount(storeRef);
category.setCount(categoriesCount.getOrDefault(category.getId(), 0));
}
return category;
return mapToCategory(changeCategoryName(categoryNodeRef, fixedCategoryModel.getName()));
}
@Override
public void deleteCategoryById(final StoreRef storeRef, final String id, final Parameters parameters)
public void deleteCategoryById(String id, Parameters parameters)
{
verifyAdminAuthority();
final NodeRef nodeRef = getCategoryNodeRef(storeRef, id);
final NodeRef nodeRef = getCategoryNodeRef(id);
if (isRootCategory(nodeRef))
{
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
@@ -187,7 +161,7 @@ public class CategoriesImpl implements Categories
}
@Override
public List<Category> listCategoriesForNode(final String nodeId, final Parameters parameters)
public List<Category> listCategoriesForNode(final String nodeId)
{
final NodeRef contentNodeRef = nodes.validateNode(nodeId);
verifyReadPermission(contentNodeRef);
@@ -204,7 +178,7 @@ public class CategoriesImpl implements Categories
}
@Override
public List<Category> linkNodeToCategories(final StoreRef storeRef, final String nodeId, final List<Category> categoryLinks, final Parameters parameters)
public List<Category> linkNodeToCategories(final String nodeId, final List<Category> categoryLinks)
{
if (CollectionUtils.isEmpty(categoryLinks))
{
@@ -220,7 +194,7 @@ public class CategoriesImpl implements Categories
.map(Category::getId)
.filter(StringUtils::isNotEmpty)
.distinct()
.map(id -> getCategoryNodeRef(storeRef, id))
.map(this::getCategoryNodeRef)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(categoryNodeRefs) || isRootCategoryPresent(categoryNodeRefs))
@@ -234,9 +208,9 @@ public class CategoriesImpl implements Categories
}
@Override
public void unlinkNodeFromCategory(final StoreRef storeRef, final String nodeId, final String categoryId, final Parameters parameters)
public void unlinkNodeFromCategory(final String nodeId, final String categoryId, Parameters parameters)
{
final NodeRef categoryNodeRef = getCategoryNodeRef(storeRef, categoryId);
final NodeRef categoryNodeRef = getCategoryNodeRef(categoryId);
final NodeRef contentNodeRef = nodes.validateNode(nodeId);
verifyChangePermission(contentNodeRef);
verifyNodeType(contentNodeRef);
@@ -298,14 +272,13 @@ 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(StoreRef storeRef, String nodeId)
private NodeRef getCategoryNodeRef(String nodeId)
{
return PATH_ROOT.equals(nodeId) ?
categoryService.getRootCategoryNodeRef(storeRef)
categoryService.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE)
.orElseThrow(() -> new EntityNotFoundException(nodeId)) :
validateCategoryNode(nodeId);
}
@@ -461,18 +434,4 @@ 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<String, Integer> 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));
}
}

View File

@@ -1,294 +1,239 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.impl;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.tagging.NonExistentTagException;
import org.alfresco.repo.tagging.TagExistsException;
import org.alfresco.repo.tagging.TaggingException;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.Tags;
import org.alfresco.rest.api.model.Tag;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException;
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.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.tagging.TaggingService;
import org.alfresco.util.Pair;
import org.alfresco.util.TypeConstraint;
import org.apache.commons.collections.CollectionUtils;
/**
* Centralises access to tag services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class TagsImpl implements Tags
{
private static final Object PARAM_INCLUDE_COUNT = "count";
static final String NOT_A_VALID_TAG = "An invalid parameter has been supplied";
static final String NO_PERMISSION_TO_MANAGE_A_TAG = "Current user does not have permission to manage a tag";
private Nodes nodes;
private TaggingService taggingService;
private TypeConstraint typeConstraint;
private AuthorityService authorityService;
public void setTypeConstraint(TypeConstraint typeConstraint)
{
this.typeConstraint = typeConstraint;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setTaggingService(TaggingService taggingService)
{
this.taggingService = taggingService;
}
public void setAuthorityService(AuthorityService authorityService)
{
this.authorityService = authorityService;
}
public List<Tag> addTags(String nodeId, final List<Tag> tags)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
if(!typeConstraint.matches(nodeRef))
{
throw new UnsupportedResourceOperationException("Cannot tag this node");
}
List<String> tagValues = new AbstractList<String>()
{
@Override
public String get(int arg0)
{
String tag = tags.get(arg0).getTag();
return tag;
}
@Override
public int size()
{
return tags.size();
}
};
try
{
List<Pair<String, NodeRef>> tagNodeRefs = taggingService.addTags(nodeRef, tagValues);
List<Tag> ret = new ArrayList<Tag>(tags.size());
for(Pair<String, NodeRef> pair : tagNodeRefs)
{
ret.add(new Tag(pair.getSecond(), pair.getFirst()));
}
return ret;
}
catch(IllegalArgumentException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public void deleteTag(String nodeId, String tagId)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
getTag(tagId);
NodeRef existingTagNodeRef = validateTag(tagId);
String tagValue = taggingService.getTagName(existingTagNodeRef);
taggingService.removeTag(nodeRef, tagValue);
}
@Override
public void deleteTagById(StoreRef storeRef, String tagId) {
verifyAdminAuthority();
NodeRef tagNodeRef = validateTag(storeRef, tagId);
String tagValue = taggingService.getTagName(tagNodeRef);
taggingService.deleteTag(storeRef, tagValue);
}
public CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Parameters params)
{
Paging paging = params.getPaging();
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(storeRef, Util.getPagingRequest(paging));
taggingService.getPagedTags(storeRef, 0, paging.getMaxItems());
Integer totalItems = results.getTotalResultCount().getFirst();
List<Pair<NodeRef, String>> page = results.getPage();
List<Tag> tags = new ArrayList<Tag>(page.size());
List<Pair<String, Integer>> tagsByCount = null;
Map<String, Integer> tagsByCountMap = new HashMap<String, Integer>();
if (params.getInclude().contains(PARAM_INCLUDE_COUNT))
{
tagsByCount = taggingService.findTaggedNodesAndCountByTagName(storeRef);
if (tagsByCount != null)
{
for (Pair<String, Integer> tagByCountElem : tagsByCount)
{
tagsByCountMap.put(tagByCountElem.getFirst(), tagByCountElem.getSecond());
}
}
}
for (Pair<NodeRef, String> pair : page)
{
Tag selectedTag = new Tag(pair.getFirst(), pair.getSecond());
selectedTag.setCount(Optional.ofNullable(tagsByCountMap.get(selectedTag.getTag())).orElse(0));
tags.add(selectedTag);
}
return CollectionWithPagingInfo.asPaged(paging, tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue()));
}
public NodeRef validateTag(String tagId)
{
NodeRef tagNodeRef = nodes.validateNode(tagId);
if(tagNodeRef == null)
{
throw new EntityNotFoundException(tagId);
}
return tagNodeRef;
}
public NodeRef validateTag(StoreRef storeRef, String tagId)
{
NodeRef tagNodeRef = nodes.validateNode(storeRef, tagId);
if(tagNodeRef == null)
{
throw new EntityNotFoundException(tagId);
}
return tagNodeRef;
}
public Tag changeTag(StoreRef storeRef, String tagId, Tag tag)
{
try
{
NodeRef existingTagNodeRef = validateTag(storeRef, tagId);
String existingTagName = taggingService.getTagName(existingTagNodeRef);
String newTagName = tag.getTag();
NodeRef newTagNodeRef = taggingService.changeTag(storeRef, existingTagName, newTagName);
return new Tag(newTagNodeRef, newTagName);
}
catch(NonExistentTagException e)
{
throw new NotFoundException(e.getMessage());
}
catch(TagExistsException e)
{
throw new ConstraintViolatedException(e.getMessage());
}
catch(TaggingException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public Tag getTag(String tagId)
{
return getTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, tagId);
}
public Tag getTag(StoreRef storeRef, String tagId)
{
NodeRef tagNodeRef = validateTag(storeRef, tagId);
String tagValue = taggingService.getTagName(tagNodeRef);
return new Tag(tagNodeRef, tagValue);
}
public CollectionWithPagingInfo<Tag> getTags(String nodeId, Parameters params)
{
NodeRef nodeRef = validateTag(nodeId);
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(nodeRef, Util.getPagingRequest(params.getPaging()));
Integer totalItems = results.getTotalResultCount().getFirst();
List<Pair<NodeRef, String>> page = results.getPage();
List<Tag> tags = new ArrayList<Tag>(page.size());
for(Pair<NodeRef, String> pair : page)
{
tags.add(new Tag(pair.getFirst(), pair.getSecond()));
}
return CollectionWithPagingInfo.asPaged(params.getPaging(), tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue()));
}
@Experimental
@Override
public List<Tag> createTags(final StoreRef storeRef, final List<Tag> tags, final Parameters parameters)
{
verifyAdminAuthority();
final List<String> tagNames = Optional.ofNullable(tags).orElse(Collections.emptyList()).stream()
.filter(Objects::nonNull)
.map(Tag::getTag)
.distinct()
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(tagNames))
{
throw new InvalidArgumentException(NOT_A_VALID_TAG);
}
return taggingService.createTags(storeRef, tagNames).stream()
.map(pair -> Tag.builder().tag(pair.getFirst()).nodeRef(pair.getSecond()).create())
.peek(tag -> {
if (parameters.getInclude().contains(PARAM_INCLUDE_COUNT))
{
tag.setCount(0);
}
}).collect(Collectors.toList());
}
private void verifyAdminAuthority()
{
if (!authorityService.hasAdminAuthority())
{
throw new PermissionDeniedException(NO_PERMISSION_TO_MANAGE_A_TAG);
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 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.impl;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.tagging.NonExistentTagException;
import org.alfresco.repo.tagging.TagExistsException;
import org.alfresco.repo.tagging.TaggingException;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.Tags;
import org.alfresco.rest.api.model.Tag;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException;
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.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.tagging.TaggingService;
import org.alfresco.util.Pair;
import org.alfresco.util.TypeConstraint;
/**
* Centralises access to tag services and maps between representations.
*
* @author steveglover
* @since publicapi1.0
*/
public class TagsImpl implements Tags
{
private static final Object PARAM_INCLUDE_COUNT = "count";
private Nodes nodes;
private TaggingService taggingService;
private TypeConstraint typeConstraint;
public void setTypeConstraint(TypeConstraint typeConstraint)
{
this.typeConstraint = typeConstraint;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setTaggingService(TaggingService taggingService)
{
this.taggingService = taggingService;
}
public List<Tag> addTags(String nodeId, final List<Tag> tags)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
if(!typeConstraint.matches(nodeRef))
{
throw new UnsupportedResourceOperationException("Cannot tag this node");
}
List<String> tagValues = new AbstractList<String>()
{
@Override
public String get(int arg0)
{
String tag = tags.get(arg0).getTag();
return tag;
}
@Override
public int size()
{
return tags.size();
}
};
try
{
List<Pair<String, NodeRef>> tagNodeRefs = taggingService.addTags(nodeRef, tagValues);
List<Tag> ret = new ArrayList<Tag>(tags.size());
for(Pair<String, NodeRef> pair : tagNodeRefs)
{
ret.add(new Tag(pair.getSecond(), pair.getFirst()));
}
return ret;
}
catch(IllegalArgumentException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public void deleteTag(String nodeId, String tagId)
{
NodeRef nodeRef = nodes.validateNode(nodeId);
getTag(tagId);
NodeRef existingTagNodeRef = validateTag(tagId);
String tagValue = taggingService.getTagName(existingTagNodeRef);
taggingService.removeTag(nodeRef, tagValue);
}
public CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Parameters params)
{
Paging paging = params.getPaging();
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(storeRef, Util.getPagingRequest(paging));
taggingService.getPagedTags(storeRef, 0, paging.getMaxItems());
Integer totalItems = results.getTotalResultCount().getFirst();
List<Pair<NodeRef, String>> page = results.getPage();
List<Tag> tags = new ArrayList<Tag>(page.size());
List<Pair<String, Integer>> tagsByCount = null;
Map<String, Integer> tagsByCountMap = new HashMap<String, Integer>();
if (params.getInclude().contains(PARAM_INCLUDE_COUNT))
{
tagsByCount = taggingService.findTaggedNodesAndCountByTagName(storeRef);
if (tagsByCount != null)
{
for (Pair<String, Integer> tagByCountElem : tagsByCount)
{
tagsByCountMap.put(tagByCountElem.getFirst(), tagByCountElem.getSecond());
}
}
}
for (Pair<NodeRef, String> pair : page)
{
Tag selectedTag = new Tag(pair.getFirst(), pair.getSecond());
selectedTag.setCount(tagsByCountMap.get(selectedTag.getTag()));
tags.add(selectedTag);
}
return CollectionWithPagingInfo.asPaged(paging, tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue()));
}
public NodeRef validateTag(String tagId)
{
NodeRef tagNodeRef = nodes.validateNode(tagId);
if(tagNodeRef == null)
{
throw new EntityNotFoundException(tagId);
}
return tagNodeRef;
}
public NodeRef validateTag(StoreRef storeRef, String tagId)
{
NodeRef tagNodeRef = nodes.validateNode(storeRef, tagId);
if(tagNodeRef == null)
{
throw new EntityNotFoundException(tagId);
}
String tag = taggingService.getTagName(tagNodeRef);
if(taggingService.isTag(storeRef,tag)==false)
{
throw new EntityNotFoundException(tagId);
}
return tagNodeRef;
}
public Tag changeTag(StoreRef storeRef, String tagId, Tag tag)
{
try
{
NodeRef existingTagNodeRef = validateTag(storeRef, tagId);
String existingTagName = taggingService.getTagName(existingTagNodeRef);
String newTagName = tag.getTag();
NodeRef newTagNodeRef = taggingService.changeTag(storeRef, existingTagName, newTagName);
return new Tag(newTagNodeRef, newTagName);
}
catch(NonExistentTagException e)
{
throw new NotFoundException(e.getMessage());
}
catch(TagExistsException e)
{
throw new ConstraintViolatedException(e.getMessage());
}
catch(TaggingException e)
{
throw new InvalidArgumentException(e.getMessage());
}
}
public Tag getTag(String tagId)
{
return getTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, tagId);
}
public Tag getTag(StoreRef storeRef, String tagId)
{
NodeRef tagNodeRef = validateTag(storeRef, tagId);
String tagValue = taggingService.getTagName(tagNodeRef);
return new Tag(tagNodeRef, tagValue);
}
public CollectionWithPagingInfo<Tag> getTags(String nodeId, Parameters params)
{
NodeRef nodeRef = validateTag(nodeId);
PagingResults<Pair<NodeRef, String>> results = taggingService.getTags(nodeRef, Util.getPagingRequest(params.getPaging()));
Integer totalItems = results.getTotalResultCount().getFirst();
List<Pair<NodeRef, String>> page = results.getPage();
List<Tag> tags = new ArrayList<Tag>(page.size());
for(Pair<NodeRef, String> pair : page)
{
tags.add(new Tag(pair.getFirst(), pair.getSecond()));
}
return CollectionWithPagingInfo.asPaged(params.getPaging(), tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue()));
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -34,7 +34,6 @@ public class Category
private String name;
private String parentId;
private boolean hasChildren;
private Integer count;
public String getId()
{
@@ -81,38 +80,20 @@ 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) && Objects.equals(name, category.name) && Objects.equals(parentId, category.parentId)
&& Objects.equals(count, category.count);
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, count);
}
@Override
public String toString()
{
return "Category{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", parentId='" + parentId + '\'' + ", hasChildren=" + hasChildren + ", count=" + count + '}';
return Objects.hash(id, name, parentId, hasChildren);
}
public static Builder builder()
@@ -126,7 +107,6 @@ public class Category
private String name;
private String parentId;
private boolean hasChildren;
private Integer count;
public Builder id(String id)
{
@@ -152,12 +132,6 @@ public class Category
return this;
}
public Builder count(Integer count)
{
this.count = count;
return this;
}
public Category create()
{
final Category category = new Category();
@@ -165,7 +139,6 @@ public class Category
category.setName(name);
category.setParentId(parentId);
category.setHasChildren(hasChildren);
category.setCount(count);
return category;
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -25,8 +25,6 @@
*/
package org.alfresco.rest.api.model;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.framework.resource.UniqueId;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -111,7 +109,7 @@ public class Tag implements Comparable<Tag>
/*
* Tags are equal if they have the same NodeRef
*
*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@@ -136,45 +134,7 @@ public class Tag implements Comparable<Tag>
@Override
public String toString()
{
return "Tag{" + "nodeRef=" + nodeRef + ", tag='" + tag + '\'' + ", count=" + count + '}';
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private NodeRef nodeRef;
private String tag;
private Integer count;
public Builder nodeRef(NodeRef nodeRef)
{
this.nodeRef = nodeRef;
return this;
}
public Builder tag(String tag)
{
this.tag = tag;
return this;
}
public Builder count(Integer count)
{
this.count = count;
return this;
}
public Tag create()
{
final Tag tag = new Tag();
tag.setNodeRef(nodeRef);
tag.setTag(this.tag);
tag.setCount(count);
return tag;
}
return "Tag [nodeRef=" + nodeRef + ", tag=" + tag + "]";
}
}

View File

@@ -1,33 +1,30 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 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.tags;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import org.alfresco.rest.api.Tags;
import org.alfresco.rest.api.model.Tag;
import org.alfresco.rest.framework.WebApiDescription;
@@ -36,14 +33,12 @@ import org.alfresco.rest.framework.resource.EntityResource;
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
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;
import org.alfresco.util.ParameterCheck;
import org.springframework.beans.factory.InitializingBean;
@EntityResource(name="tags", title = "Tags")
public class TagsEntityResource implements EntityResourceAction.Read<Tag>,
EntityResourceAction.ReadById<Tag>, EntityResourceAction.Update<Tag>, EntityResourceAction.Create<Tag>, EntityResourceAction.Delete, InitializingBean
public class TagsEntityResource implements EntityResourceAction.Read<Tag>, EntityResourceAction.ReadById<Tag>, EntityResourceAction.Update<Tag>, InitializingBean
{
private Tags tags;
@@ -82,25 +77,4 @@ public class TagsEntityResource implements EntityResourceAction.Read<Tag>,
{
return tags.getTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id);
}
/**
* POST /tags
*/
@Experimental
@WebApiDescription(
title = "Create an orphan tag",
description = "Creates a tag, which is not associated with any node",
successStatus = HttpServletResponse.SC_CREATED
)
@Override
public List<Tag> create(List<Tag> tags, Parameters parameters)
{
return this.tags.createTags(tags, parameters);
}
@Override
public void delete(String id, Parameters parameters)
{
tags.deleteTagById(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id);
}
}

View File

@@ -856,7 +856,6 @@
<bean id="tags" class="org.alfresco.rest.api.impl.TagsImpl">
<property name="nodes" ref="nodes" />
<property name="taggingService" ref="TaggingService" />
<property name="authorityService" ref="AuthorityService" />
<property name="typeConstraint" ref="nodeTypeConstraint" />
</bean>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -49,8 +49,6 @@ 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.TagsUnitTests.class,
org.alfresco.rest.api.impl.ContentStorageInformationImplTest.class,
org.alfresco.rest.api.nodes.NodeStorageInfoRelationTest.class,
org.alfresco.rest.api.search.ResultMapperTests.class,

View File

@@ -1,47 +0,0 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #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
{
}

View File

@@ -1,42 +0,0 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api;
import org.alfresco.rest.api.impl.TagsImplTest;
import org.alfresco.rest.api.tags.TagsEntityResourceTest;
import org.alfresco.service.Experimental;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@Experimental
@RunWith(Suite.class)
@Suite.SuiteClasses({
TagsImplTest.class,
TagsEntityResourceTest.class
})
public class TagsUnitTests
{
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -26,21 +26,15 @@
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;
@@ -51,7 +45,6 @@ import org.mockito.junit.MockitoJUnitRunner;
public class CategoriesEntityResourceTest
{
private static final String CATEGORY_ID = "category-node-id";
@Mock
private Categories categoriesMock;
@Mock
@@ -65,37 +58,26 @@ public class CategoriesEntityResourceTest
@Test
public void testReadCategoryById()
{
given(categoriesMock.getCategoryById(any(), any())).willCallRealMethod();
given(categoriesMock.getCategoryById(any(), any(), any())).willReturn(categoryMock);
given(categoriesMock.getCategoryById(CATEGORY_ID, parametersMock)).willReturn(categoryMock);
//when
final Category category = objectUnderTest.readById(CATEGORY_ID, parametersMock);
then(categoriesMock).should().getCategoryById(STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID, parametersMock);
then(categoriesMock).should().getCategoryById(CATEGORY_ID, parametersMock);
then(categoriesMock).shouldHaveNoMoreInteractions();
assertEquals(categoryMock, category);
}
@Test
public void testUpdateCategoryById()
{
given(categoriesMock.updateCategoryById(any(), any(), any())).willCallRealMethod();
given(categoriesMock.updateCategoryById(any(), any(), any(), any())).willReturn(categoryMock);
given(categoriesMock.updateCategoryById(any(), any())).willReturn(categoryMock);
// when
final Category actualCategory = objectUnderTest.update(CATEGORY_ID, categoryMock, parametersMock);
then(categoriesMock).should().updateCategoryById(STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID, categoryMock, parametersMock);
then(categoriesMock).should().updateCategoryById(CATEGORY_ID, categoryMock);
then(categoriesMock).shouldHaveNoMoreInteractions();
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);
}
}

View File

@@ -47,7 +47,6 @@ 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;
@@ -62,12 +61,12 @@ public class NodesCategoryLinksRelationTest
@Test
public void testReadAll()
{
given(categoriesMock.listCategoriesForNode(any(), any())).willReturn(List.of(categoryMock));
given(categoriesMock.listCategoriesForNode(any())).willReturn(List.of(categoryMock));
// when
final CollectionWithPagingInfo<Category> actualCategoriesPage = objectUnderTest.readAll(CONTENT_ID, parametersMock);
then(categoriesMock).should().listCategoriesForNode(CONTENT_ID, parametersMock);
then(categoriesMock).should().listCategoriesForNode(CONTENT_ID);
then(categoriesMock).shouldHaveNoMoreInteractions();
assertThat(actualCategoriesPage)
.isNotNull()
@@ -78,25 +77,15 @@ public class NodesCategoryLinksRelationTest
@Test
public void testCreate()
{
given(categoriesMock.linkNodeToCategories(any(), any(), any())).willReturn(List.of(categoryMock));
given(categoriesMock.linkNodeToCategories(any(), any())).willReturn(List.of(categoryMock));
// when
final List<Category> actualCategories = objectUnderTest.create(CONTENT_ID, List.of(categoryMock), parametersMock);
then(categoriesMock).should().linkNodeToCategories(CONTENT_ID, List.of(categoryMock), parametersMock);
then(categoriesMock).should().linkNodeToCategories(CONTENT_ID, List.of(categoryMock));
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();
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* 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
@@ -26,10 +26,7 @@
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;
@@ -40,8 +37,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;
@@ -70,37 +67,39 @@ 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<Category> categoriesToCreate = List.of(categoryToCreate);
given(categoriesMock.createSubcategories(any(), any(), any())).willCallRealMethod();
given(categoriesMock.createSubcategories(any(), any(), any(), any())).willReturn(List.of(category));
given(categoriesMock.createSubcategories(PARENT_CATEGORY_ID, categoriesToCreate, parametersMock)).willReturn(List.of(category));
//when
List<Category> categories = objectUnderTest.create(PARENT_CATEGORY_ID, categoriesToCreate, parametersMock);
then(categoriesMock).should().createSubcategories(STORE_REF_WORKSPACE_SPACESSTORE, PARENT_CATEGORY_ID, categoriesToCreate, parametersMock);
then(categoriesMock).should().createSubcategories(PARENT_CATEGORY_ID, categoriesToCreate, parametersMock);
then(categoriesMock).shouldHaveNoMoreInteractions();
assertEquals(List.of(category), categories);
}
@Test
public void testGetCategoryChildren() {
final List<Category> categoryChildren = getCategories(3);
given(categoriesMock.getCategoryChildren(any(), any())).willCallRealMethod();
given(categoriesMock.getCategoryChildren(any(), any(), any())).willReturn(categoryChildren);
final CollectionWithPagingInfo<Category> categoryChildren = getCategories(3);
given(categoriesMock.getCategoryChildren(PARENT_CATEGORY_ID, parametersMock)).willReturn(categoryChildren);
//when
final CollectionWithPagingInfo<Category> returnedChildren = objectUnderTest.readAll(PARENT_CATEGORY_ID, parametersMock);
then(categoriesMock).should().getCategoryChildren(STORE_REF_WORKSPACE_SPACESSTORE, PARENT_CATEGORY_ID, parametersMock);
assertEquals(categoryChildren, returnedChildren.getCollection());
then(categoriesMock).should().getCategoryChildren(PARENT_CATEGORY_ID, parametersMock);
then(categoriesMock).shouldHaveNoMoreInteractions();
assertEquals(categoryChildren, returnedChildren);
}
private List<Category> getCategories(final int count)
private CollectionWithPagingInfo<Category> getCategories(final int count)
{
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());
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())
);
}
}

View File

@@ -27,13 +27,11 @@
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;
@@ -41,7 +39,6 @@ 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;
@@ -67,6 +64,7 @@ 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;
@@ -79,7 +77,6 @@ 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;
@@ -97,7 +94,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 = createDefaultCategory();
private static final Category CATEGORY = createDefaultCategoryWithName(CATEGORY_NAME);
private static final String CONTENT_NODE_ID = "content-node-id";
private static final NodeRef CONTENT_NODE_REF = createNodeRefWithId(CONTENT_NODE_ID);
@@ -106,6 +103,8 @@ public class CategoriesImplTest
@Mock
private NodeService nodeServiceMock;
@Mock
private Parameters parametersMock;
@Mock
private AuthorityService authorityServiceMock;
@Mock
private CategoryService categoryServiceMock;
@@ -117,8 +116,6 @@ public class CategoriesImplTest
private PermissionService permissionServiceMock;
@Mock
private TypeConstraint typeConstraint;
@Mock
private Parameters parametersMock;
@InjectMocks
private CategoriesImpl objectUnderTest;
@@ -138,7 +135,7 @@ public class CategoriesImplTest
@Test
public void shouldNotGetRootCategoryById()
{
final NodeRef categoryRootNodeRef = createNodeRefWithId(CAT_ROOT_NODE_ID);
final NodeRef categoryRootNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, 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));
@@ -158,26 +155,31 @@ public class CategoriesImplTest
@Test
public void testGetCategoryById_withChildren()
{
final NodeRef parentNodeRef = createNodeRefWithId(PARENT_ID);
final Node categoryNode = createNode(CATEGORY_NAME, CATEGORY_ID, parentNodeRef);
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);
given(nodesMock.getNode(CATEGORY_ID)).willReturn(categoryNode);
final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentNodeRef, null, CATEGORY_NODE_REF);
given(nodeServiceMock.getPrimaryParent(CATEGORY_NODE_REF)).willReturn(parentAssoc);
final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentNodeRef, null, categoryNodeRef);
given(nodeServiceMock.getPrimaryParent(categoryNodeRef)).willReturn(parentAssoc);
final List<ChildAssociationRef> dummyChildren = List.of(dummyChildAssociationRefMock);
given(nodeServiceMock.getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
given(nodeServiceMock.getChildAssocs(categoryNodeRef, 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(CATEGORY_NODE_REF, ContentModel.TYPE_CATEGORY, false);
then(nodesMock).should().isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false);
then(nodesMock).should().getNode(CATEGORY_ID);
then(nodesMock).shouldHaveNoMoreInteractions();
then(nodeServiceMock).should().getPrimaryParent(CATEGORY_NODE_REF);
then(nodeServiceMock).should().getPrimaryParent(categoryNodeRef);
then(nodeServiceMock).should().getParentAssocs(parentNodeRef);
then(nodeServiceMock).should().getParentAssocs(CATEGORY_NODE_REF);
then(nodeServiceMock).should().getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
then(nodeServiceMock).should().getParentAssocs(categoryNodeRef);
then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
then(nodeServiceMock).shouldHaveNoMoreInteractions();
then(categoryServiceMock).shouldHaveNoInteractions();
@@ -195,25 +197,30 @@ public class CategoriesImplTest
@Test
public void testGetCategoryById_withoutChildren()
{
final NodeRef parentNodeRef = createNodeRefWithId(PARENT_ID);
final Node categoryNode = createNode(CATEGORY_NAME, CATEGORY_ID, parentNodeRef);
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);
given(nodesMock.getNode(CATEGORY_ID)).willReturn(categoryNode);
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))
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))
.willReturn(Collections.emptyList());
//when
final Category category = objectUnderTest.getCategoryById(CATEGORY_ID, parametersMock);
then(nodesMock).should().validateNode(CATEGORY_ID);
then(nodesMock).should().isSubClass(CATEGORY_NODE_REF, ContentModel.TYPE_CATEGORY, false);
then(nodesMock).should().isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false);
then(nodesMock).should().getNode(CATEGORY_ID);
then(nodesMock).shouldHaveNoMoreInteractions();
then(nodeServiceMock).should().getPrimaryParent(CATEGORY_NODE_REF);
then(nodeServiceMock).should().getPrimaryParent(categoryNodeRef);
then(nodeServiceMock).should().getParentAssocs(parentNodeRef);
then(nodeServiceMock).should().getParentAssocs(CATEGORY_NODE_REF);
then(nodeServiceMock).should().getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
then(nodeServiceMock).should().getParentAssocs(categoryNodeRef);
then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
then(nodeServiceMock).shouldHaveNoMoreInteractions();
then(categoryServiceMock).shouldHaveNoInteractions();
@@ -228,30 +235,6 @@ 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()
{
@@ -291,9 +274,14 @@ public class CategoriesImplTest
public void testDeleteCategoryById_asAdmin()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
final NodeRef categoryNodeRef = createNodeRefWithId(CATEGORY_ID);
final NodeRef categoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, 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);
@@ -329,7 +317,7 @@ public class CategoriesImplTest
public void testDeleteCategoryById_nonCategoryId()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
final NodeRef categoryNodeRef = createNodeRefWithId(CATEGORY_ID);
final NodeRef categoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID);
given(nodesMock.validateNode(CATEGORY_ID)).willReturn(categoryNodeRef);
given(nodesMock.isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(false);
@@ -348,7 +336,7 @@ public class CategoriesImplTest
public void testDeleteCategoryById_rootCategory()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
final NodeRef categoryRootNodeRef = createNodeRefWithId(CAT_ROOT_NODE_ID);
final NodeRef categoryRootNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, 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);
@@ -371,13 +359,13 @@ public class CategoriesImplTest
@Test
public void testCreateCategoryUnderRoot()
{
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PATH_ROOT);
final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, 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(createNode());
final ChildAssociationRef parentAssoc = createAssociationOf(parentCategoryNodeRef, 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))
@@ -412,12 +400,12 @@ public class CategoriesImplTest
@Test
public void testCreateCategory()
{
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, 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(createNode());
final ChildAssociationRef parentAssoc = createAssociationOf(parentCategoryNodeRef, 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))
@@ -450,35 +438,6 @@ 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<Category> categoryModels = prepareCategories().stream().peek(category -> category.setCount(1)).collect(Collectors.toList());
// when
final List<Category> 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()
{
@@ -535,7 +494,7 @@ public class CategoriesImplTest
@Test
public void testGetRootCategoryChildren()
{
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PATH_ROOT);
final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PATH_ROOT);
given(categoryServiceMock.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE))
.willReturn(Optional.of(parentCategoryNodeRef));
final int childrenCount = 3;
@@ -544,7 +503,7 @@ public class CategoriesImplTest
childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks);
//when
final List<Category> categoryChildren = objectUnderTest.getCategoryChildren(PATH_ROOT, parametersMock);
final CollectionWithPagingInfo<Category> categoryChildren = objectUnderTest.getCategoryChildren(PATH_ROOT, parametersMock);
then(categoryServiceMock).should().getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
then(categoryServiceMock).shouldHaveNoMoreInteractions();
@@ -562,14 +521,16 @@ public class CategoriesImplTest
then(authorityServiceMock).shouldHaveNoInteractions();
assertEquals(childAssociationRefMocks.size(), categoryChildren.size());
IntStream.range(0, childrenCount).forEach(i -> doCategoryAssertions(categoryChildren.get(i), i, PATH_ROOT));
assertEquals(childAssociationRefMocks.size(), categoryChildren.getTotalItems().intValue());
final List<Category> categoryChildrenList = new ArrayList<>(categoryChildren.getCollection());
assertEquals(childAssociationRefMocks.size(), categoryChildrenList.size());
IntStream.range(0, childrenCount).forEach(i -> doCategoryAssertions(categoryChildrenList.get(i), i, PATH_ROOT));
}
@Test
public void testGetCategoryChildren()
{
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
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 int childrenCount = 3;
@@ -578,7 +539,7 @@ public class CategoriesImplTest
childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks);
//when
final List<Category> categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
final CollectionWithPagingInfo<Category> categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
then(nodesMock).should().validateNode(PARENT_ID);
then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
@@ -597,47 +558,24 @@ public class CategoriesImplTest
then(authorityServiceMock).shouldHaveNoInteractions();
then(categoryServiceMock).shouldHaveNoInteractions();
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<ChildAssociationRef> 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<Category> 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));
assertEquals(childAssociationRefMocks.size(), categoryChildren.getTotalItems().intValue());
final List<Category> categoryChildrenList = new ArrayList<>(categoryChildren.getCollection());
assertEquals(childAssociationRefMocks.size(), categoryChildrenList.size());
IntStream.range(0, childrenCount).forEach(i -> doCategoryAssertions(categoryChildrenList.get(i), i, PARENT_ID));
}
@Test
public void testGetCategoryChildren_noChildren()
{
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
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);
given(nodeServiceMock.getChildAssocs(parentCategoryNodeRef)).willReturn(Collections.emptyList());
//when
final List<Category> categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
final CollectionWithPagingInfo<Category> categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
then(nodesMock).should().validateNode(PARENT_ID);
then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
@@ -648,13 +586,13 @@ public class CategoriesImplTest
then(authorityServiceMock).shouldHaveNoInteractions();
then(categoryServiceMock).shouldHaveNoInteractions();
assertEquals(0, categoryChildren.size());
assertEquals(0, categoryChildren.getTotalItems().intValue());
}
@Test
public void testGetCategoryChildren_wrongParentNodeType()
{
final NodeRef parentCategoryNodeRef = createNodeRefWithId(PARENT_ID);
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);
@@ -695,12 +633,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(createNode(categoryNewName));
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(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, parametersMock);
final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, fixedCategory);
then(authorityServiceMock).should().hasAdminAuthority();
then(authorityServiceMock).shouldHaveNoMoreInteractions();
@@ -723,41 +661,13 @@ 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, parametersMock));
assertThatExceptionOfType(PermissionDeniedException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY));
then(nodesMock).shouldHaveNoInteractions();
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -769,7 +679,7 @@ public class CategoriesImplTest
given(nodesMock.validateNode(any(String.class))).willThrow(EntityNotFoundException.class);
// when
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY, parametersMock));
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY));
then(nodeServiceMock).shouldHaveNoInteractions();
}
@@ -780,7 +690,7 @@ public class CategoriesImplTest
given(nodesMock.isSubClass(any(), any(), eq(false))).willReturn(false);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY, parametersMock))
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, CATEGORY))
.withMessageContaining(NOT_A_VALID_CATEGORY);
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -794,7 +704,7 @@ public class CategoriesImplTest
given(categoryChildAssociationRefMock.getQName()).willReturn(ContentModel.ASPECT_GEN_CLASSIFIABLE);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(PATH_ROOT, CATEGORY, parametersMock))
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(PATH_ROOT, CATEGORY))
.withMessageContaining(NOT_A_VALID_CATEGORY);
then(categoryServiceMock).should().getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
@@ -817,7 +727,7 @@ public class CategoriesImplTest
final Category categoryWithoutName = createCategoryOnlyWithName(invalidName);
// when
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithoutName, parametersMock))
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(() -> objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithoutName))
.withMessageContaining(NOT_NULL_OR_EMPTY);
}
}
@@ -831,12 +741,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(createNode(categoryNewName));
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(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, parametersMock);
final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithInvalidId);
final Category expectedCategory = createDefaultCategoryWithName(categoryNewName);
assertThat(actualCategory)
@@ -853,12 +763,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(createNode(categoryNewName));
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(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, parametersMock);
final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithInvalidParentId);
final Category expectedCategory = createDefaultCategoryWithName(categoryNewName);
assertThat(actualCategory)
@@ -875,12 +785,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(createNode(categoryNewName));
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(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, parametersMock);
final Category actualCategory = objectUnderTest.updateCategoryById(CATEGORY_ID, categoryWithInvalidHasChildren);
final Category expectedCategory = createDefaultCategoryWithName(categoryNewName);
assertThat(actualCategory)
@@ -894,11 +804,11 @@ public class CategoriesImplTest
final List<Category> categoryLinks = List.of(CATEGORY);
final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF);
given(nodesMock.getNode(any())).willReturn(createNode());
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode());
given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
// when
final List<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock);
final List<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks);
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS);
@@ -928,12 +838,12 @@ public class CategoriesImplTest
{
final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF);
given(nodesMock.getNode(any())).willReturn(createNode());
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode());
given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
given(nodeServiceMock.hasAspect(any(), any())).willReturn(true);
// when
final List<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock);
final List<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY));
then(nodesMock).should().getNode(CATEGORY_ID);
then(nodeServiceMock).should().getChildAssocs(CATEGORY_NODE_REF, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
@@ -963,11 +873,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(createNode(), createNode(secondCategoryName));
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode(), prepareCategoryNode(secondCategoryName));
given(nodeServiceMock.getPrimaryParent(any())).willReturn(categoryParentAssociation, secondCategoryParentAssociation);
// when
final List<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock);
final List<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks);
then(nodesMock).should().validateNode(CATEGORY_ID);
then(nodesMock).should().validateNode(secondCategoryId);
@@ -992,13 +902,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(createNode());
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode());
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<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock);
final List<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY));
final Serializable expectedCategories = (Serializable) Set.of(otherCategoryNodeRef, CATEGORY_NODE_REF);
then(nodeServiceMock).should().setProperty(CONTENT_NODE_REF, ContentModel.PROP_CATEGORIES, expectedCategories);
@@ -1014,7 +924,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), parametersMock));
final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY)));
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).shouldHaveNoInteractions();
@@ -1029,7 +939,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), parametersMock));
final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY)));
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS);
@@ -1044,8 +954,9 @@ public class CategoriesImplTest
{
given(typeConstraint.matches(any())).willReturn(false);
// when
final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock));
final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY)));
then(typeConstraint).should().matches(CONTENT_NODE_REF);
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -1060,7 +971,7 @@ public class CategoriesImplTest
final List<Category> categoryLinks = Collections.emptyList();
// when
final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock));
final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks));
then(nodesMock).shouldHaveNoInteractions();
then(permissionServiceMock).shouldHaveNoInteractions();
@@ -1081,7 +992,7 @@ public class CategoriesImplTest
categoryLinks.add(categoryLinkWithEmptyId);
// when
final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock));
final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks));
then(nodeServiceMock).shouldHaveNoInteractions();
assertThat(actualException)
@@ -1095,11 +1006,11 @@ public class CategoriesImplTest
final List<Category> categoryLinks = List.of(CATEGORY, CATEGORY);
final NodeRef categoryParentNodeRef = createNodeRefWithId(PARENT_ID);
final ChildAssociationRef parentAssociation = createAssociationOf(categoryParentNodeRef, CATEGORY_NODE_REF);
given(nodesMock.getNode(any())).willReturn(createNode());
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode());
given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
// when
final List<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock);
final List<Category> actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks);
final Map<QName, Serializable> expectedProperties = Map.of(ContentModel.PROP_CATEGORIES, (Serializable) List.of(CATEGORY_NODE_REF));
then(nodeServiceMock).should().addAspect(CONTENT_NODE_REF, ContentModel.ASPECT_GEN_CLASSIFIABLE, expectedProperties);
@@ -1134,7 +1045,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();
@@ -1149,11 +1060,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(createNode());
given(nodesMock.getNode(any())).willReturn(prepareCategoryNode());
given(nodeServiceMock.getPrimaryParent(any())).willReturn(parentAssociation);
// when
final List<Category> actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock);
final List<Category> actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID);
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF);
@@ -1179,7 +1090,7 @@ public class CategoriesImplTest
given(nodesMock.validateNode(CONTENT_NODE_ID)).willThrow(EntityNotFoundException.class);
// when
final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock));
final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID));
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -1193,7 +1104,7 @@ public class CategoriesImplTest
given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.DENIED);
// when
final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock));
final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID));
then(nodesMock).should().validateNode(CONTENT_NODE_ID);
then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF);
@@ -1209,7 +1120,7 @@ public class CategoriesImplTest
given(typeConstraint.matches(any())).willReturn(false);
// when
final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock));
final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID));
then(typeConstraint).should().matches(CONTENT_NODE_REF);
then(nodeServiceMock).shouldHaveNoInteractions();
@@ -1225,19 +1136,45 @@ public class CategoriesImplTest
given(nodeServiceMock.getProperty(any(), eq(ContentModel.PROP_CATEGORIES))).willReturn((Serializable) nullOrEmptyList);
// when
final List<Category> actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock);
final List<Category> actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID);
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<Category> prepareCategories()
{
return List.of(Category.builder()
.name(CATEGORY_NAME)
.create());
}
private List<ChildAssociationRef> 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(createNodeRefWithId(CATEGORY_ID + "-" + i));
.willReturn(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID + "-" + i));
given(dummyChildAssocMock.getParentRef()).willReturn(parentCategoryNodeRef);
return dummyChildAssocMock;
}).collect(Collectors.toList());
@@ -1249,8 +1186,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(createNode(name, id, parentRef));
final ChildAssociationRef parentAssoc = createAssociationOf(parentRef, childRef);
given(nodesMock.getNode(id)).willReturn(prepareCategoryNode(name, id, parentRef));
final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentRef, null, childRef);
given(nodeServiceMock.getPrimaryParent(childRef)).willReturn(parentAssoc);
given(nodeServiceMock.getParentAssocs(parentRef)).willReturn(List.of(parentAssoc));
}
@@ -1258,38 +1195,14 @@ 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<Category> 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);
@@ -1300,11 +1213,6 @@ 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()

View File

@@ -1,305 +0,0 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.impl;
import static org.alfresco.rest.api.impl.TagsImpl.NOT_A_VALID_TAG;
import static org.alfresco.rest.api.impl.TagsImpl.NO_PERMISSION_TO_MANAGE_A_TAG;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.Tag;
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.resource.parameters.Parameters;
import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.tagging.TaggingService;
import org.alfresco.util.Pair;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TagsImplTest
{
private static final String TAG_ID = "tag-node-id";
private static final String TAG_NAME = "tag-dummy-name";
private static final NodeRef TAG_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID);
@Mock
private Nodes nodesMock;
@Mock
private AuthorityService authorityServiceMock;
@Mock
private TaggingService taggingServiceMock;
@Mock
private Parameters parametersMock;
@InjectMocks
private TagsImpl objectUnderTest;
@Before
public void setup()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
given(nodesMock.validateNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID)).willReturn(TAG_NODE_REF);
given(taggingServiceMock.getTagName(TAG_NODE_REF)).willReturn(TAG_NAME);
}
@Test
public void testGetTags() {
final List<String> tagNames = List.of("testTag","tag11");
final List<Tag> tagsToCreate = createTags(tagNames);
given(taggingServiceMock.createTags(any(), any())).willAnswer(invocation -> createTagAndNodeRefPairs(invocation.getArgument(1)));
given(parametersMock.getInclude()).willReturn(List.of("count"));
final List<Tag> actualCreatedTags = objectUnderTest.createTags(tagsToCreate, parametersMock);
final List<Tag> expectedTags = createTagsWithNodeRefs(tagNames).stream()
.peek(tag -> tag.setCount(0))
.collect(Collectors.toList());
assertEquals(expectedTags, actualCreatedTags);
}
@Test
public void testDeleteTagById()
{
//when
objectUnderTest.deleteTagById(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID);
then(authorityServiceMock).should().hasAdminAuthority();
then(authorityServiceMock).shouldHaveNoMoreInteractions();
then(nodesMock).should().validateNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID);
then(nodesMock).shouldHaveNoMoreInteractions();
then(taggingServiceMock).should().getTagName(TAG_NODE_REF);
then(taggingServiceMock).should().deleteTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_NAME);
then(taggingServiceMock).shouldHaveNoMoreInteractions();
}
@Test
public void testDeleteTagById_asNonAdminUser()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(false);
//when
assertThrows(PermissionDeniedException.class, () -> objectUnderTest.deleteTagById(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID));
then(authorityServiceMock).should().hasAdminAuthority();
then(authorityServiceMock).shouldHaveNoMoreInteractions();
then(nodesMock).shouldHaveNoInteractions();
then(taggingServiceMock).shouldHaveNoInteractions();
}
@Test
public void testDeleteTagById_nonExistentTag()
{
//when
assertThrows(EntityNotFoundException.class, () -> objectUnderTest.deleteTagById(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "dummy-id"));
then(authorityServiceMock).should().hasAdminAuthority();
then(authorityServiceMock).shouldHaveNoMoreInteractions();
then(nodesMock).should().validateNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "dummy-id");
then(nodesMock).shouldHaveNoMoreInteractions();
then(taggingServiceMock).shouldHaveNoInteractions();
}
@Test
public void testCreateTags()
{
final List<String> tagNames = List.of("tag1", "99gat");
final List<Tag> tagsToCreate = createTags(tagNames);
given(taggingServiceMock.createTags(any(), any())).willAnswer(invocation -> createTagAndNodeRefPairs(invocation.getArgument(1)));
//when
final List<Tag> actualCreatedTags = objectUnderTest.createTags(tagsToCreate, parametersMock);
then(authorityServiceMock).should().hasAdminAuthority();
then(authorityServiceMock).shouldHaveNoMoreInteractions();
then(taggingServiceMock).should().createTags(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, tagNames);
then(taggingServiceMock).shouldHaveNoMoreInteractions();
final List<Tag> expectedTags = createTagsWithNodeRefs(tagNames);
assertThat(actualCreatedTags)
.isNotNull()
.isEqualTo(expectedTags);
}
@Test
public void testCreateTags_withoutPermission()
{
given(authorityServiceMock.hasAdminAuthority()).willReturn(false);
//when
final Throwable actualException = catchThrowable(() -> objectUnderTest.createTags(List.of(createTag(TAG_NAME)), parametersMock));
then(authorityServiceMock).should().hasAdminAuthority();
then(authorityServiceMock).shouldHaveNoMoreInteractions();
then(taggingServiceMock).shouldHaveNoInteractions();
assertThat(actualException)
.isInstanceOf(PermissionDeniedException.class)
.hasMessageContaining(NO_PERMISSION_TO_MANAGE_A_TAG);
}
@Test
public void testCreateTags_passingNullInsteadList()
{
//when
final Throwable actualException = catchThrowable(() -> objectUnderTest.createTags(null, parametersMock));
then(taggingServiceMock).shouldHaveNoInteractions();
assertThat(actualException)
.isInstanceOf(InvalidArgumentException.class)
.hasMessageContaining(NOT_A_VALID_TAG);
}
@Test
public void testCreateTags_passingEmptyList()
{
//when
final Throwable actualException = catchThrowable(() -> objectUnderTest.createTags(Collections.emptyList(), parametersMock));
then(taggingServiceMock).shouldHaveNoInteractions();
assertThat(actualException)
.isInstanceOf(InvalidArgumentException.class)
.hasMessageContaining(NOT_A_VALID_TAG);
}
@Test
public void testCreateTags_passingListOfNulls()
{
//when
final Throwable actualException = catchThrowable(() -> objectUnderTest.createTags(Collections.singletonList(null), parametersMock));
then(taggingServiceMock).shouldHaveNoInteractions();
assertThat(actualException)
.isInstanceOf(InvalidArgumentException.class)
.hasMessageContaining(NOT_A_VALID_TAG);
}
@Test
public void testCreateTags_whileTagAlreadyExists()
{
given(taggingServiceMock.createTags(any(), any())).willThrow(new DuplicateChildNodeNameException(null, null, TAG_NAME, null));
//when
final Throwable actualException = catchThrowable(() -> objectUnderTest.createTags(List.of(createTag(TAG_NAME)), parametersMock));
then(taggingServiceMock).should().createTags(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, List.of(TAG_NAME));
then(taggingServiceMock).shouldHaveNoMoreInteractions();
assertThat(actualException).isInstanceOf(DuplicateChildNodeNameException.class);
}
@Test
public void testCreateTags_withRepeatedTagName()
{
final List<String> tagNames = List.of(TAG_NAME, TAG_NAME);
final List<Tag> tagsToCreate = createTags(tagNames);
given(taggingServiceMock.createTags(any(), any())).willAnswer(invocation -> createTagAndNodeRefPairs(invocation.getArgument(1)));
//when
final List<Tag> actualCreatedTags = objectUnderTest.createTags(tagsToCreate, parametersMock);
then(taggingServiceMock).should().createTags(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, List.of(TAG_NAME));
final List<Tag> expectedTags = List.of(createTagWithNodeRef(TAG_NAME));
assertThat(actualCreatedTags)
.isNotNull()
.isEqualTo(expectedTags);
}
@Test
public void testCreateTags_includingCount()
{
final List<String> tagNames = List.of("tag1", "99gat");
final List<Tag> tagsToCreate = createTags(tagNames);
given(taggingServiceMock.createTags(any(), any())).willAnswer(invocation -> createTagAndNodeRefPairs(invocation.getArgument(1)));
given(parametersMock.getInclude()).willReturn(List.of("count"));
//when
final List<Tag> actualCreatedTags = objectUnderTest.createTags(tagsToCreate, parametersMock);
final List<Tag> expectedTags = createTagsWithNodeRefs(tagNames).stream()
.peek(tag -> tag.setCount(0))
.collect(Collectors.toList());
assertThat(actualCreatedTags)
.isNotNull()
.isEqualTo(expectedTags);
}
private static List<Pair<String, NodeRef>> createTagAndNodeRefPairs(final List<String> tagNames)
{
return tagNames.stream()
.map(tagName -> createPair(tagName, new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID.concat("-").concat(tagName))))
.collect(Collectors.toList());
}
private static Pair<String, NodeRef> createPair(final String tagName, final NodeRef nodeRef)
{
return new Pair<>(tagName, nodeRef);
}
private static List<Tag> createTags(final List<String> tagNames)
{
return tagNames.stream().map(TagsImplTest::createTag).collect(Collectors.toList());
}
private static List<Tag> createTagsWithNodeRefs(final List<String> tagNames)
{
return tagNames.stream().map(TagsImplTest::createTagWithNodeRef).collect(Collectors.toList());
}
private static Tag createTag(final String tagName)
{
return Tag.builder()
.tag(tagName)
.create();
}
private static Tag createTagWithNodeRef(final String tagName)
{
return Tag.builder()
.nodeRef(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID.concat("-").concat(tagName)))
.tag(tagName)
.create();
}
}

View File

@@ -1,78 +0,0 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.tags;
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import java.util.List;
import org.alfresco.rest.api.Tags;
import org.alfresco.rest.api.model.Tag;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.cmr.repository.NodeRef;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TagsEntityResourceTest
{
private static final String TAG_ID = "tag-dummy-id";
private static final String TAG_NAME = "tag-dummy-name";
private static final NodeRef TAG_NODE_REF = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID);
@Mock
private Parameters parametersMock;
@Mock
private Tags tagsMock;
@InjectMocks
private TagsEntityResource tagsEntityResource;
@Test
public void testCreate()
{
final Tag tag = Tag.builder().tag(TAG_NAME).create();
final List<Tag> tags = List.of(tag);
given(tagsMock.createTags(any(), any())).willCallRealMethod();
given(tagsMock.createTags(any(), any(), any())).willReturn(List.of(Tag.builder().nodeRef(TAG_NODE_REF).tag(TAG_NAME).create()));
//when
final List<Tag> actualCreatedTags = tagsEntityResource.create(tags, parametersMock);
then(tagsMock).should().createTags(STORE_REF_WORKSPACE_SPACESSTORE, tags, parametersMock);
final List<Tag> expectedTags = List.of(Tag.builder().nodeRef(TAG_NODE_REF).tag(TAG_NAME).create());
assertThat(actualCreatedTags)
.isNotEmpty()
.isEqualTo(expectedTags);
}
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>20.93</version>
<version>20.79-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -1,28 +1,28 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 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%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 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.repo.download;
import java.io.File;
@@ -31,8 +31,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.attribute.FileTime;
import java.util.Date;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
@@ -87,8 +85,6 @@ public class ZipDownloadExporter extends BaseExporter
private String currentName;
private OutputStream outputStream;
private Date zipTimestampCreated;
private Date zipTimestampModified;
/**
* Construct
@@ -141,8 +137,6 @@ public class ZipDownloadExporter extends BaseExporter
public void startNode(NodeRef nodeRef)
{
this.currentName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
this.zipTimestampCreated = (Date)nodeService.getProperty(nodeRef, ContentModel.PROP_CREATED);
this.zipTimestampModified = (Date)nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED);
path.push(new Pair<String, NodeRef>(currentName, nodeRef));
if (dictionaryService.isSubClass(nodeService.getType(nodeRef), ContentModel.TYPE_FOLDER))
{
@@ -150,9 +144,6 @@ public class ZipDownloadExporter extends BaseExporter
ZipArchiveEntry archiveEntry = new ZipArchiveEntry(path);
try
{
archiveEntry.setTime(zipTimestampCreated.getTime());
archiveEntry.setCreationTime(FileTime.fromMillis(zipTimestampCreated.getTime()));
archiveEntry.setLastModifiedTime(FileTime.fromMillis(zipTimestampModified.getTime()));
zipStream.putArchiveEntry(archiveEntry);
zipStream.closeArchiveEntry();
}
@@ -176,9 +167,6 @@ public class ZipDownloadExporter extends BaseExporter
{
// ALF-2016
ZipArchiveEntry zipEntry=new ZipArchiveEntry(getPath());
zipEntry.setTime(zipTimestampCreated.getTime());
zipEntry.setCreationTime(FileTime.fromMillis(zipTimestampCreated.getTime()));
zipEntry.setLastModifiedTime(FileTime.fromMillis(zipTimestampModified.getTime()));
zipStream.putArchiveEntry(zipEntry);
// copy export stream to zip

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* Copyright (C) 2005 - 2020 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.repo.tagging;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
@@ -40,10 +41,9 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.query.EmptyPagingResults;
import org.alfresco.query.PagingRequest;
@@ -64,13 +64,11 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.TransactionListener;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
@@ -1577,27 +1575,4 @@ public class TaggingServiceImpl implements TaggingService,
}
}
@Experimental
@Override
public List<Pair<String, NodeRef>> createTags(final StoreRef storeRef, final List<String> tagNames)
{
updateTagBehaviour.disable();
createTagBehaviour.disable();
try
{
return tagNames.stream()
.map(String::toLowerCase)
.peek(tagName -> categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, tagName, false).stream()
.filter(association -> Objects.nonNull(association.getChildRef()))
.findAny()
.ifPresent(association -> { throw new DuplicateChildNodeNameException(association.getParentRef(), association.getTypeQName(), tagName, null); }))
.map(tagName -> new Pair<>(tagName, getTagNodeRef(storeRef, tagName, true)))
.collect(Collectors.toList());
}
finally
{
updateTagBehaviour.enable();
createTagBehaviour.enable();
}
}
}

View File

@@ -0,0 +1,140 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 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.repo.urlshortening;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.service.cmr.urlshortening.UrlShortener;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @deprecated as it is no longer used in the core repository code.
*/
@Deprecated
public class BitlyUrlShortenerImpl implements UrlShortener
{
private static final Log log = LogFactory.getLog(BitlyUrlShortenerImpl.class);
private int urlLength = 20;
private String username;
private String apiKey = "R_ca15c6c89e9b25ccd170bafd209a0d4f";
private HttpClient httpClient;
public BitlyUrlShortenerImpl()
{
httpClient = new HttpClient();
httpClient.setHttpConnectionManager(new MultiThreadedHttpConnectionManager());
HostConfiguration hostConfiguration = new HostConfiguration();
hostConfiguration.setHost("api-ssl.bitly.com", 443, Protocol.getProtocol("https"));
httpClient.setHostConfiguration(hostConfiguration);
}
@Override
public String shortenUrl(String longUrl)
{
if (log.isDebugEnabled())
{
log.debug("Shortening URL: " + longUrl);
}
String shortUrl = longUrl;
if (longUrl.length() > urlLength)
{
GetMethod getMethod = new GetMethod();
getMethod.setPath("/v3/shorten");
List<NameValuePair> args = new ArrayList<NameValuePair>();
args.add(new NameValuePair("login", username));
args.add(new NameValuePair("apiKey", apiKey));
args.add(new NameValuePair("longUrl", longUrl));
args.add(new NameValuePair("format", "txt"));
getMethod.setQueryString(args.toArray(new NameValuePair[args.size()]));
try
{
int resultCode = httpClient.executeMethod(getMethod);
if (resultCode == 200)
{
shortUrl = getMethod.getResponseBodyAsString();
}
else
{
log.warn("Failed to shorten URL " + longUrl + " - response code == " + resultCode);
log.warn(getMethod.getResponseBodyAsString());
}
}
catch (Exception ex)
{
log.error("Failed to shorten URL " + longUrl, ex);
}
if (log.isDebugEnabled())
{
log.debug("URL " + longUrl + " has been shortened to " + shortUrl);
}
}
return shortUrl.trim();
}
/**
* {@inheritDoc}
*/
@Override
public int getUrlLength()
{
return urlLength;
}
/**
* @param urlLength the urlLength to set
*/
public void setUrlLength(int urlLength)
{
this.urlLength = urlLength;
}
/**
* @param username the username to set
*/
public void setUsername(String username)
{
this.username = username;
}
/**
* @param apiKey the apiKey to set
*/
public void setApiKey(String apiKey)
{
this.apiKey = apiKey;
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of

View File

@@ -1,38 +1,36 @@
/*
* #%L
* Alfresco Repository
* %%
* 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 <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 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.service.cmr.tagging;
import java.util.Collections;
import java.util.List;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.service.Auditable;
import org.alfresco.service.Experimental;
import org.alfresco.service.NotAuditable;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
@@ -308,31 +306,17 @@ public interface TaggingService
*/
@NotAuditable
Pair<List<String>, Integer> getPagedTags(StoreRef storeRef, String filter, int fromTag, int pageSize);
/**
* Get tagged nodes and count of nodes group by tag name
*
* @param storeRef
* @return
*/
@NotAuditable
List<Pair<String, Integer>> findTaggedNodesAndCountByTagName(StoreRef storeRef);
/**
* Creates orphan tags. Tag names case will be lowered.
*
* @param storeRef Reference to node store.
* @param tagNames List of tag names.
* @return {@link List} of {@link Pair}s of tag names and node references.
* @throws org.alfresco.service.cmr.repository.DuplicateChildNodeNameException if tag already exists.
*/
@Experimental
@Auditable(parameters = {"tagNames"})
default List<Pair<String, NodeRef>> createTags(StoreRef storeRef, List<String> tagNames)
{
return Collections.emptyList();
}
/**
* Get tagged nodes and count of nodes group by tag name
*
* @param storeRef
* @return
*/
@NotAuditable
List<Pair<String, Integer>> findTaggedNodesAndCountByTagName(StoreRef storeRef);
}

View File

@@ -813,6 +813,13 @@ solr6.store.mappings.value.solrMappingHistory.baseUrl=/solr/history
solr6.store.mappings.value.solrMappingHistory.protocol=workspace
solr6.store.mappings.value.solrMappingHistory.identifier=history
#
# URL Shortening Properties
#
urlshortening.bitly.username=brianalfresco
urlshortening.bitly.api.key=R_ca15c6c89e9b25ccd170bafd209a0d4f
urlshortening.bitly.url.length=20
#
# Bulk Filesystem Importer
#

View File

@@ -84,6 +84,7 @@ import org.junit.runners.Suite;
org.alfresco.repo.transfer.HttpClientTransmitterImplTest.class,
org.alfresco.repo.transfer.manifest.TransferManifestTest.class,
org.alfresco.repo.transfer.TransferVersionCheckerImplTest.class,
org.alfresco.repo.urlshortening.BitlyUrlShortenerTest.class,
org.alfresco.service.cmr.calendar.CalendarRecurrenceHelperTest.class,
org.alfresco.service.cmr.calendar.CalendarTimezoneHelperTest.class,
org.alfresco.tools.RenameUserTest.class,
@@ -243,8 +244,7 @@ import org.junit.runners.Suite;
org.alfresco.repo.event2.RepoEvent2UnitSuite.class,
org.alfresco.util.schemacomp.SchemaDifferenceHelperUnitTest.class,
org.alfresco.repo.tagging.TaggingServiceImplUnitTest.class
org.alfresco.util.schemacomp.SchemaDifferenceHelperUnitTest.class
})
public class AllUnitTestsSuite
{

View File

@@ -1,106 +0,0 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.tagging;
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.catchThrowable;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.mock;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.CategoryService;
import org.alfresco.util.Pair;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TaggingServiceImplUnitTest
{
private static final String TAG_ID = "tag-node-id";
private static final String TAG_NAME = "tag-dummy-name";
private static final NodeRef TAG_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID);
@Mock
private CategoryService categoryServiceMock;
@Mock
private PolicyComponent policyComponentMock;
@InjectMocks
private TaggingServiceImpl taggingService;
@Before
public void setUp() throws Exception
{
taggingService.init();
}
@Test
public void testCreateTags()
{
final ChildAssociationRef tagAssociationMock = mock(ChildAssociationRef.class);
given(categoryServiceMock.getRootCategories(any(), any(), any(String.class), eq(true))).willReturn(List.of(tagAssociationMock));
given(tagAssociationMock.getChildRef()).willReturn(TAG_NODE_REF);
//when
final List<Pair<String, NodeRef>> actualTagPairs = taggingService.createTags(STORE_REF_WORKSPACE_SPACESSTORE, List.of(TAG_NAME));
then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ContentModel.ASPECT_TAGGABLE, TAG_NAME, false);
then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ContentModel.ASPECT_TAGGABLE, TAG_NAME, true);
then(categoryServiceMock).shouldHaveNoMoreInteractions();
List<Pair<String, NodeRef>> expectedTagPairs = List.of(new Pair<>(TAG_NAME, TAG_NODE_REF));
assertThat(actualTagPairs)
.isNotNull()
.isEqualTo(expectedTagPairs);
}
@Test
public void testCreateTags_whileTagAlreadyExists()
{
given(categoryServiceMock.getRootCategories(any(), any(), any(String.class), eq(false))).willThrow(new DuplicateChildNodeNameException(null, null, null, null));
//when
final Throwable actualException = catchThrowable(() -> taggingService.createTags(STORE_REF_WORKSPACE_SPACESSTORE, List.of(TAG_NAME)));
then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ContentModel.ASPECT_TAGGABLE, TAG_NAME, false);
then(categoryServiceMock).shouldHaveNoMoreInteractions();
assertThat(actualException).isInstanceOf(DuplicateChildNodeNameException.class);
}
}

View File

@@ -0,0 +1,59 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 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.repo.urlshortening;
import junit.framework.TestCase;
/**
* @deprecated as BitlyUrlShortenerImpl is no longer used in the core repository code.
*/
@Deprecated
public class BitlyUrlShortenerTest extends TestCase
{
private BitlyUrlShortenerImpl shortener;
public void testShorten()
{
String url = "http://www.alfresco.com/";
String shortUrl = shortener.shortenUrl(url);
assertNotNull(shortUrl);
assertFalse(shortUrl.isEmpty());
assertFalse(url.equals(shortUrl));
assertTrue(shortUrl.length() < url.length());
}
/**
* {@inheritDoc}
*/
@Override
protected void setUp() throws Exception
{
this.shortener = new BitlyUrlShortenerImpl();;
shortener.setApiKey("R_ca15c6c89e9b25ccd170bafd209a0d4f");
shortener.setUrlLength(20);
shortener.setUsername("brianalfresco");
}
}