mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-29 15:21:53 +00:00
Compare commits
4 Commits
20.155
...
ACS-3916_G
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06004e207d | ||
|
|
a7c35ae391 | ||
|
|
324e2f619d | ||
|
|
5d269e05ab |
18
.github/dependabot.yml
vendored
18
.github/dependabot.yml
vendored
@@ -53,6 +53,24 @@ updates:
|
||||
- dependency-name: org.freemarker:freemarker
|
||||
versions:
|
||||
- "> 2.3.20-alfresco-patched-20200421"
|
||||
- dependency-name: org.keycloak:keycloak-adapter-core
|
||||
versions:
|
||||
- "> 12.0.2"
|
||||
- dependency-name: org.keycloak:keycloak-adapter-spi
|
||||
versions:
|
||||
- "> 12.0.2"
|
||||
- dependency-name: org.keycloak:keycloak-authz-client
|
||||
versions:
|
||||
- "> 12.0.2"
|
||||
- dependency-name: org.keycloak:keycloak-common
|
||||
versions:
|
||||
- "> 12.0.2"
|
||||
- dependency-name: org.keycloak:keycloak-core
|
||||
versions:
|
||||
- "> 12.0.2"
|
||||
- dependency-name: org.keycloak:keycloak-servlet-adapter-spi
|
||||
versions:
|
||||
- "> 12.0.2"
|
||||
- dependency-name: org.eclipse.jetty:jetty-server
|
||||
versions:
|
||||
- 9.4.38.v20210224
|
||||
|
||||
17
.github/workflows/ci.yml
vendored
17
.github/workflows/ci.yml
vendored
@@ -23,7 +23,6 @@ env:
|
||||
MAVEN_USERNAME: ${{ secrets.NEXUS_USERNAME }}
|
||||
QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }}
|
||||
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
|
||||
CI_WORKSPACE: ${{ github.workspace }}
|
||||
TAS_ENVIRONMENT: ./packaging/tests/environment
|
||||
TAS_SCRIPTS: ../alfresco-community-repo/packaging/tests/scripts
|
||||
|
||||
@@ -314,11 +313,6 @@ jobs:
|
||||
- testSuite: SearchTestSuite
|
||||
compose-profile: default
|
||||
mvn-options: '-Dindex.subsystem.name=solr6'
|
||||
- testSuite: MTLSTestSuite
|
||||
compose-profile: with-mtls-transform-core-aio
|
||||
mtls: true
|
||||
disabledHostnameVerification: false
|
||||
mvn-options: '-Dencryption.ssl.keystore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.keystore -Dencryption.ssl.truststore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.truststore'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v1.33.0
|
||||
@@ -327,17 +321,6 @@ jobs:
|
||||
run: bash ./scripts/ci/init.sh
|
||||
- name: "Set transformers tag"
|
||||
run: echo "TRANSFORMERS_TAG=$(mvn help:evaluate -Dexpression=dependency.alfresco-transform-core.version -q -DforceStdout)" >> $GITHUB_ENV
|
||||
- name: "Generate Keystores and Truststores for Mutual TLS configuration"
|
||||
if: ${{ matrix.mtls }}
|
||||
run: |
|
||||
git clone -b "master" --depth=1 "https://${{ secrets.BOT_GITHUB_USERNAME }}:${{ secrets.BOT_GITHUB_TOKEN }}@github.com/Alfresco/alfresco-ssl-generator.git"
|
||||
if ${{ matrix.disabledHostnameVerification }} ; then
|
||||
bash ${{ env.CI_WORKSPACE }}/alfresco-ssl-generator/scripts/ci/generate_keystores_wrong_hostnames.sh
|
||||
echo "HOSTNAME_VERIFICATION_DISABLED=true" >> "$GITHUB_ENV"
|
||||
else
|
||||
bash ${{ env.CI_WORKSPACE }}/alfresco-ssl-generator/scripts/ci/generate_keystores.sh
|
||||
echo "HOSTNAME_VERIFICATION_DISABLED=false" >> "$GITHUB_ENV"
|
||||
fi
|
||||
- name: "Set up the environment"
|
||||
run: |
|
||||
if [ -e ./scripts/ci/tests/${{ matrix.testSuite }}-setup.sh ]; then
|
||||
|
||||
10
.github/workflows/master_release.yml
vendored
10
.github/workflows/master_release.yml
vendored
@@ -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
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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, () ->
|
||||
{
|
||||
|
||||
@@ -50,7 +50,6 @@ import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Ignore;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.testng.AssertJUnit;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
@@ -67,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;
|
||||
@@ -84,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();
|
||||
@@ -136,195 +133,192 @@ public class DispositionScheduleLinkedRecordsTest extends BaseRMRestTest {
|
||||
* <p>
|
||||
* <p/> TestRail Test C775<p/>
|
||||
**/
|
||||
// @Ignore("ACS-5020")
|
||||
// @Test
|
||||
// @AlfrescoTest(jira = "RM-1622")
|
||||
// public void dispositionScheduleLinkedRecords() throws UnsupportedEncodingException {
|
||||
// STEP("Create record category");
|
||||
// Category1 = createRootCategory(categoryRM3077);
|
||||
//
|
||||
// //create retention schedule
|
||||
// dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), false);
|
||||
//
|
||||
// // add cut off step
|
||||
// dispositionScheduleService.addCutOffAfterPeriodStep(Category1.getName(), "day|2", CREATED_DATE);
|
||||
//
|
||||
// //create a copy of the category recordsCategory
|
||||
// String CopyCategoryId = copyCategory(getAdminUser(),Category1.getId(), copyCategoryRM3077);
|
||||
//
|
||||
// // create folders in both categories
|
||||
// CatFolder = createRecordFolder(Category1.getId(), folderRM3077);
|
||||
// CopyCatFolder = createRecordFolder(CopyCategoryId, copyFolderRM3077);
|
||||
//
|
||||
// // create record files
|
||||
// String electronicRecord = "RM-2801 electronic record";
|
||||
// Record elRecord = createElectronicRecord(CatFolder.getId(), electronicRecord);
|
||||
// String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), electronicRecord);
|
||||
//
|
||||
// String nonElectronicRecord = "RM-2801 non-electronic record";
|
||||
// Record nonElRecord = createNonElectronicRecord(CatFolder.getId(), nonElectronicRecord);
|
||||
// String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), nonElectronicRecord);
|
||||
//
|
||||
// // link the records to copy folder, then complete them
|
||||
// List<String> recordLists = new ArrayList<>();
|
||||
// recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + elRecord.getId());
|
||||
// recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + nonElRecord.getId());
|
||||
//
|
||||
// linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,copyCategoryRM3077 + "/" +
|
||||
// copyFolderRM3077, recordLists);
|
||||
// recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), elRecordFullName);
|
||||
// recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), nonElRecordFullName);
|
||||
//
|
||||
// // edit disposition date
|
||||
// recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),CatFolder.getName());
|
||||
//
|
||||
// // cut off the Folder
|
||||
// recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),CatFolder.getName());
|
||||
//
|
||||
// // Verify the Content
|
||||
// Node electronicNode = getNode(elRecord.getId());
|
||||
// assertTrue("The content of " + electronicRecord + " is available",
|
||||
// StringUtils.isEmpty(electronicNode.getNodeContent().getResponse().getBody().asString()));
|
||||
//
|
||||
// // verify the Properties
|
||||
// AssertJUnit.assertNull("The properties are present even after cutting off the record.", elRecord.getProperties().getTitle());
|
||||
//
|
||||
// // delete precondition
|
||||
// deleteRecordCategory(Category1.getId());
|
||||
// deleteRecordCategory(CopyCategoryId);
|
||||
// }
|
||||
// /**
|
||||
// * Test covering RM-3060
|
||||
// * Check the disposition steps for a record can be executed
|
||||
// * When the record is linked to a folder with the same disposition schedule
|
||||
// * */
|
||||
// @Ignore("ACS-5020")
|
||||
//// @Test
|
||||
// @AlfrescoTest (jira = "RM-3060")
|
||||
// public void sameDispositionScheduleLinkedRecords() throws UnsupportedEncodingException {
|
||||
//
|
||||
// // create a category with retention applied on records level
|
||||
// RecordCategory recordCategory = getRestAPIFactory().getFilePlansAPI(rmAdmin)
|
||||
// .createRootRecordCategory(RecordCategory.builder().name(firstCategoryRM3060).build(),
|
||||
// RecordCategory.DEFAULT_FILE_PLAN_ALIAS);
|
||||
// dispositionScheduleService.createCategoryRetentionSchedule(firstCategoryRM3060, true);
|
||||
// dispositionScheduleService.addCutOffAfterPeriodStep(firstCategoryRM3060, "week|1", DATE_FILED);
|
||||
// dispositionScheduleService.addTransferAfterEventStep(firstCategoryRM3060, TRANSFER_LOCATION, RMEvents.CASE_CLOSED.getEventName());
|
||||
// dispositionScheduleService.addDestroyWithoutGhostingAfterPeriodStep(firstCategoryRM3060, "week|1", CUT_OFF_DATE);
|
||||
//
|
||||
// // make a copy of the category created
|
||||
// String categorySecondId = copyCategory(getAdminUser(), recordCategory.getId(), secondCategoryRM3060);
|
||||
//
|
||||
// // create a folder on the category firstCategoryRM3060 with a complete electronic record
|
||||
// RecordCategoryChild firstFolderRecordCategoryChild = createRecordFolder(recordCategory.getId(),firstFolderRM3060);
|
||||
// Record firstElectronicRecord = createElectronicRecord(firstFolderRecordCategoryChild.getId(),electronicRecordRM3060);
|
||||
//
|
||||
// String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(),firstFolderRM3060, electronicRecordRM3060);
|
||||
// String elRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060);
|
||||
//
|
||||
// recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), elRecordFullName);
|
||||
//
|
||||
// // create a folder on the category secondCategoryRM3060 with a non electronic record
|
||||
// RecordCategoryChild secondFolderRecordCategoryChild = createRecordFolder(categorySecondId,secondFolderRM3060);
|
||||
// Record secondNonElectronicRecord = createNonElectronicRecord(secondFolderRecordCategoryChild.getId(),nonElectronicRecordRM3060);
|
||||
//
|
||||
// // link the nonElectronicRecordRM3060 to firstFolderRM3060
|
||||
// List<String> recordLists = new ArrayList<>();
|
||||
// recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId());
|
||||
//
|
||||
// linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" +
|
||||
// secondFolderRM3060, recordLists);
|
||||
// String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), secondFolderRM3060, secondNonElectronicRecord.getName());
|
||||
// String nonElRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060);
|
||||
//
|
||||
// // complete records and cut them off
|
||||
// recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), nonElRecordFullName);
|
||||
//
|
||||
// // edit the disposition date
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
|
||||
//
|
||||
// // cut off the record
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),nonElRecordNameNodeRef);
|
||||
//
|
||||
// //check the record is cut off
|
||||
// AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT));
|
||||
//
|
||||
// // link the electronic record to secondFolderRM3060
|
||||
// recordLists.clear();
|
||||
// recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId());
|
||||
// linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" +
|
||||
// secondFolderRM3060, recordLists);
|
||||
//
|
||||
// // edit the disposition date and cut off the record
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),elRecordNameNodeRef);
|
||||
//
|
||||
// AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT));
|
||||
//
|
||||
// // open the record and complete the disposition schedule event
|
||||
// rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(), elRecordFullName, RMEvents.CASE_CLOSED, Instant.now());
|
||||
// rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(), nonElRecordFullName, RMEvents.CASE_CLOSED, Instant.now());
|
||||
//
|
||||
// // transfer the files & complete transfers
|
||||
// HttpResponse nonElRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060));
|
||||
//
|
||||
// String nonElRecordNameTransferId = getTransferId(nonElRecordNameHttpResponse,nonElRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),nonElRecordNameTransferId);
|
||||
//
|
||||
// HttpResponse elRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060));
|
||||
//
|
||||
// String elRecordNameTransferId = getTransferId(elRecordNameHttpResponse,elRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),elRecordNameTransferId);
|
||||
//
|
||||
// AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully transferred", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE));
|
||||
// AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully transferred.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE));
|
||||
//
|
||||
// // edit the disposition date for nonElectronicRecordRM3060 & electronicRecordRM3060
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
|
||||
//
|
||||
// // destroy nonElectronicRecordRM3060 & electronicRecordRM3060 records
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","destroy"),nonElRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","destroy"),elRecordNameNodeRef);
|
||||
//
|
||||
// // check the file is not displayed
|
||||
// assertNull("The file " + nonElectronicRecordRM3060 + " has not been successfully destroyed.", secondNonElectronicRecord.getContent());
|
||||
// assertNull("The file " + electronicRecordRM3060 + " has not been successfully destroyed.", firstElectronicRecord.getContent());
|
||||
//
|
||||
// // delete precondition
|
||||
// deleteRecordCategory(recordCategory.getId());
|
||||
// deleteRecordCategory(categorySecondId);
|
||||
// }
|
||||
@Test
|
||||
@AlfrescoTest(jira = "RM-1622")
|
||||
public void dispositionScheduleLinkedRecords() throws UnsupportedEncodingException {
|
||||
STEP("Create record category");
|
||||
Category1 = createRootCategory(categoryRM3077);
|
||||
|
||||
//create retention schedule
|
||||
dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), false);
|
||||
|
||||
// add cut off step
|
||||
dispositionScheduleService.addCutOffAfterPeriodStep(Category1.getName(), "day|2", CREATED_DATE);
|
||||
|
||||
//create a copy of the category recordsCategory
|
||||
String CopyCategoryId = copyCategory(getAdminUser(),Category1.getId(), copyCategoryRM3077);
|
||||
|
||||
// create folders in both categories
|
||||
CatFolder = createRecordFolder(Category1.getId(), folderRM3077);
|
||||
CopyCatFolder = createRecordFolder(CopyCategoryId, copyFolderRM3077);
|
||||
|
||||
// create record files
|
||||
String electronicRecord = "RM-2801 electronic record";
|
||||
Record elRecord = createElectronicRecord(CatFolder.getId(), electronicRecord);
|
||||
String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), electronicRecord);
|
||||
|
||||
String nonElectronicRecord = "RM-2801 non-electronic record";
|
||||
Record nonElRecord = createNonElectronicRecord(CatFolder.getId(), nonElectronicRecord);
|
||||
String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), nonElectronicRecord);
|
||||
|
||||
// link the records to copy folder, then complete them
|
||||
List<String> recordLists = new ArrayList<>();
|
||||
recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + elRecord.getId());
|
||||
recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + nonElRecord.getId());
|
||||
|
||||
linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,copyCategoryRM3077 + "/" +
|
||||
copyFolderRM3077, recordLists);
|
||||
recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), elRecordFullName);
|
||||
recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), nonElRecordFullName);
|
||||
|
||||
// edit disposition date
|
||||
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),CatFolder.getName());
|
||||
|
||||
// cut off the Folder
|
||||
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),CatFolder.getName());
|
||||
|
||||
// Verify the Content
|
||||
Node electronicNode = getNode(elRecord.getId());
|
||||
assertTrue("The content of " + electronicRecord + " is available",
|
||||
StringUtils.isEmpty(electronicNode.getNodeContent().getResponse().getBody().asString()));
|
||||
|
||||
// verify the Properties
|
||||
AssertJUnit.assertNull("The properties are present even after cutting off the record.", elRecord.getProperties().getTitle());
|
||||
|
||||
// delete precondition
|
||||
deleteRecordCategory(Category1.getId());
|
||||
deleteRecordCategory(CopyCategoryId);
|
||||
}
|
||||
/**
|
||||
* Test covering RM-3060
|
||||
* Check the disposition steps for a record can be executed
|
||||
* When the record is linked to a folder with the same disposition schedule
|
||||
* */
|
||||
@Test
|
||||
@AlfrescoTest (jira = "RM-3060")
|
||||
public void sameDispositionScheduleLinkedRecords() throws UnsupportedEncodingException {
|
||||
|
||||
// create a category with retention applied on records level
|
||||
RecordCategory recordCategory = getRestAPIFactory().getFilePlansAPI(rmAdmin)
|
||||
.createRootRecordCategory(RecordCategory.builder().name(firstCategoryRM3060).build(),
|
||||
RecordCategory.DEFAULT_FILE_PLAN_ALIAS);
|
||||
dispositionScheduleService.createCategoryRetentionSchedule(firstCategoryRM3060, true);
|
||||
dispositionScheduleService.addCutOffAfterPeriodStep(firstCategoryRM3060, "week|1", DATE_FILED);
|
||||
dispositionScheduleService.addTransferAfterEventStep(firstCategoryRM3060, TRANSFER_LOCATION, RMEvents.CASE_CLOSED.getEventName());
|
||||
dispositionScheduleService.addDestroyWithoutGhostingAfterPeriodStep(firstCategoryRM3060, "week|1", CUT_OFF_DATE);
|
||||
|
||||
// make a copy of the category created
|
||||
String categorySecondId = copyCategory(getAdminUser(), recordCategory.getId(), secondCategoryRM3060);
|
||||
|
||||
// create a folder on the category firstCategoryRM3060 with a complete electronic record
|
||||
RecordCategoryChild firstFolderRecordCategoryChild = createRecordFolder(recordCategory.getId(),firstFolderRM3060);
|
||||
Record firstElectronicRecord = createElectronicRecord(firstFolderRecordCategoryChild.getId(),electronicRecordRM3060);
|
||||
|
||||
String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(),firstFolderRM3060, electronicRecordRM3060);
|
||||
String elRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060);
|
||||
|
||||
recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), elRecordFullName);
|
||||
|
||||
// create a folder on the category secondCategoryRM3060 with a non electronic record
|
||||
RecordCategoryChild secondFolderRecordCategoryChild = createRecordFolder(categorySecondId,secondFolderRM3060);
|
||||
Record secondNonElectronicRecord = createNonElectronicRecord(secondFolderRecordCategoryChild.getId(),nonElectronicRecordRM3060);
|
||||
|
||||
// link the nonElectronicRecordRM3060 to firstFolderRM3060
|
||||
List<String> recordLists = new ArrayList<>();
|
||||
recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId());
|
||||
|
||||
linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" +
|
||||
secondFolderRM3060, recordLists);
|
||||
String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), secondFolderRM3060, secondNonElectronicRecord.getName());
|
||||
String nonElRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060);
|
||||
|
||||
// complete records and cut them off
|
||||
recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), nonElRecordFullName);
|
||||
|
||||
// edit the disposition date
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
|
||||
|
||||
// cut off the record
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),nonElRecordNameNodeRef);
|
||||
|
||||
//check the record is cut off
|
||||
AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT));
|
||||
|
||||
// link the electronic record to secondFolderRM3060
|
||||
recordLists.clear();
|
||||
recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId());
|
||||
linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" +
|
||||
secondFolderRM3060, recordLists);
|
||||
|
||||
// edit the disposition date and cut off the record
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),elRecordNameNodeRef);
|
||||
|
||||
AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT));
|
||||
|
||||
// open the record and complete the disposition schedule event
|
||||
rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(), elRecordFullName, RMEvents.CASE_CLOSED, Instant.now());
|
||||
rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(), nonElRecordFullName, RMEvents.CASE_CLOSED, Instant.now());
|
||||
|
||||
// transfer the files & complete transfers
|
||||
HttpResponse nonElRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060));
|
||||
|
||||
String nonElRecordNameTransferId = getTransferId(nonElRecordNameHttpResponse,nonElRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),nonElRecordNameTransferId);
|
||||
|
||||
HttpResponse elRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060));
|
||||
|
||||
String elRecordNameTransferId = getTransferId(elRecordNameHttpResponse,elRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),elRecordNameTransferId);
|
||||
|
||||
AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully transferred", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE));
|
||||
AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully transferred.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE));
|
||||
|
||||
// edit the disposition date for nonElectronicRecordRM3060 & electronicRecordRM3060
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
|
||||
|
||||
// destroy nonElectronicRecordRM3060 & electronicRecordRM3060 records
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),nonElRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),elRecordNameNodeRef);
|
||||
|
||||
// check the file is not displayed
|
||||
assertNull("The file " + nonElectronicRecordRM3060 + " has not been successfully destroyed.", secondNonElectronicRecord.getContent());
|
||||
assertNull("The file " + electronicRecordRM3060 + " has not been successfully destroyed.", firstElectronicRecord.getContent());
|
||||
|
||||
// delete precondition
|
||||
deleteRecordCategory(recordCategory.getId());
|
||||
deleteRecordCategory(categorySecondId);
|
||||
}
|
||||
private String copyCategory(UserModel user, String categoryId, String copyName) {
|
||||
RepoTestModel repoTestModel = new RepoTestModel() {};
|
||||
repoTestModel.setNodeRef(categoryId);
|
||||
@@ -374,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
|
||||
@@ -410,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(),
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
SOLR6_TAG=2.0.7-A5
|
||||
SOLR6_TAG=2.0.7-A2
|
||||
POSTGRES_TAG=14.4
|
||||
ACTIVEMQ_TAG=5.17.1-jre11-rockylinux8
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
ARG BASE_IMAGE
|
||||
# BUILD STAGE AGS
|
||||
FROM debian:11-slim AS AGSBUILDER
|
||||
|
||||
@@ -13,7 +12,7 @@ RUN unzip -q /build/gs-api-explorer-*.war -d /build/gs-api-explorer && \
|
||||
chmod -R g-w,o= /build
|
||||
|
||||
# ACTUAL IMAGE
|
||||
FROM ${BASE_IMAGE}
|
||||
FROM alfresco/alfresco-community-repo-base:${image.tag}
|
||||
|
||||
# Alfresco user does not have permissions to modify webapps or configuration. Switch to root.
|
||||
# The access will be fixed after all operations are done.
|
||||
|
||||
@@ -8,15 +8,13 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<app.amp.client.war.folder>${project.build.directory}/${project.build.finalName}-war</app.amp.client.war.folder>
|
||||
|
||||
<image.name>alfresco/alfresco-governance-repository-community-base</image.name>
|
||||
<base.image>alfresco/alfresco-community-repo-base</base.image>
|
||||
<scripts.directory>${project.parent.parent.parent.parent.basedir}/scripts</scripts.directory>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -539,43 +537,9 @@
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>build-docker-images</id>
|
||||
<!-- builds "image:latest" locally -->
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<images>
|
||||
<image>
|
||||
<name>${image.name}:${image.tag}</name>
|
||||
<build>
|
||||
<args>
|
||||
<BASE_IMAGE>${base.image}:${image.tag}</BASE_IMAGE>
|
||||
</args>
|
||||
<contextDir>${project.basedir}</contextDir>
|
||||
</build>
|
||||
</image>
|
||||
</images>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>build-image</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>build-multiarch-docker-images</id>
|
||||
<id>build-docker-images</id>
|
||||
<!-- builds "image:latest" locally -->
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -584,56 +548,20 @@
|
||||
<configuration>
|
||||
<images>
|
||||
<image>
|
||||
<name>${local.registry}/${image.name}:${image.tag}</name>
|
||||
<build>
|
||||
<buildx>
|
||||
<platforms>
|
||||
<platform>linux/amd64</platform>
|
||||
<platform>linux/arm64</platform>
|
||||
</platforms>
|
||||
<builderName>${builder.name}</builderName>
|
||||
</buildx>
|
||||
<contextDir>${project.basedir}</contextDir>
|
||||
<args>
|
||||
<BASE_IMAGE>${local.registry}/${base.image}:${image.tag}</BASE_IMAGE>
|
||||
</args>
|
||||
</build>
|
||||
<name>${image.name}:${image.tag}</name>
|
||||
</image>
|
||||
</images>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>build-push-image</id>
|
||||
<id>build-image</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
<goal>push</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare-buildx</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>${scripts.directory}/prepare_buildx.sh</executable>
|
||||
<arguments>
|
||||
<argument>${builder.name}</argument>
|
||||
<argument>${image.registry}</argument>
|
||||
<argument>${image.name}</argument>
|
||||
<argument>${image.tag}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
@@ -650,37 +578,12 @@
|
||||
<images>
|
||||
<image>
|
||||
<!-- Quay image -->
|
||||
<name>${image.registry}/${image.name}:${image.tag}</name>
|
||||
<build>
|
||||
<buildx>
|
||||
<platforms>
|
||||
<platform>linux/amd64</platform>
|
||||
<platform>linux/arm64</platform>
|
||||
</platforms>
|
||||
<builderName>${builder.name}</builderName>
|
||||
</buildx>
|
||||
<args>
|
||||
<BASE_IMAGE>${local.registry}/${base.image}:${image.tag}</BASE_IMAGE>
|
||||
</args>
|
||||
<contextDir>${project.basedir}</contextDir>
|
||||
</build>
|
||||
<name>${image.name}:${image.tag}</name>
|
||||
<registry>${image.registry}</registry>
|
||||
</image>
|
||||
<image>
|
||||
<!-- DockerHub image -->
|
||||
<name>${image.name}:${image.tag}</name>
|
||||
<build>
|
||||
<buildx>
|
||||
<platforms>
|
||||
<platform>linux/amd64</platform>
|
||||
<platform>linux/arm64</platform>
|
||||
</platforms>
|
||||
<builderName>${builder.name}</builderName>
|
||||
</buildx>
|
||||
<args>
|
||||
<BASE_IMAGE>${local.registry}/${base.image}:${image.tag}</BASE_IMAGE>
|
||||
</args>
|
||||
<contextDir>${project.basedir}</contextDir>
|
||||
</build>
|
||||
</image>
|
||||
</images>
|
||||
</configuration>
|
||||
@@ -695,28 +598,6 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare-buildx</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>${scripts.directory}/prepare_buildx.sh</executable>
|
||||
<arguments>
|
||||
<argument>${builder.name}</argument>
|
||||
<argument>${image.registry}</argument>
|
||||
<argument>${image.name}</argument>
|
||||
<argument>${image.tag}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -38,7 +38,9 @@ tags:
|
||||
description: Retrieve and manage unfiled records containers
|
||||
- name: unfiled-record-folders
|
||||
description: Retrieve and manage unfiled record folders
|
||||
|
||||
- name: events
|
||||
description: Retrieve and manage retention events
|
||||
|
||||
paths:
|
||||
## GS sites
|
||||
'/gs-sites':
|
||||
@@ -2092,8 +2094,172 @@ paths:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
'/events':
|
||||
get:
|
||||
tags:
|
||||
- events
|
||||
summary: List all available retention events
|
||||
description: |
|
||||
Gets the list of events that can be used by retention steps
|
||||
operationId: getAllEvents
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: '#/parameters/skipCountParam'
|
||||
- $ref: '#/parameters/maxItemsParam'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventPaging'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: value of **maxItems** or **skipCount** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- events
|
||||
summary: Create a new retention event
|
||||
description: |
|
||||
Creates a new event that can be used by retention schedules.
|
||||
operationId: createEvent
|
||||
parameters:
|
||||
- in: body
|
||||
name: eventBodyCreate
|
||||
description: The new event.
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/EventBody'
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
'201':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventEntry'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: **name** or **type** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
'403':
|
||||
description: Current user does not have permission to create event
|
||||
'409':
|
||||
description: Cannot create event. An event with the name **name** already exists
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
|
||||
'/events/{eventId}':
|
||||
get:
|
||||
tags:
|
||||
- events
|
||||
summary: Return event for given eventId
|
||||
description: |
|
||||
Gets information about the retention event with id **eventId**.
|
||||
operationId: getEvent
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: '#/parameters/eventIdParam'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventEntry'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: **eventId** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
'404':
|
||||
description: "**eventId** does not exist"
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
put:
|
||||
tags:
|
||||
- events
|
||||
summary: Update event for given eventId
|
||||
operationId: updateEvent
|
||||
description: |
|
||||
Updates retention event with id **eventId**.
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: '#/parameters/eventIdParam'
|
||||
- in: body
|
||||
name: eventBodyUpdate
|
||||
description: The event information to update.
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/EventBody'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventEntry'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: The update request is invalid or **eventId** is not a valid format or **eventBodyUpdate** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
'403':
|
||||
description: Current user does not have permission to update events
|
||||
'404':
|
||||
description: "**eventId** does not exist"
|
||||
'409':
|
||||
description: Cannot update event. An event with the name **name** already exists
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
|
||||
'/event-types':
|
||||
get:
|
||||
tags:
|
||||
- events
|
||||
summary: List all the retention event types
|
||||
description: |
|
||||
Gets a list of all the retention event types.
|
||||
operationId: getAllEventTypes
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: '#/parameters/skipCountParam'
|
||||
- $ref: '#/parameters/maxItemsParam'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventTypePaging'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: value of **maxItems** or **skipCount** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
parameters:
|
||||
## event
|
||||
eventIdParam:
|
||||
name: eventId
|
||||
in: path
|
||||
description: The identifier of an event.
|
||||
required: true
|
||||
type: string
|
||||
## File plans
|
||||
filePlanEntryIncludeParam:
|
||||
name: include
|
||||
@@ -3761,4 +3927,92 @@ definitions:
|
||||
- SiteConsumer
|
||||
- SiteCollaborator
|
||||
- SiteContributor
|
||||
- SiteManager
|
||||
- SiteManager
|
||||
EventPaging:
|
||||
type: object
|
||||
properties:
|
||||
list:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: '#/definitions/Pagination'
|
||||
entries:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/EventEntry'
|
||||
EventEntry:
|
||||
type: object
|
||||
required:
|
||||
- entry
|
||||
properties:
|
||||
entry:
|
||||
$ref: '#/definitions/Event'
|
||||
Event:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- type
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: this is the id of the event
|
||||
name:
|
||||
type: string
|
||||
description: This is the unique display label of the event
|
||||
type:
|
||||
type: string
|
||||
description: this is event type
|
||||
EventBody:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: This is the unique display label of the event
|
||||
type:
|
||||
type: string
|
||||
description: this is event type
|
||||
default: Simple
|
||||
EventTypePaging:
|
||||
type: object
|
||||
properties:
|
||||
list:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: '#/definitions/Pagination'
|
||||
entries:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/EventTypeEntry'
|
||||
EventTypeEntry:
|
||||
type: object
|
||||
required:
|
||||
- entry
|
||||
properties:
|
||||
entry:
|
||||
$ref: '#/definitions/EventType'
|
||||
EventType:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: this is the event type id
|
||||
name:
|
||||
type: string
|
||||
description: this is event type name
|
||||
isAutomatic:
|
||||
type: boolean
|
||||
description: Whether events of this type need completing manually or can be completed automatically
|
||||
default: true
|
||||
associationName:
|
||||
type: string
|
||||
description: The association used to determine whether automatic events of this type are complete
|
||||
actionOnAssociatedNode:
|
||||
type: string
|
||||
description: If an association name is set for this event type then it is possible to require an action to be completed on the associated node
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -121,6 +121,12 @@
|
||||
<version>${dependency.webscripts.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@@ -137,10 +137,6 @@
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.httpclient;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequestInterceptor;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.client.StandardHttpRequestRetryHandler;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
|
||||
|
||||
public class HttpClient4Factory
|
||||
{
|
||||
protected static final String TLS_PROTOCOL = "TLS";
|
||||
protected static final String HTTPS_PROTOCOL = "https";
|
||||
protected static final String HTTP_TARGET_HOST = "http.target_host";
|
||||
protected static final String TLS_V_1_2 = "TLSv1.2";
|
||||
protected static final String TLS_V_1_3 = "TLSv1.3";
|
||||
|
||||
private static SSLContext createSSLContext(HttpClientConfig config)
|
||||
{
|
||||
KeyManager[] keyManagers = config.getKeyStore().createKeyManagers();
|
||||
TrustManager[] trustManagers = config.getTrustStore().createTrustManagers();
|
||||
|
||||
try
|
||||
{
|
||||
SSLContext sslcontext = SSLContext.getInstance(TLS_PROTOCOL);
|
||||
sslcontext.init(keyManagers, trustManagers, null);
|
||||
return sslcontext;
|
||||
}
|
||||
catch(Throwable e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to create SSL context", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static CloseableHttpClient createHttpClient(HttpClientConfig config)
|
||||
{
|
||||
return createHttpClient(config, null);
|
||||
}
|
||||
|
||||
public static CloseableHttpClient createHttpClient(HttpClientConfig config, HttpClientConnectionManager connectionManager)
|
||||
{
|
||||
HttpClientBuilder clientBuilder = HttpClients.custom();
|
||||
|
||||
if(config.isMTLSEnabled())
|
||||
{
|
||||
clientBuilder.addInterceptorFirst((HttpRequestInterceptor) (request, context) -> {
|
||||
if (!((HttpHost) context.getAttribute(HTTP_TARGET_HOST)).getSchemeName().equals(HTTPS_PROTOCOL))
|
||||
{
|
||||
String msg = "mTLS is enabled but provided URL does not use a secured protocol";
|
||||
throw new HttpClientException(msg);
|
||||
}
|
||||
});
|
||||
clientBuilder.setSSLSocketFactory(getSslConnectionSocketFactory(config));
|
||||
}
|
||||
|
||||
if (connectionManager != null)
|
||||
{
|
||||
clientBuilder.setConnectionManager(connectionManager);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Setting a connectionManager overrides these properties
|
||||
clientBuilder.setMaxConnTotal(config.getMaxTotalConnections());
|
||||
clientBuilder.setMaxConnPerRoute(config.getMaxHostConnections());
|
||||
}
|
||||
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(config.getConnectionTimeout())
|
||||
.setSocketTimeout(config.getSocketTimeout())
|
||||
.setConnectionRequestTimeout(config.getConnectionRequestTimeout())
|
||||
.build();
|
||||
|
||||
clientBuilder.setDefaultRequestConfig(requestConfig);
|
||||
|
||||
clientBuilder.setRetryHandler(new StandardHttpRequestRetryHandler(5, false));
|
||||
|
||||
return clientBuilder.build();
|
||||
}
|
||||
|
||||
private static SSLConnectionSocketFactory getSslConnectionSocketFactory(HttpClientConfig config)
|
||||
{
|
||||
return new SSLConnectionSocketFactory(
|
||||
createSSLContext(config),
|
||||
new String[] { TLS_V_1_2, TLS_V_1_3 },
|
||||
null,
|
||||
config.isHostnameVerificationDisabled() ? new NoopHostnameVerifier() : SSLConnectionSocketFactory.getDefaultHostnameVerifier());
|
||||
}
|
||||
|
||||
public static PoolingHttpClientConnectionManager createPoolingConnectionManager(HttpClientConfig config)
|
||||
{
|
||||
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager;
|
||||
if(config.isMTLSEnabled())
|
||||
{
|
||||
poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(
|
||||
RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("https", getSslConnectionSocketFactory(config))
|
||||
.build());
|
||||
}
|
||||
else
|
||||
{
|
||||
poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(
|
||||
RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
||||
.build());
|
||||
}
|
||||
poolingHttpClientConnectionManager.setMaxTotal(config.getMaxTotalConnections());
|
||||
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(config.getMaxHostConnections());
|
||||
|
||||
return poolingHttpClientConnectionManager;
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.httpclient;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.encryption.AlfrescoKeyStore;
|
||||
import org.alfresco.encryption.AlfrescoKeyStoreImpl;
|
||||
import org.alfresco.encryption.KeyResourceLoader;
|
||||
import org.alfresco.encryption.ssl.SSLEncryptionParameters;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class HttpClientConfig
|
||||
{
|
||||
private static final String HTTPCLIENT_CONFIG = "httpclient.config.";
|
||||
|
||||
protected static final Log LOGGER = LogFactory.getLog(HttpClientConfig.class);
|
||||
|
||||
private Properties properties;
|
||||
private String serviceName;
|
||||
|
||||
private SSLEncryptionParameters sslEncryptionParameters;
|
||||
private KeyResourceLoader keyResourceLoader;
|
||||
|
||||
private AlfrescoKeyStore keyStore;
|
||||
private AlfrescoKeyStore trustStore;
|
||||
|
||||
private Map<String, String> config;
|
||||
|
||||
public void setProperties(Properties properties)
|
||||
{
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public void setServiceName(String serviceName)
|
||||
{
|
||||
this.serviceName = serviceName;
|
||||
}
|
||||
|
||||
public void setSslEncryptionParameters(SSLEncryptionParameters sslEncryptionParameters)
|
||||
{
|
||||
this.sslEncryptionParameters = sslEncryptionParameters;
|
||||
}
|
||||
|
||||
public void setKeyResourceLoader(KeyResourceLoader keyResourceLoader)
|
||||
{
|
||||
this.keyResourceLoader = keyResourceLoader;
|
||||
}
|
||||
|
||||
public AlfrescoKeyStore getKeyStore()
|
||||
{
|
||||
return keyStore;
|
||||
}
|
||||
|
||||
public AlfrescoKeyStore getTrustStore()
|
||||
{
|
||||
return trustStore;
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
this.keyStore = new AlfrescoKeyStoreImpl(sslEncryptionParameters.getKeyStoreParameters(), keyResourceLoader);
|
||||
this.trustStore = new AlfrescoKeyStoreImpl(sslEncryptionParameters.getTrustStoreParameters(), keyResourceLoader);
|
||||
|
||||
config = retrieveConfig(serviceName);
|
||||
checkUnsupportedProperties(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used for retrieving HttpClient config from Global Properties
|
||||
* @param serviceName name of used service
|
||||
* @return map of properties
|
||||
*/
|
||||
private Map<String, String> retrieveConfig(String serviceName)
|
||||
{
|
||||
return properties.keySet().stream()
|
||||
.filter(key -> key instanceof String)
|
||||
.map(Object::toString)
|
||||
.filter(key -> key.startsWith(HTTPCLIENT_CONFIG + serviceName))
|
||||
.collect(Collectors.toMap(
|
||||
key -> key.replace(HTTPCLIENT_CONFIG + serviceName + ".", ""),
|
||||
key -> properties.getProperty(key, null)));
|
||||
}
|
||||
|
||||
private void checkUnsupportedProperties(Map<String, String> config)
|
||||
{
|
||||
config.keySet().stream()
|
||||
.filter(propertyName -> !HttpClientPropertiesEnum.isPropertyNameSupported(propertyName))
|
||||
.forEach(propertyName -> LOGGER.warn(String.format("For service [%s], an unsupported property [%s] is set", serviceName, propertyName)));
|
||||
}
|
||||
|
||||
private Integer getIntegerProperty(HttpClientPropertiesEnum property)
|
||||
{
|
||||
return Integer.parseInt(extractValueFromConfig(property).orElse("0"));
|
||||
}
|
||||
|
||||
private Boolean getBooleanProperty(HttpClientPropertiesEnum property)
|
||||
{
|
||||
return Boolean.parseBoolean(extractValueFromConfig(property).orElse("false"));
|
||||
}
|
||||
|
||||
private Optional<String> extractValueFromConfig(HttpClientPropertiesEnum property)
|
||||
{
|
||||
Optional<String> optionalProperty = Optional.ofNullable(config.get(property.name));
|
||||
if(property.isRequired && optionalProperty.isEmpty())
|
||||
{
|
||||
String msg = String.format("Required property: '%s' is empty.", property.name);
|
||||
throw new HttpClientException(msg);
|
||||
}
|
||||
return optionalProperty;
|
||||
}
|
||||
|
||||
public Integer getConnectionTimeout()
|
||||
{
|
||||
return getIntegerProperty(HttpClientPropertiesEnum.CONNECTION_REQUEST_TIMEOUT);
|
||||
}
|
||||
|
||||
public Integer getSocketTimeout()
|
||||
{
|
||||
return getIntegerProperty(HttpClientPropertiesEnum.SOCKET_TIMEOUT);
|
||||
}
|
||||
|
||||
public Integer getConnectionRequestTimeout()
|
||||
{
|
||||
return getIntegerProperty(HttpClientPropertiesEnum.CONNECTION_REQUEST_TIMEOUT);
|
||||
}
|
||||
|
||||
public Integer getMaxTotalConnections()
|
||||
{
|
||||
return getIntegerProperty(HttpClientPropertiesEnum.MAX_TOTAL_CONNECTIONS);
|
||||
}
|
||||
|
||||
public Integer getMaxHostConnections()
|
||||
{
|
||||
return getIntegerProperty(HttpClientPropertiesEnum.MAX_HOST_CONNECTIONS);
|
||||
}
|
||||
|
||||
public Boolean isMTLSEnabled()
|
||||
{
|
||||
return getBooleanProperty(HttpClientPropertiesEnum.MTLS_ENABLED);
|
||||
}
|
||||
|
||||
public boolean isHostnameVerificationDisabled()
|
||||
{
|
||||
return getBooleanProperty(HttpClientPropertiesEnum.HOSTNAME_VERIFICATION_DISABLED);
|
||||
}
|
||||
|
||||
private enum HttpClientPropertiesEnum
|
||||
{
|
||||
CONNECTION_TIMEOUT("connectionTimeout", true),
|
||||
SOCKET_TIMEOUT("socketTimeout", true),
|
||||
CONNECTION_REQUEST_TIMEOUT("connectionRequestTimeout", true),
|
||||
MAX_TOTAL_CONNECTIONS("maxTotalConnections", true),
|
||||
MAX_HOST_CONNECTIONS("maxHostConnections", true),
|
||||
HOSTNAME_VERIFICATION_DISABLED("hostnameVerificationDisabled", false),
|
||||
MTLS_ENABLED("mTLSEnabled", true);
|
||||
|
||||
private final String name;
|
||||
private final Boolean isRequired;
|
||||
|
||||
HttpClientPropertiesEnum(String propertyName, Boolean isRequired)
|
||||
{
|
||||
this.name = propertyName;
|
||||
this.isRequired = isRequired;
|
||||
}
|
||||
|
||||
private static final List<String> supportedProperties = new ArrayList<>();
|
||||
|
||||
static {
|
||||
for (HttpClientPropertiesEnum property : HttpClientPropertiesEnum.values()) {
|
||||
supportedProperties.add(property.name);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPropertyNameSupported(String propertyName) {
|
||||
return supportedProperties.contains(propertyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.httpclient;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
|
||||
public class HttpClientException extends AlfrescoRuntimeException
|
||||
{
|
||||
public HttpClientException(String msgId)
|
||||
{
|
||||
super(msgId);
|
||||
}
|
||||
}
|
||||
@@ -45,13 +45,6 @@ public class ListBackedPagingResults<R> implements PagingResults<R>
|
||||
size = list.size();
|
||||
hasMore = false;
|
||||
}
|
||||
|
||||
public ListBackedPagingResults(List<R> list, boolean hasMore)
|
||||
{
|
||||
this(list);
|
||||
this.hasMore = hasMore;
|
||||
}
|
||||
|
||||
public ListBackedPagingResults(List<R> list, PagingRequest paging)
|
||||
{
|
||||
// Excerpt
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
</project>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Fetch image based on Tomcat 9.0, Java 17 and Rocky Linux 8
|
||||
# More infos about this image: https://github.com/Alfresco/alfresco-docker-base-tomcat
|
||||
FROM alfresco/alfresco-base-tomcat:tomcat9-jre17-rockylinux8-202303081618
|
||||
FROM alfresco/alfresco-base-tomcat:tomcat9-jre17-rockylinux8-202209261711
|
||||
|
||||
# Set default docker_context.
|
||||
ARG resource_path=target
|
||||
@@ -65,7 +65,7 @@ RUN sed -i -e "s_appender.rolling.fileName\=alfresco.log_appender.rolling.fileNa
|
||||
RUN yum install -y fontconfig-2.13.1-4.el8 \
|
||||
dejavu-fonts-common-2.35-7.el8 \
|
||||
fontpackages-filesystem-1.44-22.el8 \
|
||||
freetype-2.9.1-9.el8 \
|
||||
freetype-2.9.1-4.el8_3.1 \
|
||||
libpng-1.6.34-5.el8 \
|
||||
dejavu-sans-fonts-2.35-7.el8 && \
|
||||
yum clean all
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<image.name>alfresco/alfresco-community-repo-base</image.name>
|
||||
<scripts.directory>${project.parent.parent.basedir}/scripts</scripts.directory>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -157,67 +156,6 @@
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>build-multiarch-docker-images</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<images>
|
||||
<image>
|
||||
<name>${local.registry}/${image.name}:${image.tag}</name>
|
||||
<build>
|
||||
<buildx>
|
||||
<platforms>
|
||||
<platform>linux/amd64</platform>
|
||||
<platform>linux/arm64</platform>
|
||||
</platforms>
|
||||
<builderName>${builder.name}</builderName>
|
||||
</buildx>
|
||||
<contextDir>${project.basedir}</contextDir>
|
||||
</build>
|
||||
</image>
|
||||
</images>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>build-push-image</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
<goal>push</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare-buildx</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>${scripts.directory}/prepare_buildx.sh</executable>
|
||||
<arguments>
|
||||
<argument>${builder.name}</argument>
|
||||
<argument>${image.registry}</argument>
|
||||
<argument>${image.name}</argument>
|
||||
<argument>${image.tag}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>push-docker-images</id>
|
||||
<!-- publishes "image:latest" on Quay & DockerHub -->
|
||||
@@ -230,29 +168,12 @@
|
||||
<images>
|
||||
<!-- Quay image -->
|
||||
<image>
|
||||
<name>${image.registry}/${image.name}:${image.tag}</name>
|
||||
<build>
|
||||
<buildx>
|
||||
<platforms>
|
||||
<platform>linux/amd64</platform>
|
||||
<platform>linux/arm64</platform>
|
||||
</platforms>
|
||||
</buildx>
|
||||
<contextDir>${project.basedir}</contextDir>
|
||||
</build>
|
||||
<name>${image.name}:${image.tag}</name>
|
||||
<registry>${image.registry}</registry>
|
||||
</image>
|
||||
<!-- DockerHub image -->
|
||||
<image>
|
||||
<name>${image.name}:${image.tag}</name>
|
||||
<build>
|
||||
<buildx>
|
||||
<platforms>
|
||||
<platform>linux/amd64</platform>
|
||||
<platform>linux/arm64</platform>
|
||||
</platforms>
|
||||
</buildx>
|
||||
<contextDir>${project.basedir}</contextDir>
|
||||
</build>
|
||||
</image>
|
||||
</images>
|
||||
</configuration>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
SOLR6_TAG=2.0.7-A5
|
||||
SOLR6_TAG=2.0.7-A2
|
||||
POSTGRES_TAG=14.4
|
||||
ACTIVEMQ_TAG=5.17.1-jre11-rockylinux8
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<organization>
|
||||
|
||||
@@ -4,6 +4,8 @@ import org.alfresco.utility.data.AisToken;
|
||||
import org.alfresco.utility.data.auth.DataAIS;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
import org.apache.chemistry.opencmis.commons.SessionParameter;
|
||||
import org.keycloak.authorization.client.util.HttpResponseException;
|
||||
import org.keycloak.representations.AccessTokenResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -84,9 +86,9 @@ public class AuthParameterProviderFactory
|
||||
parameters.put(SessionParameter.OAUTH_REFRESH_TOKEN, aisToken.getRefreshToken());
|
||||
parameters.put(SessionParameter.OAUTH_EXPIRATION_TIMESTAMP, String.valueOf(System.currentTimeMillis()
|
||||
+ (aisToken.getExpiresIn() * 1000))); // getExpiresIn is in seconds
|
||||
parameters.put(SessionParameter.OAUTH_TOKEN_ENDPOINT, cmisProperties.aisProperty().getAuthServerUrl()
|
||||
parameters.put(SessionParameter.OAUTH_TOKEN_ENDPOINT, cmisProperties.aisProperty().getAdapterConfig().getAuthServerUrl()
|
||||
+ "/realms/alfresco/protocol/openid-connect/token");
|
||||
parameters.put(SessionParameter.OAUTH_CLIENT_ID, cmisProperties.aisProperty().getResource());
|
||||
parameters.put(SessionParameter.OAUTH_CLIENT_ID, cmisProperties.aisProperty().getAdapterConfig().getResource());
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@@ -108,10 +110,10 @@ public class AuthParameterProviderFactory
|
||||
// Attempt to get an access token for userModel from AIS
|
||||
aisToken = dataAIS.perform().getAccessToken(userModel);
|
||||
}
|
||||
catch (AssertionError e)
|
||||
catch (HttpResponseException e)
|
||||
{
|
||||
// Trying to authenticate with invalid user credentials so return an invalid access token
|
||||
if (e.getMessage().contains("invalid_grant"))
|
||||
if (e.getStatusCode() == 401)
|
||||
{
|
||||
STEP(String.format("%s Invalid user credentials were provided %s:%s. Using invalid token for reqest.",
|
||||
STEP_PREFIX, userModel.getUsername(), userModel.getPassword()));
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
@@ -95,6 +95,7 @@
|
||||
<dependency>
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
<version>${dependency.jakarta-json-path.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -165,14 +165,14 @@
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
<version>3.0.16</version>
|
||||
<version>3.0.12</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-json-->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-json</artifactId>
|
||||
<version>3.0.16</version>
|
||||
<version>3.0.12</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -30,6 +30,7 @@ import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import org.alfresco.utility.data.AisToken;
|
||||
import org.alfresco.utility.data.auth.DataAIS;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
import org.keycloak.authorization.client.util.HttpResponseException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -85,11 +86,12 @@ public class RestAisAuthentication
|
||||
// Attempt to get an access token for userModel from AIS
|
||||
aisToken = dataAIS.perform().getAccessToken(userModel);
|
||||
}
|
||||
catch (AssertionError e)
|
||||
catch (HttpResponseException e)
|
||||
{
|
||||
// Trying to authenticate with invalid user credentials or disabled
|
||||
// user so return an invalid access token
|
||||
if (e.getMessage().contains("invalid_grant"))
|
||||
String httpResponse = new String(e.getBytes());
|
||||
if (e.getStatusCode() == 401 || httpResponse.contains(USER_DISABLED_MSG))
|
||||
{
|
||||
STEP(String.format("%s User disabled or invalid user credentials were provided %s:%s. Using invalid token for request.", STEP_PREFIX,
|
||||
userModel.getUsername(), userModel.getPassword()));
|
||||
|
||||
@@ -680,22 +680,17 @@ public class RestWrapper extends DSLWrapper<RestWrapper>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (returnedResponse.asString().isEmpty())
|
||||
{
|
||||
LOG.info("On {} {}, received the following response \n{}", restRequest.getHttpMethod(), restRequest.getPath(),
|
||||
returnedResponse.getStatusCode());
|
||||
}
|
||||
else if (returnedResponse.getContentType().contains("image/png"))
|
||||
if (returnedResponse.getContentType().contains("image/png"))
|
||||
{
|
||||
LOG.info("On {} {}, received the response with an image and headers: \n{}", restRequest.getHttpMethod(), restRequest.getPath(),
|
||||
returnedResponse.getHeaders().toString());
|
||||
returnedResponse.getHeaders().toString());
|
||||
}
|
||||
else if (returnedResponse.getContentType().contains("application/json"))
|
||||
else if (returnedResponse.getContentType().contains("application/json") && !returnedResponse.asString().isEmpty())
|
||||
{
|
||||
LOG.info("On {} {}, received the following response \n{}", restRequest.getHttpMethod(), restRequest.getPath(),
|
||||
Utility.prettyPrintJsonString(returnedResponse.asString()));
|
||||
Utility.prettyPrintJsonString(returnedResponse.asString()));
|
||||
}
|
||||
else if (returnedResponse.getContentType().contains("application/xml"))
|
||||
else if (returnedResponse.getContentType().contains("application/xml") && !returnedResponse.asString().isEmpty())
|
||||
{
|
||||
String response = parseXML(returnedResponse);
|
||||
LOG.info("On {} {}, received the following response \n{}", restRequest.getHttpMethod(), restRequest.getPath(), response);
|
||||
@@ -703,7 +698,7 @@ public class RestWrapper extends DSLWrapper<RestWrapper>
|
||||
else
|
||||
{
|
||||
LOG.info("On {} {}, received the following response \n{}", restRequest.getHttpMethod(), restRequest.getPath(),
|
||||
ToStringBuilder.reflectionToString(returnedResponse.asString(), ToStringStyle.MULTI_LINE_STYLE));
|
||||
ToStringBuilder.reflectionToString(returnedResponse.asString(), ToStringStyle.MULTI_LINE_STYLE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,7 @@ import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.rest.core.IRestModelsCollection;
|
||||
import org.alfresco.utility.exception.TestConfigurationException;
|
||||
@@ -120,7 +117,7 @@ public class ModelsCollectionAssertion<C>
|
||||
return (C) modelCollection;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings("unchecked")
|
||||
public C entriesListDoesNotContain(String key, String value)
|
||||
{
|
||||
boolean exist = false;
|
||||
@@ -146,53 +143,6 @@ public class ModelsCollectionAssertion<C>
|
||||
return (C) modelCollection;
|
||||
}
|
||||
|
||||
public C entrySetContains(String key, String... expectedValues)
|
||||
{
|
||||
return entrySetContains(key, Arrays.stream(expectedValues).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public C entrySetContains(String key, Collection<String> expectedValues)
|
||||
{
|
||||
Collection<String> actualValues = ((List<Model>) modelCollection.getEntries()).stream()
|
||||
.map(model -> extractValueAsString(model, key))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Assert.assertTrue(actualValues.containsAll(expectedValues), String.format("Entry with key: \"%s\" is expected to contain values: %s, but actual values are: %s",
|
||||
key, expectedValues, actualValues));
|
||||
|
||||
return (C) modelCollection;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public C entrySetMatches(String key, Collection<String> expectedValues)
|
||||
{
|
||||
Collection<String> actualValues = ((List<Model>) modelCollection.getEntries()).stream()
|
||||
.map(model -> extractValueAsString(model, key))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Assert.assertEqualsNoOrder(actualValues, expectedValues, String.format("Entry with key: \"%s\" is expected to match values: %s, but actual values are: %s",
|
||||
key, expectedValues, actualValues));
|
||||
|
||||
return (C) modelCollection;
|
||||
}
|
||||
|
||||
private String extractValueAsString(Model model, String key)
|
||||
{
|
||||
String fieldValue;
|
||||
Object modelObject = loadModel(model);
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String jsonInString = mapper.writeValueAsString(modelObject);
|
||||
fieldValue = JsonPath.with(jsonInString).get(key);
|
||||
} catch (Exception e) {
|
||||
throw new TestConfigurationException(String.format(
|
||||
"You try to assert field [%s] that doesn't exist in class: [%s]. Exception: %s, Please check your code!",
|
||||
key, getClass().getCanonicalName(), e.getMessage()));
|
||||
}
|
||||
return fieldValue;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public C entriesListDoesNotContain(String key)
|
||||
{
|
||||
|
||||
@@ -52,11 +52,6 @@ This must be unique within the parent category.
|
||||
*/
|
||||
private long count;
|
||||
|
||||
/**
|
||||
The path to this category.
|
||||
*/
|
||||
private String path;
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return this.id;
|
||||
@@ -107,14 +102,6 @@ This must be unique within the parent category.
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
@@ -139,7 +126,6 @@ This must be unique within the parent category.
|
||||
", parentId='" + parentId + '\'' +
|
||||
", hasChildren=" + hasChildren +
|
||||
", count=" + count +
|
||||
", path=" + path +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class RestErrorModel
|
||||
public static String INVALID_MAXITEMS = "Invalid paging parameter maxItems:%s";
|
||||
public static String INVALID_SKIPCOUNT = "Invalid paging parameter skipCount:%s";
|
||||
public static String INVALID_TAG = "Tag name must not contain %s char sequence";
|
||||
public static String BLANK_TAG = "New tag cannot be blank";
|
||||
public static String EMPTY_TAG = "New tag cannot be null";
|
||||
public static String UNKNOWN_ROLE = "Unknown role '%s'";
|
||||
public static String ALREADY_Site_MEMBER = "%s is already a member of site %s";
|
||||
public static String ALREADY_INVITED = "%s is already invited to site %s";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,223 +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.RestCategoryLinkBodyModel;
|
||||
import org.alfresco.rest.model.RestCategoryModel;
|
||||
import org.alfresco.rest.model.RestCategoryModelsCollection;
|
||||
import org.alfresco.utility.Utility;
|
||||
import org.alfresco.utility.model.FileModel;
|
||||
import org.alfresco.utility.model.FolderModel;
|
||||
import org.alfresco.utility.model.SiteModel;
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class CategoriesPathTests extends CategoriesRestTest
|
||||
{
|
||||
private FileModel file;
|
||||
private RestCategoryModel category;
|
||||
|
||||
@BeforeClass(alwaysRun = true)
|
||||
@Override
|
||||
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 a category");
|
||||
FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||
file = dataContent.usingUser(user).usingResource(folder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
category = prepareCategoryUnderRoot();
|
||||
|
||||
STEP("Wait for indexing to complete");
|
||||
Utility.sleep(1000, 60000, () -> restClient.authenticateUser(user)
|
||||
.withCoreAPI()
|
||||
.usingCategory(category)
|
||||
.include(INCLUDE_PATH_PARAM)
|
||||
.getCategory()
|
||||
.assertThat()
|
||||
.field(FIELD_PATH)
|
||||
.isNotNull());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify path for a category got by ID.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API })
|
||||
public void testGetCategoryById_includePath()
|
||||
{
|
||||
STEP("Get category and verify if path is a general path for categories");
|
||||
final RestCategoryModel actualCategory = restClient.authenticateUser(user)
|
||||
.withCoreAPI()
|
||||
.usingCategory(category)
|
||||
.include(INCLUDE_PATH_PARAM)
|
||||
.getCategory();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
actualCategory.assertThat().field(FIELD_ID).is(category.getId());
|
||||
actualCategory.assertThat().field(FIELD_PATH).is("/categories/General");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify path for category.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API })
|
||||
public void testGetCategories_includePath()
|
||||
{
|
||||
STEP("Get few categories and verify its paths");
|
||||
final RestCategoryModel parentCategory = createCategoryModelWithId(ROOT_CATEGORY_ID);
|
||||
final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user)
|
||||
.withCoreAPI()
|
||||
.usingCategory(parentCategory)
|
||||
.include(INCLUDE_PATH_PARAM)
|
||||
.getCategoryChildren();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
assertTrue(actualCategories.getEntries().stream()
|
||||
.map(RestCategoryModel::onModel)
|
||||
.allMatch(cat -> cat.getPath().equals("/categories/General")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify path for child category.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API })
|
||||
public void testGetChildCategory_includePath()
|
||||
{
|
||||
STEP("Create parent and child categories");
|
||||
final RestCategoryModel parentCategory = prepareCategoryUnderRoot();
|
||||
final RestCategoryModel childCategory = prepareCategoryUnder(parentCategory);
|
||||
|
||||
STEP("Verify path for created child categories");
|
||||
final RestCategoryModelsCollection actualCategories = restClient.authenticateUser(user)
|
||||
.withCoreAPI()
|
||||
.usingCategory(parentCategory)
|
||||
.include(INCLUDE_PATH_PARAM)
|
||||
.getCategoryChildren();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
actualCategories.getEntries().stream()
|
||||
.map(RestCategoryModel::onModel)
|
||||
.forEach(cat -> cat.assertThat().field(FIELD_PATH).is("/categories/General/" + parentCategory.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create category and verify that it has a path.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API })
|
||||
public void testCreateCategory_includingPath()
|
||||
{
|
||||
STEP("Create a category under root and verify if path is a general path for categories");
|
||||
final String categoryName = getRandomName("Category");
|
||||
final RestCategoryModel rootCategory = createCategoryModelWithId(ROOT_CATEGORY_ID);
|
||||
final RestCategoryModel aCategory = createCategoryModelWithName(categoryName);
|
||||
final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
|
||||
.withCoreAPI()
|
||||
.include(INCLUDE_PATH_PARAM)
|
||||
.usingCategory(rootCategory)
|
||||
.createSingleCategory(aCategory);
|
||||
|
||||
restClient.assertStatusCodeIs(CREATED);
|
||||
createdCategory.assertThat().field(FIELD_NAME).is(categoryName);
|
||||
createdCategory.assertThat().field(FIELD_PATH).is("/categories/General");
|
||||
}
|
||||
|
||||
/**
|
||||
* Update category and verify that it has a path.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API })
|
||||
public void testUpdateCategory_includePath()
|
||||
{
|
||||
STEP("Update linked category and verify if path is a general path for categories");
|
||||
final String categoryNewName = getRandomName("NewCategoryName");
|
||||
final RestCategoryModel fixedCategoryModel = createCategoryModelWithName(categoryNewName);
|
||||
final RestCategoryModel updatedCategory = restClient.authenticateUser(dataUser.getAdminUser())
|
||||
.withCoreAPI()
|
||||
.usingCategory(category)
|
||||
.include(INCLUDE_PATH_PARAM)
|
||||
.updateCategory(fixedCategoryModel);
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
updatedCategory.assertThat().field(FIELD_ID).is(category.getId());
|
||||
updatedCategory.assertThat().field(FIELD_PATH).is("/categories/General");
|
||||
}
|
||||
|
||||
/**
|
||||
* Link node to categories and verify that they have path.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API })
|
||||
public void testLinkNodeToCategories_includePath()
|
||||
{
|
||||
STEP("Link node to categories and verify if path is a general path");
|
||||
final RestCategoryLinkBodyModel categoryLinkModel = createCategoryLinkModelWithId(category.getId());
|
||||
final RestCategoryModel linkedCategory = restClient.authenticateUser(dataUser.getAdminUser())
|
||||
.withCoreAPI()
|
||||
.usingNode(file)
|
||||
.include(INCLUDE_PATH_PARAM)
|
||||
.linkToCategory(categoryLinkModel);
|
||||
|
||||
restClient.assertStatusCodeIs(CREATED);
|
||||
linkedCategory.assertThat().field(FIELD_ID).is(category.getId());
|
||||
linkedCategory.assertThat().field(FIELD_PATH).is("/categories/General");
|
||||
}
|
||||
|
||||
/**
|
||||
* List categories for given node and verify that they have a path.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API })
|
||||
public void testListCategoriesForNode_includePath()
|
||||
{
|
||||
STEP("Link file to category");
|
||||
final RestCategoryLinkBodyModel categoryLink = createCategoryLinkModelWithId(category.getId());
|
||||
final RestCategoryModel linkedCategory = restClient.authenticateUser(dataUser.getAdminUser())
|
||||
.withCoreAPI()
|
||||
.usingNode(file)
|
||||
.include(INCLUDE_PATH_PARAM)
|
||||
.linkToCategory(categoryLink);
|
||||
|
||||
STEP("Get linked category and verify if path is a general path");
|
||||
final RestCategoryModelsCollection linkedCategories = restClient.authenticateUser(dataUser.getAdminUser())
|
||||
.withCoreAPI()
|
||||
.usingNode(file)
|
||||
.include(INCLUDE_PATH_PARAM)
|
||||
.getLinkedCategories();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
linkedCategories.assertThat().entriesListCountIs(1);
|
||||
linkedCategories.getEntries().get(0).onModel().assertThat().field(FIELD_ID).is(category.getId());
|
||||
linkedCategories.getEntries().get(0).onModel().assertThat().field(FIELD_PATH).is("/categories/General");
|
||||
}
|
||||
}
|
||||
@@ -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,23 +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 INCLUDE_PATH_PARAM = "path";
|
||||
protected static final String ROOT_CATEGORY_ID = "-root-";
|
||||
protected static final String CATEGORY_NAME_PREFIX = "CategoryName";
|
||||
protected static final String FIELD_NAME = "name";
|
||||
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 static final String FIELD_PATH = "path";
|
||||
|
||||
protected UserModel user;
|
||||
|
||||
@@ -65,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()
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,5 @@
|
||||
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.CREATED;
|
||||
import static org.springframework.http.HttpStatus.OK;
|
||||
|
||||
import org.alfresco.rest.model.RestErrorModel;
|
||||
import org.alfresco.rest.model.RestTagModel;
|
||||
import org.alfresco.utility.constants.UserRole;
|
||||
@@ -19,14 +14,9 @@ import org.testng.annotations.Test;
|
||||
public class GetTagTests extends TagsDataPrep
|
||||
{
|
||||
|
||||
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";
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify admin user gets tag using REST API and status code is OK (200)")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsAbleToGetTag()
|
||||
public void adminIsAbleToGetTag() throws Exception
|
||||
{
|
||||
RestTagModel returnedTag = restClient.authenticateUser(adminUserModel).withCoreAPI().getTag(documentTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
@@ -35,7 +25,7 @@ public class GetTagTests extends TagsDataPrep
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, description = "Verify user with Manager role gets tag using REST API and status code is OK (200)")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void userWithManagerRoleIsAbleToGetTag()
|
||||
public void userWithManagerRoleIsAbleToGetTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
|
||||
@@ -47,7 +37,7 @@ public class GetTagTests extends TagsDataPrep
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify user with Collaborator role gets tag using REST API and status code is OK (200)")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void userWithCollaboratorRoleIsAbleToGetTag()
|
||||
public void userWithCollaboratorRoleIsAbleToGetTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
RestTagModel returnedTag = restClient.withCoreAPI().getTag(documentTag);
|
||||
@@ -57,7 +47,7 @@ public class GetTagTests extends TagsDataPrep
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify user with Contributor role gets tag using REST API and status code is OK (200)")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void userWithContributorRoleIsAbleToGetTag()
|
||||
public void userWithContributorRoleIsAbleToGetTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor));
|
||||
RestTagModel returnedTag = restClient.withCoreAPI().getTag(documentTag);
|
||||
@@ -67,7 +57,7 @@ public class GetTagTests extends TagsDataPrep
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify user with Consumer role gets tag using REST API and status code is OK (200)")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void userWithConsumerRoleIsAbleToGetTag()
|
||||
public void userWithConsumerRoleIsAbleToGetTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer));
|
||||
RestTagModel returnedTag = restClient.withCoreAPI().getTag(documentTag);
|
||||
@@ -78,7 +68,7 @@ public class GetTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, description = "Verify Manager user gets status code 401 if authentication call fails")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void managerIsNotAbleToGetTagIfAuthenticationFails()
|
||||
public void managerIsNotAbleToGetTagIfAuthenticationFails() throws Exception
|
||||
{
|
||||
UserModel managerUser = dataUser.usingAdmin().createRandomTestUser();
|
||||
String managerPassword = managerUser.getPassword();
|
||||
@@ -92,7 +82,7 @@ public class GetTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if tag id is invalid status code returned is 400")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void invalidTagIdTest()
|
||||
public void invalidTagIdTest() throws Exception
|
||||
{
|
||||
String tagId = documentTag.getId();
|
||||
documentTag.setId("random_tag_value");
|
||||
@@ -104,7 +94,7 @@ public class GetTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Check that properties filter is applied when getting tag using Manager user.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void checkPropertiesFilterIsApplied()
|
||||
public void checkPropertiesFilterIsApplied() throws Exception
|
||||
{
|
||||
RestTagModel returnedTag = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
|
||||
.withParams("properties=id,tag").withCoreAPI().getTag(documentTag);
|
||||
@@ -117,7 +107,7 @@ public class GetTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Check that Manager user can get tag of a folder.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void getTagOfAFolder()
|
||||
public void getTagOfAFolder() throws Exception
|
||||
{
|
||||
RestTagModel returnedTag = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
|
||||
.withCoreAPI().getTag(folderTag);
|
||||
@@ -128,7 +118,7 @@ public class GetTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Check default error model schema. Use invalid skipCount parameter.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void checkDefaultErrorModelSchema()
|
||||
public void checkDefaultErrorModelSchema() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
|
||||
.withParams("skipCount=abc").withCoreAPI().getTag(documentTag);
|
||||
@@ -138,44 +128,4 @@ public class GetTagTests extends TagsDataPrep
|
||||
.descriptionURLIs(RestErrorModel.RESTAPIEXPLORER)
|
||||
.stackTraceIs(RestErrorModel.STACKTRACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that count field is not present for searched tag when not requested.
|
||||
*/
|
||||
@Test(groups = {TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION})
|
||||
public void testGetTag_notIncludingCount()
|
||||
{
|
||||
STEP("Create single tag as admin");
|
||||
String tagName = getRandomName(TAG_NAME_PREFIX).toLowerCase();
|
||||
final RestTagModel tagModel = createTagModelWithName(tagName);
|
||||
final RestTagModel createdTag = restClient.authenticateUser(adminUserModel).withCoreAPI().createSingleTag(tagModel);
|
||||
|
||||
restClient.assertStatusCodeIs(CREATED);
|
||||
|
||||
STEP("Get a single tag, not including count and verify if it is not present in the response");
|
||||
final RestTagModel searchedTag = restClient.withCoreAPI().getTag(createdTag);
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
RestTagModel expected = RestTagModel.builder().id(createdTag.getId()).tag(tagName).create();
|
||||
searchedTag.assertThat().isEqualTo(expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the count field can be included.
|
||||
*/
|
||||
@Test (groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTag_includeCount()
|
||||
{
|
||||
STEP("Create unused tag as admin");
|
||||
String tagName = getRandomName(TAG_NAME_PREFIX).toLowerCase();
|
||||
RestTagModel tagModel = createTagModelWithName(tagName);
|
||||
RestTagModel createdTag = restClient.authenticateUser(adminUserModel).withCoreAPI().createSingleTag(tagModel);
|
||||
|
||||
STEP("Get a single tag with the count field");
|
||||
RestTagModel searchedTag = restClient.withCoreAPI().include("count").getTag(createdTag);
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
RestTagModel expected = RestTagModel.builder().id(createdTag.getId()).tag(tagName).count(0).create();
|
||||
searchedTag.assertThat().isEqualTo(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,219 +1,79 @@
|
||||
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.OK;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.rest.model.RestErrorModel;
|
||||
import org.alfresco.rest.model.RestTagModel;
|
||||
import org.alfresco.rest.model.RestTagModelsCollection;
|
||||
import org.alfresco.utility.constants.UserRole;
|
||||
import org.alfresco.utility.data.RandomData;
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.alfresco.utility.testrail.ExecutionType;
|
||||
import org.alfresco.utility.testrail.annotation.TestRail;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.alfresco.utility.report.log.Step.STEP;
|
||||
|
||||
@Test(groups = {TestGroup.REQUIRE_SOLR})
|
||||
public class GetTagsTests extends TagsDataPrep
|
||||
{
|
||||
|
||||
private static final String FIELD_ID = "id";
|
||||
private static final String FIELD_TAG = "tag";
|
||||
private static final String FIELD_COUNT = "count";
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void dataPreparation() throws Exception
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, description = "Verify user with Manager role gets tags using REST API and status code is OK (200)")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void getTagsWithManagerRole()
|
||||
public void getTagsWithManagerRole() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify user with Collaborator role gets tags using REST API and status code is OK (200)")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void getTagsWithCollaboratorRole()
|
||||
public void getTagsWithCollaboratorRole() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify user with Contributor role gets tags using REST API and status code is OK (200)")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void getTagsWithContributorRole()
|
||||
public void getTagsWithContributorRole() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor));
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify user with Consumer role gets tags using REST API and status code is OK (200)")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void getTagsWithConsumerRole()
|
||||
public void getTagsWithConsumerRole() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer));
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Include count in the query parameters and ensure count is as expected for returned tags.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withIncludeCount()
|
||||
{
|
||||
STEP("Get tags including count filter and ensure count is as expected for returned tags");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("include=count")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
|
||||
returnedCollection.getEntries().stream()
|
||||
.filter(e -> e.onModel().getTag().equals(folderTagValue) || e.onModel().getTag().equals(documentTagValue))
|
||||
.forEach(e -> e.onModel().assertThat().field("count").is(2));
|
||||
|
||||
returnedCollection.getEntries().stream()
|
||||
.filter(e -> e.onModel().getTag().equals(documentTagValue2))
|
||||
.forEach(e -> e.onModel().assertThat().field("count").is(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tags and order results by count. Default sort order should be ascending
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withOrderByCountDefaultOrderShouldBeAsc()
|
||||
{
|
||||
STEP("Get tags and order results by count. Default sort order should be ascending");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("include=count&orderBy=count")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsSortedAscBy("count");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tags and order results by count in ascending order
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withOrderByCountAsc()
|
||||
{
|
||||
STEP("Get tags and order results by count in ascending order");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("include=count&orderBy=count ASC")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsSortedAscBy("count");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tags and order results by count in descending order
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withOrderByCountDesc()
|
||||
{
|
||||
STEP("Get tags and order results by count in descending order");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("include=count&orderBy=count DESC")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsSortedDescBy("count");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tags and order results by tag name. Default sort order should be ascending
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withOrderByTagDefaultOrderShouldBeAsc()
|
||||
{
|
||||
STEP("Get tags and order results by tag name. Default sort order should be ascending");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("orderBy=tag")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsSortedAscBy("tag");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tags and order results by tag name in ascending order
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withOrderByTagAsc()
|
||||
{
|
||||
STEP("Get tags and order results by tag name in ascending order");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("orderBy=tag ASC")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsSortedAscBy("tag");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tags and order results by tag name in descending order
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withOrderByTagDesc()
|
||||
{
|
||||
STEP("Get tags and order results by tag name in descending order");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("orderBy=tag DESC")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsSortedDescBy("tag");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that we get a 400 error when we request to order by count without also including the tag count.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_orderByCountWithoutIncludeCount()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel)
|
||||
.withParams("orderBy=count")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(BAD_REQUEST);
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, description = "Failed authentication get tags call returns status code 401 with Manager role")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void failedAuthenticationReturnsUnauthorizedStatus()
|
||||
public void failedAuthenticationReturnsUnauthorizedStatus() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
userModel = dataUser.createRandomTestUser();
|
||||
@@ -227,7 +87,7 @@ public class GetTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if maxItems is invalid status code returned is 400")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION})
|
||||
public void maxItemsInvalidValueTest()
|
||||
public void maxItemsInvalidValueTest() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel).withParams("maxItems=abc").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST).assertLastError().containsSummary(String.format(RestErrorModel.INVALID_MAXITEMS, "abc"));
|
||||
@@ -236,7 +96,7 @@ public class GetTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if skipCount is invalid status code returned is 400")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION})
|
||||
public void skipCountInvalidValueTest()
|
||||
public void skipCountInvalidValueTest() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel).withParams("skipCount=abc").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST).assertLastError().containsSummary(String.format(RestErrorModel.INVALID_SKIPCOUNT, "abc"));
|
||||
@@ -245,55 +105,55 @@ public class GetTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that file tag is retrieved")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION})
|
||||
public void fileTagIsRetrieved()
|
||||
public void fileTagIsRetrieved() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that folder tag is retrieved")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION})
|
||||
public void folderTagIsRetrieved()
|
||||
public void folderTagIsRetrieved() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", folderTagValue);
|
||||
.and().entriesListContains("tag", folderTagValue.toLowerCase());
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify site Manager is able to get tags using properties parameter."
|
||||
+ "Check that properties filter is applied.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void siteManagerIsAbleToRetrieveTagsWithPropertiesParameter()
|
||||
public void siteManagerIsAbleToRetrieveTagsWithPropertiesParameter() throws Exception
|
||||
{
|
||||
returnedCollection = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
|
||||
.withParams("maxItems=5000&properties=tag").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2)
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase())
|
||||
.and().entriesListDoesNotContain("id");
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "With admin get tags and use skipCount parameter. Check pagination")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void useSkipCountCheckPagination()
|
||||
public void useSkipCountCheckPagination() throws Exception
|
||||
{
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel).withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
RestTagModel firstTag = returnedCollection.getEntries().get(0).onModel();
|
||||
RestTagModel secondTag = returnedCollection.getEntries().get(1).onModel();
|
||||
RestTagModelsCollection tagsWithSkipCount = restClient.withParams("skipCount=2").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
tagsWithSkipCount.assertThat().entriesListDoesNotContain("tag", firstTag.getTag())
|
||||
.assertThat().entriesListDoesNotContain("tag", secondTag.getTag());
|
||||
@@ -303,15 +163,15 @@ public class GetTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "With admin get tags and use maxItems parameter. Check pagination")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void useMaxItemsParameterCheckPagination()
|
||||
public void useMaxItemsParameterCheckPagination() throws Exception
|
||||
{
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel).withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
RestTagModel firstTag = returnedCollection.getEntries().get(0).onModel();
|
||||
RestTagModel secondTag = returnedCollection.getEntries().get(1).onModel();
|
||||
RestTagModelsCollection tagsWithMaxItems = restClient.withParams("maxItems=2").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
tagsWithMaxItems.assertThat().entriesListContains("tag", firstTag.getTag())
|
||||
.assertThat().entriesListContains("tag", secondTag.getTag())
|
||||
@@ -322,22 +182,23 @@ public class GetTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "With manager get tags and use high skipCount parameter. Check pagination")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void useHighSkipCountCheckPagination()
|
||||
public void useHighSkipCountCheckPagination() throws Exception
|
||||
{
|
||||
returnedCollection = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
|
||||
.withParams("skipCount=20000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat().entriesListIsEmpty()
|
||||
.getPagination().assertThat().field("maxItems").is(100)
|
||||
.and().field("hasMoreItems").is("false")
|
||||
.and().field("count").is("0")
|
||||
.and().field("skipCount").is(20000);
|
||||
.and().field("skipCount").is(20000)
|
||||
.and().field("totalItems").isNull();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "With Collaborator user get tags and use maxItems with value zero. Check default error model schema")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void useMaxItemsWithValueZeroCheckDefaultErrorModelSchema()
|
||||
public void useMaxItemsWithValueZeroCheckDefaultErrorModelSchema() throws Exception
|
||||
{
|
||||
returnedCollection = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
|
||||
.withParams("maxItems=0").withCoreAPI().getTags();
|
||||
@@ -351,167 +212,18 @@ public class GetTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "With Manager user delete tag. Check it is not retrieved anymore.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void checkThatDeletedTagIsNotRetrievedAnymore()
|
||||
public void checkThatDeletedTagIsNotRetrievedAnymore() throws Exception
|
||||
{
|
||||
String removedTag = getRandomName("tag3");
|
||||
String removedTag = RandomData.getRandomName("tag3");
|
||||
|
||||
RestTagModel deletedTag = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
|
||||
.withCoreAPI().usingResource(document).addTag(removedTag);
|
||||
|
||||
restClient.authenticateUser(adminUserModel).withCoreAPI().usingTag(deletedTag).deleteTag();
|
||||
restClient.withCoreAPI().usingResource(document).deleteTag(deletedTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.NO_CONTENT);
|
||||
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListDoesNotContain("tag", removedTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if exact name filter can be applied.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withSingleNameFilter()
|
||||
{
|
||||
STEP("Get tags with names filter using EQUALS and expect one item in result");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(tag='" + documentTag.getTag() + "')")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetMatches("tag", Set.of(documentTagValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if multiple names can be applied as a filter.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withTwoNameFilters()
|
||||
{
|
||||
STEP("Get tags with names filter using IN and expect two items in result");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(tag IN ('" + documentTag.getTag() + "', '" + folderTag.getTag() + "'))")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetMatches("tag", Set.of(documentTagValue, folderTagValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if alike name filter can be applied.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_whichNamesStartsWithOrphan()
|
||||
{
|
||||
STEP("Get tags with names filter using MATCHES and expect one item in result");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(tag MATCHES ('orphan*'))", "maxItems=10000")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetContains("tag", orphanTag.getTag());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that tags can be filtered by exact name and alike name at the same time.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withExactNameAndAlikeFilters()
|
||||
{
|
||||
STEP("Get tags with names filter using EQUALS and MATCHES and expect four items in result");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(tag MATCHES ('*tag*'))", "maxItems=10000")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetContains("tag", documentTagValue, documentTagValue2, folderTagValue, orphanTag.getTag());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if multiple alike filters can be applied.
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withTwoAlikeFilters()
|
||||
{
|
||||
STEP("Get tags applying names filter using MATCHES twice and expect four items in result");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(tag MATCHES ('orphan*') OR tag MATCHES ('tag*'))", "maxItems=10000")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetContains("tag", documentTagValue, documentTagValue2, folderTagValue, orphanTag.getTag());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that providing incorrect field name in where query will result with 400 (Bad Request).
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withWrongWherePropertyNameAndExpect400()
|
||||
{
|
||||
STEP("Try to get tags with names filter using EQUALS and wrong property name and expect 400");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(name=gat)")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary("Where query error: property with name: name is not expected");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify tht AND operator is not supported in where query and expect 400 (Bad Request).
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_queryAndOperatorNotSupported()
|
||||
{
|
||||
STEP("Try to get tags applying names filter using AND operator and expect 400");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(name=tag AND name IN ('tag-', 'gat'))")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary("An invalid WHERE query was received. Unsupported Predicate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if count field is present for searched tags.
|
||||
*/
|
||||
@Test(groups = {TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION})
|
||||
public void testGetTags_includingCount()
|
||||
{
|
||||
STEP("Get tags including count and verify if it is present in the response");
|
||||
final RestTagModelsCollection searchedTags = restClient.withCoreAPI().include(FIELD_COUNT).getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
searchedTags.assertThat().entriesListIsNotEmpty()
|
||||
.assertThat().entriesListContains(FIELD_COUNT)
|
||||
.assertThat().entriesListContains(FIELD_TAG)
|
||||
.assertThat().entriesListContains(FIELD_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if count field is not present for searched tags.
|
||||
*/
|
||||
@Test(groups = {TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION})
|
||||
public void testGetTags_notIncludingCount()
|
||||
{
|
||||
STEP("Get tags, not including count and verify if it is not in the response");
|
||||
final RestTagModelsCollection searchedTags = restClient.withCoreAPI().getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
searchedTags.assertThat().entriesListIsNotEmpty()
|
||||
.assertThat().entriesListDoesNotContain(FIELD_COUNT)
|
||||
.assertThat().entriesListContains(FIELD_TAG)
|
||||
.assertThat().entriesListContains(FIELD_ID);
|
||||
.and().entriesListDoesNotContain("tag", removedTag.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -22,69 +26,38 @@ public class TagsDataPrep extends RestTest
|
||||
protected static ListUserWithRoles usersWithRoles;
|
||||
protected static SiteModel siteModel;
|
||||
protected static FileModel document;
|
||||
protected static FolderModel folder, folder2;
|
||||
protected static RestTagModelsCollection folder2tags;
|
||||
protected static FolderModel folder;
|
||||
protected static String documentTagValue, documentTagValue2, folderTagValue;
|
||||
protected static RestTagModel documentTag, documentTag2, folderTag, orphanTag, returnedModel;
|
||||
protected static RestTagModel documentTag, documentTag2, folderTag, returnedModel;
|
||||
protected static RestTagModelsCollection returnedCollection;
|
||||
|
||||
@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);
|
||||
document = dataContent.usingUser(adminUserModel).usingSite(siteModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
folder = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
folder2 = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
|
||||
documentTagValue = RandomData.getRandomName("tag").toLowerCase();
|
||||
documentTagValue2 = RandomData.getRandomName("tag").toLowerCase();
|
||||
folderTagValue = RandomData.getRandomName("tag").toLowerCase();
|
||||
documentTagValue = RandomData.getRandomName("tag");
|
||||
documentTagValue2 = RandomData.getRandomName("tag");
|
||||
folderTagValue = RandomData.getRandomName("tag");
|
||||
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
documentTag = restClient.withCoreAPI().usingResource(document).addTag(documentTagValue);
|
||||
documentTag2 = restClient.withCoreAPI().usingResource(document).addTag(documentTagValue2);
|
||||
folderTag = restClient.withCoreAPI().usingResource(folder).addTag(folderTagValue);
|
||||
orphanTag = restClient.withCoreAPI().createSingleTag(RestTagModel.builder().tag(RandomData.getRandomName("orphan-tag").toLowerCase()).create());
|
||||
folder2tags = restClient.withCoreAPI().usingResource(folder2).addTags(folderTagValue, documentTagValue);
|
||||
|
||||
// Allow indexing to complete.
|
||||
Utility.sleep(500, 60000, () ->
|
||||
{
|
||||
returnedCollection = restClient.withParams("maxItems=10000", "where=(tag MATCHES ('*tag*'))")
|
||||
.withCoreAPI().getTags();
|
||||
returnedCollection.assertThat().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2)
|
||||
.and().entriesListContains("tag", folderTagValue)
|
||||
.and().entriesListContains("tag", orphanTag.getTag());
|
||||
});
|
||||
}
|
||||
{
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
returnedCollection.assertThat().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase())
|
||||
.and().entriesListContains("tag", folderTagValue.toLowerCase());
|
||||
});
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
protected RestTagModel createTagModelWithName(final String tagName)
|
||||
{
|
||||
return RestTagModel.builder().tag(tagName).create();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package org.alfresco.rest.tags;
|
||||
|
||||
import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import org.alfresco.rest.model.RestErrorModel;
|
||||
import org.alfresco.rest.model.RestTagModel;
|
||||
import org.alfresco.utility.Utility;
|
||||
@@ -16,7 +13,6 @@ import org.alfresco.utility.testrail.annotation.TestRail;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Ignore;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
@@ -29,29 +25,28 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
private String randomTag = "";
|
||||
|
||||
@BeforeMethod(alwaysRun=true)
|
||||
public void addTagToDocument()
|
||||
public void addTagToDocument() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
oldTag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("old").toLowerCase());
|
||||
randomTag = RandomData.getRandomName("tag").toLowerCase();
|
||||
oldTag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("old"));
|
||||
randomTag = RandomData.getRandomName("tag");
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, description = "Verify Admin user updates tags and status code is 200")
|
||||
@Bug(id="REPO-1828")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void adminIsAbleToUpdateTags()
|
||||
public void adminIsAbleToUpdateTags() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedModel.assertThat().field("tag").is(randomTag);
|
||||
returnedModel.assertThat().field("id").isNotNull();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API,
|
||||
TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify Manager user can't update tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void managerIsNotAbleToUpdateTag()
|
||||
public void managerIsNotAbleToUpdateTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
@@ -61,7 +56,7 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Collaborator user can't update tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsNotAbleToUpdateTagCheckDefaultErrorModelSchema()
|
||||
public void collaboratorIsNotAbleToUpdateTagCheckDefaultErrorModelSchema() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
@@ -74,7 +69,7 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Contributor user can't update tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsNotAbleToUpdateTag()
|
||||
public void contributorIsNotAbleToUpdateTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor));
|
||||
restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
@@ -84,7 +79,7 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.SANITY, description = "Verify Consumer user can't update tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToUpdateTag()
|
||||
public void consumerIsNotAbleToUpdateTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer));
|
||||
restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
@@ -95,7 +90,7 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
executionType = ExecutionType.SANITY, description = "Verify user gets status code 401 if authentication call fails")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void userIsNotAbleToUpdateTagIfAuthenticationFails()
|
||||
public void userIsNotAbleToUpdateTagIfAuthenticationFails() throws Exception
|
||||
{
|
||||
UserModel siteManager = usersWithRoles.getOneUserWithRole(UserRole.SiteManager);
|
||||
String managerPassword = siteManager.getPassword();
|
||||
@@ -108,140 +103,118 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify admin is not able to update tag with invalid id")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidId()
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidId() throws Exception
|
||||
{
|
||||
String invalidTagId = "invalid-id";
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag").toLowerCase());
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
tag.setId(invalidTagId);
|
||||
restClient.withCoreAPI().usingTag(tag).update(RandomData.getRandomName("tag").toLowerCase());
|
||||
restClient.withCoreAPI().usingTag(tag).update(RandomData.getRandomName("tag"));
|
||||
restClient.assertStatusCodeIs(HttpStatus.NOT_FOUND)
|
||||
.assertLastError().containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, invalidTagId));
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify admin is not able to update tag with empty id")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsNotAbleToUpdateTagWithEmptyId()
|
||||
public void adminIsNotAbleToUpdateTagWithEmptyId() throws Exception
|
||||
{
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag").toLowerCase());
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
tag.setId("");
|
||||
restClient.withCoreAPI().usingTag(tag).update(RandomData.getRandomName("tag").toLowerCase());
|
||||
restClient.withCoreAPI().usingTag(tag).update(RandomData.getRandomName("tag"));
|
||||
restClient.assertStatusCodeIs(HttpStatus.METHOD_NOT_ALLOWED)
|
||||
.assertLastError().containsSummary(RestErrorModel.PUT_EMPTY_ARGUMENT);
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify admin is not able to update tag with invalid body")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsNotAbleToUpdateTagWithEmptyBody()
|
||||
public void adminIsNotAbleToUpdateTagWithEmptyBody() throws Exception
|
||||
{
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag").toLowerCase());
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
restClient.withCoreAPI().usingTag(tag).update("");
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary(RestErrorModel.BLANK_TAG);
|
||||
.assertLastError().containsSummary(RestErrorModel.EMPTY_TAG);
|
||||
}
|
||||
|
||||
@Bug(id="ACE-5629")
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin is not able to update tag with invalid body containing '|' symbol")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Ignore
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidBodyScenario1()
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidBodyScenario1() throws Exception
|
||||
{
|
||||
String invalidTagBody = "|.\"/<>*";
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag").toLowerCase());
|
||||
try
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
Utility.sleep(500, 20000, () ->
|
||||
{
|
||||
Utility.sleep(500, 20000, () ->
|
||||
{
|
||||
restClient.withCoreAPI().usingTag(tag).update(invalidTagBody);
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary(String.format(RestErrorModel.INVALID_TAG, invalidTagBody));
|
||||
});
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
fail("Test interrupted while waiting for error status code.");
|
||||
}
|
||||
restClient.withCoreAPI().usingTag(tag).update(invalidTagBody);
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary(String.format(RestErrorModel.INVALID_TAG, invalidTagBody));
|
||||
});
|
||||
}
|
||||
|
||||
@Bug(id="ACE-5629")
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin is not able to update tag with invalid body without '|' symbol")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Ignore
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidBodyScenario2()
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidBodyScenario2() throws Exception
|
||||
{
|
||||
String invalidTagBody = ".\"/<>*";
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
try
|
||||
{
|
||||
Utility.sleep(500, 20000, () ->
|
||||
{
|
||||
restClient.withCoreAPI().usingTag(tag).update(invalidTagBody);
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
restClient.withCoreAPI().usingTag(tag).update(invalidTagBody);
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary(String.format(RestErrorModel.INVALID_TAG, invalidTagBody));
|
||||
});
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
fail("Test interrupted while waiting for error status code.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin user can provide large string for new tag value.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
@Ignore
|
||||
public void adminIsAbleToUpdateTagsProvideLargeStringTag()
|
||||
public void adminIsAbleToUpdateTagsProvideLargeStringTag() throws Exception
|
||||
{
|
||||
String largeStringTag = RandomStringUtils.randomAlphanumeric(10000).toLowerCase();
|
||||
String largeStringTag = RandomStringUtils.randomAlphanumeric(10000);
|
||||
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(largeStringTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedModel.assertThat().field("tag").is(largeStringTag);
|
||||
returnedModel.assertThat().field("id").isNotNull();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin user can provide short string for new tag value.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
public void adminIsAbleToUpdateTagsProvideShortStringTag()
|
||||
public void adminIsAbleToUpdateTagsProvideShortStringTag() throws Exception
|
||||
{
|
||||
String shortStringTag = RandomStringUtils.randomAlphanumeric(2).toLowerCase();
|
||||
String shortStringTag = RandomStringUtils.randomAlphanumeric(2);
|
||||
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(shortStringTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedModel.assertThat().field("tag").is(shortStringTag);
|
||||
returnedModel.assertThat().field("id").isNotNull();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin user can provide string with special chars for new tag value.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
@Ignore
|
||||
public void adminIsAbleToUpdateTagsProvideSpecialCharsStringTag()
|
||||
public void adminIsAbleToUpdateTagsProvideSpecialCharsStringTag() throws Exception
|
||||
{
|
||||
String specialCharsString = RandomData.getRandomName("!@#$%^&*()'\".,<>-_+=|\\").toLowerCase();
|
||||
String specialCharsString = "!@#$%^&*()'\".,<>-_+=|\\";
|
||||
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(specialCharsString);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedModel.assertThat().field("tag").is(specialCharsString);
|
||||
returnedModel.assertThat().field("id").isNotNull();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Admin user can provide existing tag for new tag value.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
@Ignore
|
||||
public void adminIsAbleToUpdateTagsProvideExistingTag()
|
||||
public void adminIsAbleToUpdateTagsProvideExistingTag() throws Exception
|
||||
{
|
||||
String existingTag = RandomData.getRandomName("oldTag").toLowerCase();
|
||||
String existingTag = "oldTag";
|
||||
RestTagModel oldExistingTag = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
|
||||
.withCoreAPI().usingResource(document).addTag(existingTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
@@ -250,43 +223,38 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
returnedModel = restClient.withCoreAPI().usingTag(oldExistingTag).update(existingTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedModel.assertThat().field("tag").is(existingTag);
|
||||
returnedModel.assertThat().field("id").isNotNull();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Admin user can delete a tag, add tag and update it.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
@Ignore
|
||||
public void adminDeleteTagAddTagUpdateTag()
|
||||
public void adminDeleteTagAddTagUpdateTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel)
|
||||
.withCoreAPI().usingResource(document).deleteTag(oldTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.NO_CONTENT);
|
||||
|
||||
String newTag = RandomData.getRandomName("addTag").toLowerCase();
|
||||
String newTag = "addTag";
|
||||
RestTagModel newTagModel = restClient.withCoreAPI().usingResource(document).addTag(newTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
|
||||
returnedModel = restClient.withCoreAPI().usingTag(newTagModel).update(newTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedModel.assertThat().field("tag").is(newTag);
|
||||
returnedModel.assertThat().field("id").isNotNull();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Admin user can update a tag, delete tag and add it.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
@Ignore
|
||||
public void adminUpdateTagDeleteTagAddTag()
|
||||
public void adminUpdateTagDeleteTagAddTag() throws Exception
|
||||
{
|
||||
String newTag = RandomData.getRandomName("addTag").toLowerCase();
|
||||
String newTag = "addTag";
|
||||
|
||||
returnedModel = restClient.authenticateUser(adminUserModel).withCoreAPI().usingTag(oldTag).update(newTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedModel.assertThat().field("tag").is(newTag);
|
||||
returnedModel.assertThat().field("id").isNotNull();
|
||||
|
||||
restClient.withCoreAPI().usingResource(document).deleteTag(returnedModel);
|
||||
restClient.assertStatusCodeIs(HttpStatus.NO_CONTENT);
|
||||
@@ -294,35 +262,4 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
restClient.withCoreAPI().usingResource(document).addTag(newTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify Admin user updates orphan tags and status code is 200")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void adminIsAbleToUpdateOrphanTag()
|
||||
{
|
||||
STEP("Update orphan tag and expect 200");
|
||||
final String newTagName = RandomData.getRandomName("new").toLowerCase();
|
||||
returnedModel = restClient.authenticateUser(adminUserModel).withCoreAPI().usingTag(orphanTag).update(newTagName);
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
RestTagModel expected = RestTagModel.builder().id(orphanTag.getId()).tag(newTagName).create();
|
||||
returnedModel.assertThat().isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test (groups = { TestGroup.REST_API, TestGroup.TAGS })
|
||||
public void canUpdateTagAndGetCount()
|
||||
{
|
||||
STEP("Create an orphaned tag");
|
||||
String tagName = RandomData.getRandomName("tag").toLowerCase();
|
||||
RestTagModel createdTag = RestTagModel.builder().tag(tagName).create();
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().createSingleTag(createdTag);
|
||||
|
||||
STEP("Update tag and request the count field");
|
||||
String newTagName = RandomData.getRandomName("new").toLowerCase();
|
||||
returnedModel = restClient.authenticateUser(adminUserModel).withCoreAPI().include("count").usingTag(tag).update(newTagName);
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
RestTagModel expected = RestTagModel.builder().id(tag.getId()).tag(newTagName).count(0).create();
|
||||
returnedModel.assertThat().isEqualTo(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,13 +33,13 @@ public class AddTagTests extends TagsDataPrep
|
||||
@BeforeMethod(alwaysRun = true)
|
||||
public void generateRandomTag()
|
||||
{
|
||||
tagValue = RandomData.getRandomName("tag").toLowerCase();
|
||||
tagValue = RandomData.getRandomName("tag");
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin user adds tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsAbleToAddTag()
|
||||
public void adminIsAbleToAddTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -51,7 +51,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify Manager user adds tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void managerIsAbleToTagAFile()
|
||||
public void managerIsAbleToTagAFile() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -63,7 +63,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Collaborator user adds tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsAbleToTagAFile()
|
||||
public void collaboratorIsAbleToTagAFile() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -75,7 +75,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user doesn't have permission to add tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsNotAbleToAddTagToAnotherContent()
|
||||
public void contributorIsNotAbleToAddTagToAnotherContent() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor));
|
||||
restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -85,7 +85,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user adds tags to his content with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsAbleToAddTagToHisContent()
|
||||
public void contributorIsAbleToAddTagToHisContent() throws Exception
|
||||
{
|
||||
userModel = usersWithRoles.getOneUserWithRole(UserRole.SiteContributor);
|
||||
restClient.authenticateUser(userModel);
|
||||
@@ -99,7 +99,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Consumer user doesn't have permission to add tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToTagAFile()
|
||||
public void consumerIsNotAbleToTagAFile() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer));
|
||||
restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -110,7 +110,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
description = "Verify user gets status code 401 if authentication call fails")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void userIsNotAbleToAddTagIfAuthenticationFails()
|
||||
public void userIsNotAbleToAddTagIfAuthenticationFails() throws Exception
|
||||
{
|
||||
UserModel siteManager = usersWithRoles.getOneUserWithRole(UserRole.SiteManager);
|
||||
String managerPassword = siteManager.getPassword();
|
||||
@@ -124,7 +124,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that adding empty tag returns status code 400")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void emptyTagTest()
|
||||
public void emptyTagTest() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag("");
|
||||
@@ -134,7 +134,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that adding tag with user that has no permissions returns status code 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagWithUserThatDoesNotHavePermissions()
|
||||
public void addTagWithUserThatDoesNotHavePermissions() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(dataUser.createRandomTestUser());
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -144,7 +144,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that adding tag to a node that does not exist returns status code 404")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToInexistentNode()
|
||||
public void addTagToInexistentNode() throws Exception
|
||||
{
|
||||
String oldNodeRef = document.getNodeRef();
|
||||
String nodeRef = RandomStringUtils.randomAlphanumeric(10);
|
||||
@@ -159,7 +159,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify that manager is able to tag a folder")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void managerIsAbleToTagAFolder()
|
||||
public void managerIsAbleToTagAFolder() throws Exception
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
@@ -171,7 +171,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that tagged file can be tagged again")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToATaggedFile()
|
||||
public void addTagToATaggedFile() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
|
||||
@@ -195,7 +195,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that user cannot add invalid tag")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addInvalidTag()
|
||||
public void addInvalidTag() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag("-1~!|@#$%^&*()_=");
|
||||
@@ -205,7 +205,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that contributor is able to tag a folder created by self")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsAbleToTagAFolderCreatedBySelf()
|
||||
public void contributorIsAbleToTagAFolderCreatedBySelf() throws Exception
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(siteModel).createFolder();
|
||||
|
||||
@@ -218,7 +218,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that collaborator is able to tag a folder")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsAbleToTagAFolder()
|
||||
public void collaboratorIsAbleToTagAFolder() throws Exception
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
|
||||
@@ -231,7 +231,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that consumer is not able to tag a folder. Check default error model schema.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToTagAFolder()
|
||||
public void consumerIsNotAbleToTagAFolder() throws Exception
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
|
||||
@@ -246,7 +246,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that tagged folder can be tagged again")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToATaggedFolder()
|
||||
public void addTagToATaggedFolder() throws Exception
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
|
||||
@@ -269,11 +269,11 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Using collaborator provide more than one tag element")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void provideMoreThanOneTagElement()
|
||||
public void provideMoreThanOneTagElement() throws Exception
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
String tagValue1 = RandomData.getRandomName("tag1").toLowerCase();
|
||||
String tagValue2 = RandomData.getRandomName("tag2").toLowerCase();
|
||||
String tagValue1 = RandomData.getRandomName("tag1");
|
||||
String tagValue2 = RandomData.getRandomName("tag2");
|
||||
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
|
||||
@@ -288,7 +288,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that manager cannot add tag with special characters.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagWithSpecialCharacters()
|
||||
public void addTagWithSpecialCharacters() throws Exception
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
String specialCharsTag = "!@#$%^&*()'\".,<>-_+=|\\";
|
||||
@@ -301,7 +301,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that you cannot tag a comment and it returns status code 405")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToAComment()
|
||||
public void addTagToAComment() throws Exception
|
||||
{
|
||||
FileModel file = dataContent.usingSite(siteModel).usingUser(adminUserModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
String comment = "comment for a tag";
|
||||
@@ -316,7 +316,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that you cannot tag a tag and it returns status code 405")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToATag()
|
||||
public void addTagToATag() throws Exception
|
||||
{
|
||||
FileModel file = dataContent.usingSite(siteModel).usingUser(adminUserModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
|
||||
@@ -326,17 +326,4 @@ public class AddTagTests extends TagsDataPrep
|
||||
restClient.withCoreAPI().usingResource(file).addTag(tagValue);
|
||||
restClient.assertStatusCodeIs(HttpStatus.METHOD_NOT_ALLOWED).assertLastError().containsSummary(RestErrorModel.CANNOT_TAG);
|
||||
}
|
||||
|
||||
@TestRail (section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify the tag name is converted to lower case before being applied")
|
||||
@Test (groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void tagNameIsConvertedToLowerCase()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
String tagName = RandomData.getRandomName("TaG-oNe");
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagName);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
returnedModel.assertThat().field("tag").is(tagName.toLowerCase())
|
||||
.and().field("id").isNotEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,14 +30,14 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@BeforeMethod(alwaysRun = true)
|
||||
public void generateRandomTagsList()
|
||||
{
|
||||
tag1 = RandomData.getRandomName("tag").toLowerCase();
|
||||
tag2 = RandomData.getRandomName("tag").toLowerCase();
|
||||
tag1 = RandomData.getRandomName("tag");
|
||||
tag2 = RandomData.getRandomName("tag");
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin user adds multiple tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsAbleToAddTags()
|
||||
public void adminIsAbleToAddTags() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedCollection = restClient.withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
@@ -49,7 +49,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify Manager user adds multiple tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void managerIsAbleToAddTags()
|
||||
public void managerIsAbleToAddTags() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
returnedCollection = restClient.withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
@@ -61,7 +61,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.SANITY, description = "Verify Collaborator user adds multiple tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsAbleToAddTags()
|
||||
public void collaboratorIsAbleToAddTags() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
returnedCollection = restClient.withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
@@ -73,7 +73,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user doesn't have permission to add multiple tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsNotAbleToAddTagsToAnotherContent()
|
||||
public void contributorIsNotAbleToAddTagsToAnotherContent() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor));
|
||||
restClient.withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
@@ -83,7 +83,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user adds multiple tags to his content with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsAbleToAddTagsToHisContent()
|
||||
public void contributorIsAbleToAddTagsToHisContent() throws Exception
|
||||
{
|
||||
userModel = usersWithRoles.getOneUserWithRole(UserRole.SiteContributor);
|
||||
restClient.authenticateUser(userModel);
|
||||
@@ -97,7 +97,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Consumer user doesn't have permission to add multiple tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToAddTags()
|
||||
public void consumerIsNotAbleToAddTags() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
restClient.assertStatusCodeIs(HttpStatus.FORBIDDEN).assertLastError().containsSummary(RestErrorModel.PERMISSION_WAS_DENIED);
|
||||
@@ -107,7 +107,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
description = "Verify user gets status code 401 if authentication call fails")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void userIsNotAbleToAddTagsIfAuthenticationFails()
|
||||
public void userIsNotAbleToAddTagsIfAuthenticationFails() throws Exception
|
||||
{
|
||||
UserModel siteManager = usersWithRoles.getOneUserWithRole(UserRole.SiteManager);
|
||||
String managerPassword = siteManager.getPassword();
|
||||
@@ -120,7 +120,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API,
|
||||
TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify include count parameter")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void getTagsUsingCountParam()
|
||||
public void getTagsUsingCountParam() throws Exception
|
||||
{
|
||||
FileModel file = dataContent.usingSite(siteModel).usingUser(adminUserModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
String tagName = RandomData.getRandomName("tag");
|
||||
@@ -139,4 +139,4 @@ public class AddTagsTests extends TagsDataPrep
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ import org.alfresco.utility.testrail.ExecutionType;
|
||||
import org.alfresco.utility.testrail.annotation.TestRail;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.Ignore;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
@@ -30,7 +29,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Admin user deletes tags with Rest API and status code is 204")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsAbleToDeleteTags()
|
||||
public void adminIsAbleToDeleteTags() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -44,7 +43,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify Manager user deletes tags created by admin user with Rest API and status code is 204")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void managerIsAbleToDeleteTags()
|
||||
public void managerIsAbleToDeleteTags() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -57,7 +56,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Collaborator user deletes tags created by admin user with Rest API and status code is 204")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsAbleToDeleteTags()
|
||||
public void collaboratorIsAbleToDeleteTags() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -70,7 +69,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user can't delete tags created by admin user with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsNotAbleToDeleteTagsForAnotherUserContent()
|
||||
public void contributorIsNotAbleToDeleteTagsForAnotherUserContent() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -83,7 +82,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user deletes tags created by him with Rest API and status code is 204")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsAbleToDeleteTagsForHisContent()
|
||||
public void contributorIsAbleToDeleteTagsForHisContent() throws Exception
|
||||
{
|
||||
userModel = usersWithRoles.getOneUserWithRole(UserRole.SiteContributor);
|
||||
restClient.authenticateUser(userModel);
|
||||
@@ -97,7 +96,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Consumer user can't delete tags created by admin user with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToDeleteTags()
|
||||
public void consumerIsNotAbleToDeleteTags() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -111,7 +110,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
description = "Verify user gets status code 401 if authentication call fails")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void userIsNotAbleToDeleteTagIfAuthenticationFails()
|
||||
public void userIsNotAbleToDeleteTagIfAuthenticationFails() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -128,7 +127,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if user has no permission to remove tag returned status code is 403. Check default error model schema")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteTagWithUserWithoutPermissionCheckDefaultErrorModelSchema()
|
||||
public void deleteTagWithUserWithoutPermissionCheckDefaultErrorModelSchema() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
RestTagModel tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -145,7 +144,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if node does not exist returned status code is 404")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteTagForANonexistentNode()
|
||||
public void deleteTagForANonexistentNode() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
RestTagModel tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -160,7 +159,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if tag does not exist returned status code is 404")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteTagThatDoesNotExist()
|
||||
public void deleteTagThatDoesNotExist() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
RestTagModel tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -173,7 +172,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if tag id is empty returned status code is 405")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteTagWithEmptyId()
|
||||
public void deleteTagWithEmptyId() throws Exception
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
RestTagModel tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -186,7 +185,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that folder tag can be deleted")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteFolderTag()
|
||||
public void deleteFolderTag() throws Exception
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();;
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
@@ -201,8 +200,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Manager user can't delete deleted tag.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id = "ACE-5455")
|
||||
@Ignore
|
||||
public void managerCannotDeleteDeletedTag()
|
||||
public void managerCannotDeleteDeletedTag() throws Exception
|
||||
{
|
||||
tag = restClient.authenticateUser(adminUserModel)
|
||||
.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -218,7 +216,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Collaborator user can delete long tag.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void userCollaboratorCanDeleteLongTag()
|
||||
public void userCollaboratorCanDeleteLongTag() throws Exception
|
||||
{
|
||||
String longTag = RandomStringUtils.randomAlphanumeric(800);
|
||||
|
||||
@@ -233,7 +231,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Manager user can delete short tag.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void managerCanDeleteShortTag()
|
||||
public void managerCanDeleteShortTag() throws Exception
|
||||
{
|
||||
String shortTag = RandomStringUtils.randomAlphanumeric(10);
|
||||
|
||||
@@ -248,7 +246,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Admin can delete tag then add it again.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminRemovesTagAndAddsItAgain()
|
||||
public void adminRemovesTagAndAddsItAgain() throws Exception
|
||||
{
|
||||
String tagValue = RandomStringUtils.randomAlphanumeric(10);
|
||||
|
||||
@@ -269,7 +267,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Manager user can delete tag added by another user.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void managerCanDeleteTagAddedByAnotherUser()
|
||||
public void managerCanDeleteTagAddedByAnotherUser() throws Exception
|
||||
{
|
||||
tag = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
|
||||
.withCoreAPI().usingResource(document).addTag(RandomStringUtils.randomAlphanumeric(10));
|
||||
@@ -278,4 +276,4 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
.withCoreAPI().usingResource(document).deleteTag(tag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,6 +150,18 @@ public class GetNodeTagsTests extends TagsDataPrep
|
||||
restClient.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError().containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, nodeRef));
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if node id is empty returns status code 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION})
|
||||
public void emptyNodeIdTest() throws Exception
|
||||
{
|
||||
FileModel badDocument = dataContent.usingSite(siteModel).usingUser(adminUserModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
badDocument.setNodeRef("");
|
||||
|
||||
restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(badDocument).getNodeTags();
|
||||
restClient.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError().containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, ""));
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify folder tags")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION})
|
||||
@@ -291,4 +303,4 @@ public class GetNodeTagsTests extends TagsDataPrep
|
||||
.and().field("skipCount").is("10000");
|
||||
returnedCollection.assertThat().entriesListCountIs(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
70
pom.xml
70
pom.xml
@@ -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.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Alfresco Community Repo Parent</name>
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
<build-number>local</build-number>
|
||||
<image.tag>latest</image.tag>
|
||||
<image.registry>quay.io</image.registry>
|
||||
<builder.name>entitled-builder</builder.name>
|
||||
<local.registry>127.0.0.1:5000</local.registry>
|
||||
|
||||
<java.version>11</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
@@ -47,26 +45,26 @@
|
||||
|
||||
<dependency.alfresco-hb-data-sender.version>1.0.12</dependency.alfresco-hb-data-sender.version>
|
||||
<dependency.alfresco-trashcan-cleaner.version>2.4.1</dependency.alfresco-trashcan-cleaner.version>
|
||||
<dependency.alfresco-jlan.version>7.4</dependency.alfresco-jlan.version>
|
||||
<dependency.alfresco-jlan.version>7.2</dependency.alfresco-jlan.version>
|
||||
<dependency.alfresco-server-root.version>6.0.1</dependency.alfresco-server-root.version>
|
||||
<dependency.alfresco-messaging-repo.version>1.2.20</dependency.alfresco-messaging-repo.version>
|
||||
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
|
||||
<dependency.activiti.version>5.23.0</dependency.activiti.version>
|
||||
<dependency.alfresco-transform-service.version>2.1.0-A9</dependency.alfresco-transform-service.version>
|
||||
<dependency.alfresco-transform-core.version>3.1.0-A12</dependency.alfresco-transform-core.version>
|
||||
<dependency.alfresco-transform-service.version>2.0.0</dependency.alfresco-transform-service.version>
|
||||
<dependency.alfresco-transform-core.version>3.0.0</dependency.alfresco-transform-core.version>
|
||||
<dependency.alfresco-greenmail.version>6.5</dependency.alfresco-greenmail.version>
|
||||
<dependency.acs-event-model.version>0.0.18</dependency.acs-event-model.version>
|
||||
|
||||
<dependency.spring.version>5.3.27</dependency.spring.version>
|
||||
<dependency.spring.version>5.3.25</dependency.spring.version>
|
||||
<dependency.antlr.version>3.5.3</dependency.antlr.version>
|
||||
<dependency.jackson.version>2.15.0-rc1</dependency.jackson.version>
|
||||
<dependency.jackson.version>2.14.0</dependency.jackson.version>
|
||||
<dependency.cxf.version>3.5.5</dependency.cxf.version>
|
||||
<dependency.opencmis.version>1.0.0</dependency.opencmis.version>
|
||||
<dependency.webscripts.version>8.40</dependency.webscripts.version>
|
||||
<dependency.webscripts.version>8.33</dependency.webscripts.version>
|
||||
<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>
|
||||
@@ -76,19 +74,20 @@
|
||||
<dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version>
|
||||
<dependency.slf4j.version>2.0.3</dependency.slf4j.version>
|
||||
<dependency.log4j.version>2.19.0</dependency.log4j.version>
|
||||
<dependency.gytheio.version>0.18</dependency.gytheio.version>
|
||||
<dependency.groovy.version>3.0.16</dependency.groovy.version>
|
||||
<dependency.gytheio.version>0.17</dependency.gytheio.version>
|
||||
<dependency.groovy.version>3.0.12</dependency.groovy.version>
|
||||
<dependency.tika.version>2.4.1</dependency.tika.version>
|
||||
<dependency.spring-security.version>5.8.2</dependency.spring-security.version>
|
||||
<dependency.spring-security.version>5.7.5</dependency.spring-security.version>
|
||||
<dependency.truezip.version>7.7.10</dependency.truezip.version>
|
||||
<dependency.poi.version>5.2.2</dependency.poi.version>
|
||||
<dependency.poi-ooxml-lite.version>5.2.3</dependency.poi-ooxml-lite.version>
|
||||
<dependency.keycloak.version>18.0.0</dependency.keycloak.version>
|
||||
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
|
||||
<dependency.camel.version>3.20.2</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies -->
|
||||
<dependency.netty.version>4.1.87.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
|
||||
<dependency.netty.qpid.version>4.1.82.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.56.Final</dependency.netty-tcnative.version> <!-- must be in sync with camels transitive dependencies -->
|
||||
<dependency.activemq.version>5.17.4</dependency.activemq.version>
|
||||
<dependency.camel.version>3.18.2</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies -->
|
||||
<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.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>
|
||||
@@ -107,12 +106,11 @@
|
||||
<dependency.jakarta-jws-api.version>2.1.0</dependency.jakarta-jws-api.version>
|
||||
<dependency.jakarta-mail-api.version>1.6.5</dependency.jakarta-mail-api.version>
|
||||
<dependency.jakarta-json-api.version>1.1.6</dependency.jakarta-json-api.version>
|
||||
<dependency.jakarta-json-path.version>2.8.0</dependency.jakarta-json-path.version>
|
||||
<dependency.json-smart.version>2.4.10</dependency.json-smart.version>
|
||||
<dependency.jakarta-json-path.version>2.7.0</dependency.jakarta-json-path.version>
|
||||
<dependency.jakarta-rpc-api.version>1.1.4</dependency.jakarta-rpc-api.version>
|
||||
|
||||
<alfresco.googledrive.version>3.4.0-A4</alfresco.googledrive.version>
|
||||
<alfresco.aos-module.version>1.6.0-A5</alfresco.aos-module.version>
|
||||
<alfresco.googledrive.version>3.4.0-M1</alfresco.googledrive.version>
|
||||
<alfresco.aos-module.version>1.6.0-M1</alfresco.aos-module.version>
|
||||
<alfresco.api-explorer.version>7.3.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
|
||||
|
||||
<alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
|
||||
@@ -122,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>4.0.0</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>
|
||||
@@ -150,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.155</tag>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
@@ -241,17 +239,6 @@
|
||||
<version>${dependency.jakarta-json-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
<version>${dependency.jakarta-json-path.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId> net.minidev</groupId>
|
||||
<artifactId>json-smart</artifactId>
|
||||
<version>${dependency.json-smart.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.rpc</groupId>
|
||||
<artifactId>jakarta.xml.rpc-api</artifactId>
|
||||
@@ -397,7 +384,7 @@
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>1.5</version>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -529,7 +516,7 @@
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>2.0</version>
|
||||
<version>1.32</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
@@ -912,13 +899,6 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-bom</artifactId>
|
||||
<version>${dependency.spring-security.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@@ -936,7 +916,7 @@
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<version>0.42.1</version>
|
||||
<version>0.40.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.155</version>
|
||||
<version>20.79-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -39,8 +39,6 @@ import org.alfresco.rest.api.model.LockInfo;
|
||||
import org.alfresco.rest.api.model.Node;
|
||||
import org.alfresco.rest.api.model.PathInfo;
|
||||
import org.alfresco.rest.api.model.UserInfo;
|
||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
@@ -210,19 +208,6 @@ public interface Nodes
|
||||
NodeRef validateNode(StoreRef storeRef, String nodeId);
|
||||
NodeRef validateNode(String nodeId);
|
||||
NodeRef validateNode(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Check that the specified id refers to a valid node.
|
||||
*
|
||||
* @param nodeId The node id to look up using SpacesStore or an alias like -root-.
|
||||
* @return The node ref.
|
||||
* @throws InvalidArgumentException if the specified node id is not a valid format.
|
||||
* @throws EntityNotFoundException if the specified node was not found in the database.
|
||||
*/
|
||||
default NodeRef validateOrLookupNode(String nodeId)
|
||||
{
|
||||
return validateOrLookupNode(nodeId, null);
|
||||
}
|
||||
NodeRef validateOrLookupNode(String nodeId, String path);
|
||||
|
||||
boolean nodeMatches(NodeRef nodeRef, Set<QName> expectedTypes, Set<QName> excludedTypes);
|
||||
|
||||
@@ -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, Parameters parameters);
|
||||
Tag getTag(StoreRef storeRef, String tagId, Parameters parameters);
|
||||
void deleteTag(String nodeId, String tagId);
|
||||
CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Parameters params);
|
||||
Tag changeTag(StoreRef storeRef, String tagId, Tag tag, Parameters parameters);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,110 +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));
|
||||
}
|
||||
|
||||
if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH))
|
||||
{
|
||||
category.setPath(getCategoryPath(category));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH))
|
||||
{
|
||||
category.setPath(getCategoryPath(category));
|
||||
}
|
||||
})
|
||||
.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()
|
||||
final NodeRef parentNodeRef = getCategoryNodeRef(parentCategoryId);
|
||||
final List<ChildAssociationRef> childCategoriesAssocs = nodeService.getChildAssocs(parentNodeRef).stream()
|
||||
.filter(ca -> ContentModel.ASSOC_SUBCATEGORIES.equals(ca.getTypeQName()))
|
||||
.map(ChildAssociationRef::getChildRef)
|
||||
.map(this::mapToCategory)
|
||||
.peek(category -> {
|
||||
if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH))
|
||||
{
|
||||
category.setPath(getCategoryPath(category));
|
||||
}
|
||||
})
|
||||
.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 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));
|
||||
}
|
||||
|
||||
if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH))
|
||||
{
|
||||
category.setPath(getCategoryPath(category));
|
||||
}
|
||||
|
||||
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});
|
||||
@@ -208,9 +161,9 @@ 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.validateOrLookupNode(nodeId);
|
||||
final NodeRef contentNodeRef = nodes.validateNode(nodeId);
|
||||
verifyReadPermission(contentNodeRef);
|
||||
verifyNodeType(contentNodeRef);
|
||||
|
||||
@@ -221,27 +174,18 @@ public class CategoriesImpl implements Categories
|
||||
}
|
||||
final Collection<NodeRef> actualCategories = DefaultTypeConverter.INSTANCE.getCollection(NodeRef.class, currentCategories);
|
||||
|
||||
return actualCategories
|
||||
.stream()
|
||||
.map(this::mapToCategory)
|
||||
.peek(category -> {
|
||||
if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH))
|
||||
{
|
||||
category.setPath(getCategoryPath(category));
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return actualCategories.stream().map(this::mapToCategory).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@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))
|
||||
{
|
||||
throw new InvalidArgumentException(NOT_A_VALID_CATEGORY);
|
||||
}
|
||||
|
||||
final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId);
|
||||
final NodeRef contentNodeRef = nodes.validateNode(nodeId);
|
||||
verifyChangePermission(contentNodeRef);
|
||||
verifyNodeType(contentNodeRef);
|
||||
|
||||
@@ -250,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))
|
||||
@@ -260,23 +204,14 @@ public class CategoriesImpl implements Categories
|
||||
|
||||
linkNodeToCategories(contentNodeRef, categoryNodeRefs);
|
||||
|
||||
return categoryNodeRefs
|
||||
.stream()
|
||||
.map(this::mapToCategory)
|
||||
.peek(category -> {
|
||||
if (parameters.getInclude().contains(Nodes.PARAM_INCLUDE_PATH))
|
||||
{
|
||||
category.setPath(getCategoryPath(category));
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return categoryNodeRefs.stream().map(this::mapToCategory).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@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 contentNodeRef = nodes.validateOrLookupNode(nodeId);
|
||||
final NodeRef categoryNodeRef = getCategoryNodeRef(categoryId);
|
||||
final NodeRef contentNodeRef = nodes.validateNode(nodeId);
|
||||
verifyChangePermission(contentNodeRef);
|
||||
verifyNodeType(contentNodeRef);
|
||||
|
||||
@@ -337,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);
|
||||
}
|
||||
@@ -500,30 +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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path for a given category in human-readable form.
|
||||
*
|
||||
* @param category Category to provide path for.
|
||||
* @return Path for a category in human-readable form.
|
||||
*/
|
||||
private String getCategoryPath(final Category category)
|
||||
{
|
||||
final NodeRef categoryNodeRef = nodes.getNode(category.getId()).getNodeRef();
|
||||
return nodeService.getPath(categoryNodeRef).toDisplayPath(nodeService, permissionService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1356,7 +1356,7 @@ public class NodesImpl implements Nodes
|
||||
|
||||
private void calculateRelativePath(String parentFolderNodeId, Node node)
|
||||
{
|
||||
NodeRef rootNodeRef = validateOrLookupNode(parentFolderNodeId);
|
||||
NodeRef rootNodeRef = validateOrLookupNode(parentFolderNodeId, null);
|
||||
try
|
||||
{
|
||||
// get the path elements
|
||||
@@ -1741,7 +1741,7 @@ public class NodesImpl implements Nodes
|
||||
@Override
|
||||
public void deleteNode(String nodeId, Parameters parameters)
|
||||
{
|
||||
NodeRef nodeRef = validateOrLookupNode(nodeId);
|
||||
NodeRef nodeRef = validateOrLookupNode(nodeId, null);
|
||||
|
||||
if (isSpecialNode(nodeRef, getNodeType(nodeRef)))
|
||||
{
|
||||
@@ -1785,7 +1785,7 @@ public class NodesImpl implements Nodes
|
||||
validateProperties(nodeInfo.getProperties(), EXCLUDED_NS, Arrays.asList());
|
||||
|
||||
// check that requested parent node exists and it's type is a (sub-)type of folder
|
||||
NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId);
|
||||
NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null);
|
||||
|
||||
// node name - mandatory
|
||||
String nodeName = nodeInfo.getName();
|
||||
@@ -2290,7 +2290,7 @@ public class NodesImpl implements Nodes
|
||||
validateAspects(nodeInfo.getAspectNames(), EXCLUDED_NS, EXCLUDED_ASPECTS);
|
||||
validateProperties(nodeInfo.getProperties(), EXCLUDED_NS, Arrays.asList());
|
||||
|
||||
final NodeRef nodeRef = validateOrLookupNode(nodeId);
|
||||
final NodeRef nodeRef = validateOrLookupNode(nodeId, null);
|
||||
|
||||
QName nodeTypeQName = getNodeType(nodeRef);
|
||||
|
||||
@@ -2523,8 +2523,8 @@ public class NodesImpl implements Nodes
|
||||
throw new InvalidArgumentException("Missing targetParentId");
|
||||
}
|
||||
|
||||
final NodeRef parentNodeRef = validateOrLookupNode(targetParentId);
|
||||
final NodeRef sourceNodeRef = validateOrLookupNode(sourceNodeId);
|
||||
final NodeRef parentNodeRef = validateOrLookupNode(targetParentId, null);
|
||||
final NodeRef sourceNodeRef = validateOrLookupNode(sourceNodeId, null);
|
||||
|
||||
FileInfo fi = moveOrCopyImpl(sourceNodeRef, parentNodeRef, name, isCopy);
|
||||
return getFolderOrDocument(fi.getNodeRef().getId(), parameters);
|
||||
@@ -2954,7 +2954,7 @@ public class NodesImpl implements Nodes
|
||||
throw new InvalidArgumentException("The request content-type is not multipart: "+parentFolderNodeId);
|
||||
}
|
||||
|
||||
NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId);
|
||||
NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null);
|
||||
if (!nodeMatches(parentNodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), null, false))
|
||||
{
|
||||
throw new InvalidArgumentException("NodeId of folder is expected: " + parentNodeRef.getId());
|
||||
@@ -3385,7 +3385,7 @@ public class NodesImpl implements Nodes
|
||||
@Override
|
||||
public Node lock(String nodeId, LockInfo lockInfo, Parameters parameters)
|
||||
{
|
||||
NodeRef nodeRef = validateOrLookupNode(nodeId);
|
||||
NodeRef nodeRef = validateOrLookupNode(nodeId, null);
|
||||
|
||||
if (isSpecialNode(nodeRef, getNodeType(nodeRef)))
|
||||
{
|
||||
@@ -3424,7 +3424,7 @@ public class NodesImpl implements Nodes
|
||||
@Override
|
||||
public Node unlock(String nodeId, Parameters parameters)
|
||||
{
|
||||
NodeRef nodeRef = validateOrLookupNode(nodeId);
|
||||
NodeRef nodeRef = validateOrLookupNode(nodeId, null);
|
||||
|
||||
if (isSpecialNode(nodeRef, getNodeType(nodeRef)))
|
||||
{
|
||||
|
||||
@@ -185,7 +185,7 @@ public class QueriesImpl implements Queries, InitializingBean
|
||||
String rootNodeId = parameters.getParameter(PARAM_ROOT_NODE_ID);
|
||||
if (rootNodeId != null)
|
||||
{
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(rootNodeId);
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(rootNodeId, null);
|
||||
query.append("PATH:\"").append(getQNamePath(nodeRef.getId())).append("//*\" AND (");
|
||||
}
|
||||
if (term != null)
|
||||
|
||||
@@ -695,7 +695,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
{
|
||||
if (versionLabelId != null)
|
||||
{
|
||||
nodeRef = nodes.validateOrLookupNode(nodeRef.getId());
|
||||
nodeRef = nodes.validateOrLookupNode(nodeRef.getId(), null);
|
||||
VersionHistory vh = versionService.getVersionHistory(nodeRef);
|
||||
if (vh != null)
|
||||
{
|
||||
|
||||
@@ -1,352 +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 static java.util.stream.Collectors.toList;
|
||||
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.EQUALS;
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.IN;
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.MATCHES;
|
||||
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
|
||||
import static org.alfresco.service.cmr.tagging.TaggingService.TAG_ROOT_NODE_REF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.query.ListBackedPagingResults;
|
||||
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.rest.framework.resource.parameters.SortColumn;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.Query;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.QueryImpl;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.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
|
||||
{
|
||||
public static final String PARAM_INCLUDE_COUNT = "count";
|
||||
private static final String PARAM_WHERE_TAG = "tag";
|
||||
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 NodeService nodeService;
|
||||
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 setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
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, final Parameters parameters)
|
||||
{
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(nodeId);
|
||||
if (!typeConstraint.matches(nodeRef))
|
||||
{
|
||||
throw new UnsupportedResourceOperationException("Cannot tag this node");
|
||||
}
|
||||
|
||||
List<String> tagValues = tags.stream().map(Tag::getTag).collect(toList());
|
||||
try
|
||||
{
|
||||
List<Pair<String, NodeRef>> tagNodeRefs = taggingService.addTags(nodeRef, tagValues);
|
||||
List<Tag> ret = new ArrayList<>(tags.size());
|
||||
List<Pair<String, Integer>> tagsCountPairList = taggingService.findTaggedNodesAndCountByTagName(nodeRef.getStoreRef());
|
||||
Map<String, Long> tagsCountMap = tagsCountPairList.stream().collect(Collectors.toMap(Pair::getFirst, pair -> Long.valueOf(pair.getSecond())));
|
||||
for (Pair<String, NodeRef> pair : tagNodeRefs)
|
||||
{
|
||||
Tag createdTag = new Tag(pair.getSecond(), pair.getFirst());
|
||||
if (parameters.getInclude().contains(PARAM_INCLUDE_COUNT))
|
||||
{
|
||||
createdTag.setCount(Optional.ofNullable(tagsCountMap.get(createdTag.getTag())).orElse(0L) + 1);
|
||||
}
|
||||
ret.add(createdTag);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
throw new InvalidArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteTag(String nodeId, String tagId)
|
||||
{
|
||||
NodeRef nodeRef = nodes.validateNode(nodeId);
|
||||
getTag(STORE_REF_WORKSPACE_SPACESSTORE, tagId, null);
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Parameters params)
|
||||
{
|
||||
Paging paging = params.getPaging();
|
||||
Pair<String, Boolean> sorting = !params.getSorting().isEmpty() ? new Pair<>(params.getSorting().get(0).column, params.getSorting().get(0).asc) : null;
|
||||
Map<Integer, Collection<String>> namesFilters = resolveTagNamesQuery(params.getQuery());
|
||||
|
||||
Map<NodeRef, Long> results = taggingService.getTags(storeRef, params.getInclude(), sorting, namesFilters.get(EQUALS), namesFilters.get(MATCHES));
|
||||
|
||||
List<Tag> tagsList = results.entrySet().stream().map(entry -> new Tag(entry.getKey(), (String)nodeService.getProperty(entry.getKey(), ContentModel.PROP_NAME))).collect(Collectors.toList());
|
||||
|
||||
if (params.getInclude().contains(PARAM_INCLUDE_COUNT))
|
||||
{
|
||||
tagsList.forEach(tag -> tag.setCount(results.get(tag.getNodeRef())));
|
||||
}
|
||||
|
||||
ListBackedPagingResults listBackedPagingResults = new ListBackedPagingResults(tagsList, Util.getPagingRequest(params.getPaging()));
|
||||
|
||||
return CollectionWithPagingInfo.asPaged(paging, listBackedPagingResults.getPage(), listBackedPagingResults.hasMoreItems(), (Integer) listBackedPagingResults.getTotalResultCount().getFirst());
|
||||
}
|
||||
|
||||
public NodeRef validateTag(String tagId)
|
||||
{
|
||||
NodeRef tagNodeRef = nodes.validateNode(tagId);
|
||||
return checkTagRootAsNodePrimaryParent(tagId, tagNodeRef);
|
||||
}
|
||||
|
||||
public NodeRef validateTag(StoreRef storeRef, String tagId)
|
||||
{
|
||||
NodeRef tagNodeRef = nodes.validateNode(storeRef, tagId);
|
||||
return checkTagRootAsNodePrimaryParent(tagId, tagNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the number of times the given tag is used (if requested).
|
||||
*
|
||||
* @param storeRef The store the tag is in.
|
||||
* @param tagName The name of the tag.
|
||||
* @param parameters The request parameters object containing the includes parameter.
|
||||
* @return The number of times the tag is applied, or null if "count" wasn't in the include parameter.
|
||||
*/
|
||||
private Long findCountIfRequested(StoreRef storeRef, String tagName, Parameters parameters)
|
||||
{
|
||||
Long count = null;
|
||||
if (parameters != null && parameters.getInclude() != null && parameters.getInclude().contains(PARAM_INCLUDE_COUNT))
|
||||
{
|
||||
count = taggingService.findCountByTagName(storeRef, tagName);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag changeTag(StoreRef storeRef, String tagId, Tag tag, Parameters parameters)
|
||||
{
|
||||
try
|
||||
{
|
||||
NodeRef existingTagNodeRef = validateTag(storeRef, tagId);
|
||||
String existingTagName = taggingService.getTagName(existingTagNodeRef);
|
||||
Long count = findCountIfRequested(storeRef, existingTagName, parameters);
|
||||
String newTagName = tag.getTag();
|
||||
NodeRef newTagNodeRef = taggingService.changeTag(storeRef, existingTagName, newTagName);
|
||||
return Tag.builder().nodeRef(newTagNodeRef).tag(newTagName).count(count).create();
|
||||
}
|
||||
catch(NonExistentTagException e)
|
||||
{
|
||||
throw new NotFoundException(e.getMessage());
|
||||
}
|
||||
catch(TagExistsException e)
|
||||
{
|
||||
throw new ConstraintViolatedException(e.getMessage());
|
||||
}
|
||||
catch(TaggingException e)
|
||||
{
|
||||
throw new InvalidArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getTag(StoreRef storeRef, String tagId, Parameters parameters)
|
||||
{
|
||||
NodeRef tagNodeRef = validateTag(storeRef, tagId);
|
||||
String tagName = taggingService.getTagName(tagNodeRef);
|
||||
Long count = findCountIfRequested(storeRef, tagName, parameters);
|
||||
return Tag.builder().nodeRef(tagNodeRef).tag(tagName).count(count).create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionWithPagingInfo<Tag> getTags(String nodeId, Parameters params)
|
||||
{
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(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<>(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(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(0L);
|
||||
}
|
||||
}).collect(toList());
|
||||
}
|
||||
|
||||
private void verifyAdminAuthority()
|
||||
{
|
||||
if (!authorityService.hasAdminAuthority())
|
||||
{
|
||||
throw new PermissionDeniedException(NO_PERMISSION_TO_MANAGE_A_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method resolves where query looking for clauses: EQUALS, IN or MATCHES.
|
||||
* Expected values for EQUALS and IN will be merged under EQUALS clause.
|
||||
* @param namesQuery Where query with expected tag name(s).
|
||||
* @return Map of expected exact and alike tag names.
|
||||
*/
|
||||
private Map<Integer, Collection<String>> resolveTagNamesQuery(final Query namesQuery)
|
||||
{
|
||||
if (namesQuery == null || namesQuery == QueryImpl.EMPTY)
|
||||
{
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
final Map<Integer, Collection<String>> properties = QueryHelper
|
||||
.resolve(namesQuery)
|
||||
.usingOrOperator()
|
||||
.withoutNegations()
|
||||
.getProperty(PARAM_WHERE_TAG)
|
||||
.getExpectedValuesForAnyOf(EQUALS, IN, MATCHES)
|
||||
.skipNegated();
|
||||
|
||||
return properties.entrySet().stream()
|
||||
.collect(Collectors.groupingBy((entry) -> {
|
||||
if (entry.getKey() == EQUALS || entry.getKey() == IN)
|
||||
{
|
||||
return EQUALS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MATCHES;
|
||||
}
|
||||
}, Collectors.flatMapping((entry) -> entry.getValue().stream().map(String::toLowerCase), Collectors.toCollection(HashSet::new))));
|
||||
}
|
||||
|
||||
private NodeRef checkTagRootAsNodePrimaryParent(String tagId, NodeRef tagNodeRef)
|
||||
{
|
||||
if ( tagNodeRef == null || !nodeService.getPrimaryParent(tagNodeRef).getParentRef().equals(TAG_ROOT_NODE_REF))
|
||||
{
|
||||
throw new EntityNotFoundException(tagId);
|
||||
}
|
||||
return tagNodeRef;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* #%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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ public class RestRuleModelMapper implements RestModelMapper<Rule, org.alfresco.s
|
||||
public org.alfresco.service.cmr.rule.Rule toServiceModel(Rule restRuleModel)
|
||||
{
|
||||
final org.alfresco.service.cmr.rule.Rule serviceRule = new org.alfresco.service.cmr.rule.Rule();
|
||||
final NodeRef nodeRef = (restRuleModel.getId() != null) ? nodes.validateOrLookupNode(restRuleModel.getId()) : null;
|
||||
final NodeRef nodeRef = (restRuleModel.getId() != null) ? nodes.validateOrLookupNode(restRuleModel.getId(), null) : null;
|
||||
serviceRule.setNodeRef(nodeRef);
|
||||
serviceRule.setTitle(restRuleModel.getName());
|
||||
serviceRule.setDescription(restRuleModel.getDescription());
|
||||
|
||||
@@ -129,7 +129,7 @@ public class RestRuleSimpleConditionModelMapper implements RestModelMapper<Simpl
|
||||
parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, ContentModel.ASPECT_GEN_CLASSIFIABLE);
|
||||
try
|
||||
{
|
||||
parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, nodes.validateOrLookupNode(parameter));
|
||||
parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, nodes.validateOrLookupNode(parameter, null));
|
||||
} catch (EntityNotFoundException e) {
|
||||
throw new InvalidArgumentException(CATEGORY_INVALID_MSG);
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ public class ActionParameterConverter
|
||||
}
|
||||
else if (typeQName.isMatch(DataTypeDefinition.NODE_REF))
|
||||
{
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(stringValue);
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(stringValue, null);
|
||||
if (permissionService.hasReadPermission(nodeRef) != ALLOWED)
|
||||
{
|
||||
throw new EntityNotFoundException(stringValue);
|
||||
|
||||
@@ -72,7 +72,7 @@ public class NodeValidator
|
||||
{
|
||||
try
|
||||
{
|
||||
final NodeRef nodeRef = nodes.validateOrLookupNode(folderNodeId);
|
||||
final NodeRef nodeRef = nodes.validateOrLookupNode(folderNodeId, null);
|
||||
validatePermission(requireChangePermission, nodeRef);
|
||||
verifyNodeType(nodeRef, ContentModel.TYPE_FOLDER, null);
|
||||
|
||||
|
||||
@@ -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,8 +34,6 @@ public class Category
|
||||
private String name;
|
||||
private String parentId;
|
||||
private boolean hasChildren;
|
||||
private Integer count;
|
||||
private String path;
|
||||
|
||||
public String getId()
|
||||
{
|
||||
@@ -82,47 +80,20 @@ public class Category
|
||||
this.hasChildren = hasChildren;
|
||||
}
|
||||
|
||||
public Integer getCount()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Integer count)
|
||||
{
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@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) && Objects.equals(path, category.path);
|
||||
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, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Category{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", parentId='" + parentId + '\'' + ", hasChildren=" + hasChildren
|
||||
+ ", count=" + count + ", path=" + path + '}';
|
||||
return Objects.hash(id, name, parentId, hasChildren);
|
||||
}
|
||||
|
||||
public static Builder builder()
|
||||
@@ -136,8 +107,6 @@ public class Category
|
||||
private String name;
|
||||
private String parentId;
|
||||
private boolean hasChildren;
|
||||
private Integer count;
|
||||
private String path;
|
||||
|
||||
public Builder id(String id)
|
||||
{
|
||||
@@ -163,18 +132,6 @@ public class Category
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder count(Integer count)
|
||||
{
|
||||
this.count = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder path(String path)
|
||||
{
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Category create()
|
||||
{
|
||||
final Category category = new Category();
|
||||
@@ -182,8 +139,6 @@ public class Category
|
||||
category.setName(name);
|
||||
category.setParentId(parentId);
|
||||
category.setHasChildren(hasChildren);
|
||||
category.setCount(count);
|
||||
category.setPath(path);
|
||||
return category;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,9 +25,6 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.model;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.alfresco.rest.framework.resource.UniqueId;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -42,7 +39,7 @@ public class Tag implements Comparable<Tag>
|
||||
{
|
||||
private NodeRef nodeRef;
|
||||
private String tag;
|
||||
private Long count;
|
||||
private Integer count;
|
||||
|
||||
public Tag()
|
||||
{
|
||||
@@ -51,7 +48,7 @@ public class Tag implements Comparable<Tag>
|
||||
public Tag(NodeRef nodeRef, String tag)
|
||||
{
|
||||
this.nodeRef = nodeRef;
|
||||
setTag(tag);
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@JsonProperty("id")
|
||||
@@ -73,16 +70,16 @@ public class Tag implements Comparable<Tag>
|
||||
|
||||
public void setTag(String tag)
|
||||
{
|
||||
this.tag = Optional.ofNullable(tag).map(String::toLowerCase).orElse(null);
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public Long getCount()
|
||||
public Integer getCount()
|
||||
{
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Long count)
|
||||
public void setCount(Integer count)
|
||||
{
|
||||
this.count = count;
|
||||
}
|
||||
@@ -101,65 +98,43 @@ public class Tag implements Comparable<Tag>
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
Tag tag1 = (Tag) o;
|
||||
return Objects.equals(nodeRef, tag1.nodeRef) && Objects.equals(tag, tag1.tag) && Objects.equals(count, tag1.count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hash(nodeRef, tag, count);
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((nodeRef == null) ? 0 : nodeRef.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tags are equal if they have the same NodeRef
|
||||
*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Tag other = (Tag) obj;
|
||||
if (nodeRef == null) {
|
||||
if (other.nodeRef != null)
|
||||
return false;
|
||||
} else if (!nodeRef.equals(other.nodeRef))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@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 Long count;
|
||||
|
||||
public Builder nodeRef(NodeRef nodeRef)
|
||||
{
|
||||
this.nodeRef = nodeRef;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder tag(String tag)
|
||||
{
|
||||
this.tag = tag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder count(Long 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 + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,9 +31,13 @@ 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.Parameters;
|
||||
import org.alfresco.rest.framework.resource.parameters.SortColumn;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RelationshipResource(name = "action-definitions", entityResource = NodesEntityResource.class, title = "Node action definitions")
|
||||
public class NodeActionDefinitionsRelation extends AbstractNodeRelation
|
||||
implements RelationshipResourceAction.Read<ActionDefinition>
|
||||
@@ -55,7 +59,7 @@ public class NodeActionDefinitionsRelation extends AbstractNodeRelation
|
||||
@Override
|
||||
public CollectionWithPagingInfo<ActionDefinition> readAll(String entityResourceId, Parameters params)
|
||||
{
|
||||
NodeRef parentNodeRef = nodes.validateOrLookupNode(entityResourceId);
|
||||
NodeRef parentNodeRef = nodes.validateOrLookupNode(entityResourceId, null);
|
||||
return actions.getActionDefinitions(parentNodeRef, params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,6 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.nodes;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.rest.antlr.WhereClauseParser;
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.model.Node;
|
||||
@@ -46,6 +41,11 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Node Parents
|
||||
*
|
||||
@@ -67,7 +67,7 @@ public class NodeParentsRelation extends AbstractNodeRelation implements Relatio
|
||||
@WebApiDescription(title = "Return a list of parent nodes based on child assocs")
|
||||
public CollectionWithPagingInfo<Node> readAll(String childNodeId, Parameters parameters)
|
||||
{
|
||||
NodeRef childNodeRef = nodes.validateOrLookupNode(childNodeId);
|
||||
NodeRef childNodeRef = nodes.validateOrLookupNode(childNodeId, null);
|
||||
|
||||
QNamePattern assocTypeQNameParam = RegexQNamePattern.MATCH_ALL;
|
||||
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.nodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.model.AssocChild;
|
||||
import org.alfresco.rest.api.model.Node;
|
||||
@@ -43,6 +41,8 @@ import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Node Secondary Children
|
||||
*
|
||||
@@ -71,7 +71,7 @@ public class NodeSecondaryChildrenRelation extends AbstractNodeRelation implemen
|
||||
@WebApiDescription(title = "Return a paged list of secondary child nodes based on child assocs")
|
||||
public CollectionWithPagingInfo<Node> readAll(String parentNodeId, Parameters parameters)
|
||||
{
|
||||
NodeRef parentNodeRef = nodes.validateOrLookupNode(parentNodeId);
|
||||
NodeRef parentNodeRef = nodes.validateOrLookupNode(parentNodeId, null);
|
||||
|
||||
QNamePattern assocTypeQNameParam = getAssocTypeFromWhereElseAll(parameters);
|
||||
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.nodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.rest.api.model.Node;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.resource.RelationshipResource;
|
||||
@@ -37,6 +35,8 @@ import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Node Sources - list node (peer) associations from target to sources
|
||||
*
|
||||
@@ -54,7 +54,7 @@ public class NodeSourcesRelation extends AbstractNodeRelation implements Relatio
|
||||
@WebApiDescription(title = "Return a paged list of sources nodes based on (peer) assocs")
|
||||
public CollectionWithPagingInfo<Node> readAll(String targetNodeId, Parameters parameters)
|
||||
{
|
||||
NodeRef targetNodeRef = nodes.validateOrLookupNode(targetNodeId);
|
||||
NodeRef targetNodeRef = nodes.validateOrLookupNode(targetNodeId, null);
|
||||
|
||||
QNamePattern assocTypeQNameParam = getAssocTypeFromWhereElseAll(parameters);
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
/*
|
||||
* #%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%
|
||||
*/
|
||||
/*
|
||||
* #%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.nodes;
|
||||
|
||||
import java.util.List;
|
||||
@@ -61,7 +61,7 @@ public class NodeTagsRelation implements RelationshipResourceAction.Create<Tag>,
|
||||
@WebApiDescription(title="Adds one or more tags to the node with id 'nodeId'.")
|
||||
public List<Tag> create(String nodeId, List<Tag> tagsToCreate, Parameters parameters)
|
||||
{
|
||||
return tags.addTags(nodeId, tagsToCreate, parameters);
|
||||
return tags.addTags(nodeId, tagsToCreate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.nodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.model.AssocTarget;
|
||||
import org.alfresco.rest.api.model.Node;
|
||||
@@ -42,6 +40,8 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Node Targets
|
||||
*
|
||||
@@ -64,7 +64,7 @@ public class NodeTargetsRelation extends AbstractNodeRelation implements
|
||||
@WebApiDescription(title = "Return a paged list of target nodes based on (peer) assocs")
|
||||
public CollectionWithPagingInfo<Node> readAll(String sourceNodeId, Parameters parameters)
|
||||
{
|
||||
NodeRef sourceNodeRef = nodes.validateOrLookupNode(sourceNodeId);
|
||||
NodeRef sourceNodeRef = nodes.validateOrLookupNode(sourceNodeId, null);
|
||||
|
||||
QNamePattern assocTypeQNameParam = getAssocTypeFromWhereElseAll(parameters);
|
||||
|
||||
|
||||
@@ -25,13 +25,6 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.nodes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.directurl.DirectAccessUrlDisabledException;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
@@ -72,6 +65,13 @@ import org.alfresco.util.ParameterCheck;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Node Versions - version history
|
||||
*
|
||||
@@ -117,7 +117,7 @@ public class NodeVersionsRelation extends AbstractNodeRelation implements
|
||||
@WebApiDescription(title = "Return version history as a paged list of version node infos")
|
||||
public CollectionWithPagingInfo<Node> readAll(String nodeId, Parameters parameters)
|
||||
{
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(nodeId);
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null);
|
||||
|
||||
VersionHistory vh = versionService.getVersionHistory(nodeRef);
|
||||
|
||||
@@ -293,7 +293,7 @@ public class NodeVersionsRelation extends AbstractNodeRelation implements
|
||||
|
||||
public Version findVersion(String nodeId, String versionLabelId)
|
||||
{
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(nodeId);
|
||||
NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null);
|
||||
VersionHistory vh = versionService.getVersionHistory(nodeRef);
|
||||
if (vh != null)
|
||||
{
|
||||
|
||||
@@ -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 java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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;
|
||||
|
||||
@@ -59,8 +54,9 @@ public class TagsEntityResource implements EntityResourceAction.Read<Tag>,
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns a paged list of all currently used tags in the store workspace://SpacesStore for the current tenant.
|
||||
* GET /tags
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title="A paged list of all tags in the network.")
|
||||
@@ -73,33 +69,12 @@ public class TagsEntityResource implements EntityResourceAction.Read<Tag>,
|
||||
@WebApiDescription(title="Updates a tag by unique Id")
|
||||
public Tag update(String id, Tag entity, Parameters parameters)
|
||||
{
|
||||
return tags.changeTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id, entity, parameters);
|
||||
return tags.changeTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag readById(String id, Parameters parameters) throws EntityNotFoundException
|
||||
{
|
||||
return tags.getTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return tags.getTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,259 +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.framework.resource.parameters.where;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.rest.antlr.WhereClauseParser;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* Basic implementation of {@link QueryHelper.WalkerCallbackAdapter} providing universal handling of Where query clauses.
|
||||
* This implementation supports AND operator and all clause types.
|
||||
* Be default, walker verifies strictly if expected or unexpected properties, and it's comparison types are present in query
|
||||
* and throws {@link InvalidQueryException} if they are missing.
|
||||
*/
|
||||
public class BasicQueryWalker extends QueryHelper.WalkerCallbackAdapter
|
||||
{
|
||||
private static final String EQUALS_AND_IN_NOT_ALLOWED_TOGETHER = "Where query error: cannot use '=' (EQUALS) AND 'IN' clauses with same property: %s";
|
||||
private static final String MISSING_PROPERTY = "Where query error: property with name: %s not present";
|
||||
static final String MISSING_CLAUSE_TYPE = "Where query error: property with name: %s expects clause: %s";
|
||||
static final String MISSING_ANY_CLAUSE_OF_TYPE = "Where query error: property with name: %s expects at least one of clauses: %s";
|
||||
private static final String PROPERTY_NOT_EXPECTED = "Where query error: property with name: %s is not expected";
|
||||
private static final String PROPERTY_NOT_NEGATABLE = "Where query error: property with name: %s cannot be negated";
|
||||
private static final String PROPERTY_NAMES_EMPTY = "Cannot verify WHERE query without expected property names";
|
||||
|
||||
private Collection<String> expectedPropertyNames;
|
||||
private final Map<String, WhereProperty> properties;
|
||||
protected boolean clausesNegatable = true;
|
||||
protected boolean validateStrictly = true;
|
||||
|
||||
public BasicQueryWalker()
|
||||
{
|
||||
this.properties = new HashMap<>();
|
||||
}
|
||||
|
||||
public BasicQueryWalker(final String... expectedPropertyNames)
|
||||
{
|
||||
this();
|
||||
this.expectedPropertyNames = Set.of(expectedPropertyNames);
|
||||
}
|
||||
|
||||
public BasicQueryWalker(final Collection<String> expectedPropertyNames)
|
||||
{
|
||||
this();
|
||||
this.expectedPropertyNames = expectedPropertyNames;
|
||||
}
|
||||
|
||||
public void setClausesNegatable(final boolean clausesNegatable)
|
||||
{
|
||||
this.clausesNegatable = clausesNegatable;
|
||||
}
|
||||
|
||||
public void setValidateStrictly(boolean validateStrictly)
|
||||
{
|
||||
this.validateStrictly = validateStrictly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exists(String propertyName, boolean negated)
|
||||
{
|
||||
verifyPropertyExpectedness(propertyName);
|
||||
verifyClausesNegatability(negated, propertyName);
|
||||
addProperties(propertyName, WhereClauseParser.EXISTS, negated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void between(String propertyName, String firstValue, String secondValue, boolean negated)
|
||||
{
|
||||
verifyPropertyExpectedness(propertyName);
|
||||
verifyClausesNegatability(negated, propertyName);
|
||||
addProperties(propertyName, WhereClauseParser.BETWEEN, negated, firstValue, secondValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comparison(int type, String propertyName, String propertyValue, boolean negated)
|
||||
{
|
||||
verifyPropertyExpectedness(propertyName);
|
||||
verifyClausesNegatability(negated, propertyName);
|
||||
if (WhereClauseParser.EQUALS == type && isAndSupported() && containsProperty(propertyName, WhereClauseParser.IN, negated))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(EQUALS_AND_IN_NOT_ALLOWED_TOGETHER, propertyName));
|
||||
}
|
||||
|
||||
addProperties(propertyName, type, negated, propertyValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void in(String propertyName, boolean negated, String... propertyValues)
|
||||
{
|
||||
verifyPropertyExpectedness(propertyName);
|
||||
verifyClausesNegatability(negated, propertyName);
|
||||
if (isAndSupported() && containsProperty(propertyName, WhereClauseParser.EQUALS, negated))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(EQUALS_AND_IN_NOT_ALLOWED_TOGETHER, propertyName));
|
||||
}
|
||||
|
||||
addProperties(propertyName, WhereClauseParser.IN, negated, propertyValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void matches(final String propertyName, String propertyValue, boolean negated)
|
||||
{
|
||||
verifyPropertyExpectedness(propertyName);
|
||||
verifyClausesNegatability(negated, propertyName);
|
||||
addProperties(propertyName, WhereClauseParser.MATCHES, negated, propertyValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void and()
|
||||
{
|
||||
// Don't need to do anything here - it's enough to enable AND operator.
|
||||
// OR is not supported at the same time.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if property is expected, if not throws {@link InvalidQueryException}.
|
||||
*/
|
||||
protected void verifyPropertyExpectedness(final String propertyName)
|
||||
{
|
||||
if (validateStrictly && CollectionUtils.isNotEmpty(expectedPropertyNames) && !this.expectedPropertyNames.contains(propertyName))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(PROPERTY_NOT_EXPECTED, propertyName));
|
||||
}
|
||||
else if (validateStrictly && CollectionUtils.isEmpty(expectedPropertyNames))
|
||||
{
|
||||
throw new IllegalStateException(PROPERTY_NAMES_EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if clause negations are allowed, if not throws {@link InvalidQueryException}.
|
||||
*/
|
||||
protected void verifyClausesNegatability(final boolean negated, final String propertyName)
|
||||
{
|
||||
if (!clausesNegatable && negated)
|
||||
{
|
||||
throw new InvalidQueryException(String.format(PROPERTY_NOT_NEGATABLE, propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isAndSupported()
|
||||
{
|
||||
try
|
||||
{
|
||||
and();
|
||||
return true;
|
||||
}
|
||||
catch (InvalidQueryException ignore)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void addProperties(final String propertyName, final int clauseType, final String... propertyValues)
|
||||
{
|
||||
this.addProperties(propertyName, clauseType, false, propertyValues);
|
||||
}
|
||||
|
||||
protected void addProperties(final String propertyName, final int clauseType, final boolean negated, final String... propertyValues)
|
||||
{
|
||||
final WhereProperty.ClauseType type = WhereProperty.ClauseType.of(clauseType, negated);
|
||||
final Set<String> propertiesToAdd = Optional.ofNullable(propertyValues).map(Set::of).orElse(Collections.emptySet());
|
||||
if (this.containsProperty(propertyName))
|
||||
{
|
||||
this.properties.get(propertyName).addValuesToType(type, propertiesToAdd);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.properties.put(propertyName, new WhereProperty(propertyName, type, propertiesToAdd, validateStrictly));
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean containsProperty(final String propertyName)
|
||||
{
|
||||
return this.properties.containsKey(propertyName);
|
||||
}
|
||||
|
||||
protected boolean containsProperty(final String propertyName, final int clauseType, final boolean negated)
|
||||
{
|
||||
return this.properties.containsKey(propertyName) && this.properties.get(propertyName).containsType(clauseType, negated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getProperty(String propertyName, int type, boolean negated)
|
||||
{
|
||||
return this.getProperty(propertyName).getExpectedValuesFor(type, negated);
|
||||
}
|
||||
|
||||
public WhereProperty getProperty(final String propertyName)
|
||||
{
|
||||
if (validateStrictly && !this.containsProperty(propertyName))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(MISSING_PROPERTY, propertyName));
|
||||
}
|
||||
|
||||
return this.properties.get(propertyName);
|
||||
}
|
||||
|
||||
public List<WhereProperty> getProperties(final String... propertyNames)
|
||||
{
|
||||
return Arrays.stream(propertyNames)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.distinct()
|
||||
.peek(propertyName -> {
|
||||
if (validateStrictly && !this.containsProperty(propertyName))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(MISSING_PROPERTY, propertyName));
|
||||
}
|
||||
})
|
||||
.map(this.properties::get)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Map<String, WhereProperty> getPropertiesAsMap(final String... propertyNames)
|
||||
{
|
||||
return Arrays.stream(propertyNames)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.distinct()
|
||||
.peek(propertyName -> {
|
||||
if (validateStrictly && !this.containsProperty(propertyName))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(MISSING_PROPERTY, propertyName));
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toMap(propertyName -> propertyName, this.properties::get));
|
||||
}
|
||||
}
|
||||
@@ -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,19 +25,10 @@
|
||||
*/
|
||||
package org.alfresco.rest.framework.resource.parameters.where;
|
||||
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.BETWEEN;
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.EQUALS;
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.EXISTS;
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.IN;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.alfresco.rest.antlr.WhereClauseParser;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
@@ -54,19 +45,14 @@ public abstract class QueryHelper
|
||||
/**
|
||||
* An interface used when walking a query tree. Calls are made to methods when the particular clause is encountered.
|
||||
*/
|
||||
public interface WalkerCallback
|
||||
public static interface WalkerCallback
|
||||
{
|
||||
InvalidQueryException UNSUPPORTED = new InvalidQueryException("Unsupported Predicate");
|
||||
|
||||
/**
|
||||
* Called any time an EXISTS clause is encountered.
|
||||
* @param propertyName Name of the property
|
||||
* @param negated returns true if "NOT EXISTS" was used
|
||||
*/
|
||||
default void exists(String propertyName, boolean negated)
|
||||
{
|
||||
throw UNSUPPORTED;
|
||||
}
|
||||
void exists(String propertyName, boolean negated);
|
||||
|
||||
/**
|
||||
* Called any time a BETWEEN clause is encountered.
|
||||
@@ -75,18 +61,12 @@ public abstract class QueryHelper
|
||||
* @param secondValue String
|
||||
* @param negated returns true if "NOT BETWEEN" was used
|
||||
*/
|
||||
default void between(String propertyName, String firstValue, String secondValue, boolean negated)
|
||||
{
|
||||
throw UNSUPPORTED;
|
||||
}
|
||||
void between(String propertyName, String firstValue, String secondValue, boolean negated);
|
||||
|
||||
/**
|
||||
* One of EQUALS LESSTHAN GREATERTHAN LESSTHANOREQUALS GREATERTHANOREQUALS;
|
||||
*/
|
||||
default void comparison(int type, String propertyName, String propertyValue, boolean negated)
|
||||
{
|
||||
throw UNSUPPORTED;
|
||||
}
|
||||
void comparison(int type, String propertyName, String propertyValue, boolean negated);
|
||||
|
||||
/**
|
||||
* Called any time an IN clause is encountered.
|
||||
@@ -94,10 +74,7 @@ public abstract class QueryHelper
|
||||
* @param negated returns true if "NOT IN" was used
|
||||
* @param propertyValues the property values
|
||||
*/
|
||||
default void in(String property, boolean negated, String... propertyValues)
|
||||
{
|
||||
throw UNSUPPORTED;
|
||||
}
|
||||
void in(String property, boolean negated, String... propertyValues);
|
||||
|
||||
/**
|
||||
* Called any time a MATCHES clause is encountered.
|
||||
@@ -105,37 +82,42 @@ public abstract class QueryHelper
|
||||
* @param propertyValue String
|
||||
* @param negated returns true if "NOT MATCHES" was used
|
||||
*/
|
||||
default void matches(String property, String propertyValue, boolean negated)
|
||||
{
|
||||
throw UNSUPPORTED;
|
||||
}
|
||||
void matches(String property, String propertyValue, boolean negated);
|
||||
|
||||
/**
|
||||
* Called any time an AND is encountered.
|
||||
*/
|
||||
default void and()
|
||||
{
|
||||
throw UNSUPPORTED;
|
||||
}
|
||||
*/
|
||||
void and();
|
||||
/**
|
||||
* Called any time an OR is encountered.
|
||||
*/
|
||||
default void or()
|
||||
{
|
||||
throw UNSUPPORTED;
|
||||
}
|
||||
|
||||
default Collection<String> getProperty(String propertyName, int type, boolean negated)
|
||||
{
|
||||
throw UNSUPPORTED;
|
||||
}
|
||||
*/
|
||||
void or();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation. Override the methods you are interested in. If you don't
|
||||
* override the methods then an InvalidQueryException will be thrown.
|
||||
*/
|
||||
public static class WalkerCallbackAdapter implements WalkerCallback {}
|
||||
public static class WalkerCallbackAdapter implements WalkerCallback
|
||||
{
|
||||
private static final String UNSUPPORTED_TEXT = "Unsupported Predicate";
|
||||
protected static final InvalidQueryException UNSUPPORTED = new InvalidQueryException(UNSUPPORTED_TEXT);
|
||||
|
||||
@Override
|
||||
public void exists(String propertyName, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void between(String propertyName, String firstValue, String secondValue, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void comparison(int type, String propertyName, String propertyValue, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void in(String propertyName, boolean negated, String... propertyValues) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void matches(String property, String value, boolean negated) { throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void and() {throw UNSUPPORTED;}
|
||||
@Override
|
||||
public void or() {throw UNSUPPORTED;}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks a query with a callback for each operation
|
||||
@@ -164,7 +146,7 @@ public abstract class QueryHelper
|
||||
if (tree != null)
|
||||
{
|
||||
switch (tree.getType()) {
|
||||
case EXISTS:
|
||||
case WhereClauseParser.EXISTS:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
callback.exists(tree.getChild(0).getText(), negated);
|
||||
@@ -178,7 +160,7 @@ public abstract class QueryHelper
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case IN:
|
||||
case WhereClauseParser.IN:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
List<Tree> children = getChildren(tree);
|
||||
@@ -192,14 +174,14 @@ public abstract class QueryHelper
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case BETWEEN:
|
||||
case WhereClauseParser.BETWEEN:
|
||||
if (WhereClauseParser.PROPERTYNAME == tree.getChild(0).getType())
|
||||
{
|
||||
callback.between(tree.getChild(0).getText(), stripQuotes(tree.getChild(1).getText()), stripQuotes(tree.getChild(2).getText()), negated);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case EQUALS: //fall through (comparison)
|
||||
case WhereClauseParser.EQUALS: //fall through (comparison)
|
||||
case WhereClauseParser.LESSTHAN: //fall through (comparison)
|
||||
case WhereClauseParser.GREATERTHAN: //fall through (comparison)
|
||||
case WhereClauseParser.LESSTHANOREQUALS: //fall through (comparison)
|
||||
@@ -304,180 +286,4 @@ public abstract class QueryHelper
|
||||
}
|
||||
return toBeStripped; //default to return the String unchanged.
|
||||
}
|
||||
|
||||
public static QueryResolver.WalkerSpecifier resolve(final Query query)
|
||||
{
|
||||
return new QueryResolver.WalkerSpecifier(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class allowing WHERE query resolving using query walker. By default {@link BasicQueryWalker} is used, but different walker can be supplied.
|
||||
*/
|
||||
public static abstract class QueryResolver<S extends QueryResolver<?>>
|
||||
{
|
||||
private final Query query;
|
||||
protected WalkerCallback queryWalker;
|
||||
protected Function<Collection<String>, BasicQueryWalker> orQueryWalkerSupplier;
|
||||
protected boolean clausesNegatable = true;
|
||||
protected boolean validateLeniently = false;
|
||||
protected abstract S self();
|
||||
|
||||
public QueryResolver(Query query)
|
||||
{
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property expected values.
|
||||
* @param propertyName Property name.
|
||||
* @param clauseType Property comparison type.
|
||||
* @param negated Comparison type negation.
|
||||
* @return Map composed of all comparators and compared values.
|
||||
*/
|
||||
public Collection<String> getProperty(final String propertyName, final int clauseType, final boolean negated)
|
||||
{
|
||||
processQuery(propertyName);
|
||||
return queryWalker.getProperty(propertyName, clauseType, negated);
|
||||
}
|
||||
|
||||
protected void processQuery(final String... propertyNames)
|
||||
{
|
||||
if (queryWalker == null)
|
||||
{
|
||||
if (orQueryWalkerSupplier != null)
|
||||
{
|
||||
queryWalker = orQueryWalkerSupplier.apply(Set.of(propertyNames));
|
||||
}
|
||||
else
|
||||
{
|
||||
queryWalker = new BasicQueryWalker(propertyNames);
|
||||
}
|
||||
}
|
||||
if (queryWalker instanceof BasicQueryWalker)
|
||||
{
|
||||
((BasicQueryWalker) queryWalker).setClausesNegatable(clausesNegatable);
|
||||
((BasicQueryWalker) queryWalker).setValidateStrictly(!validateLeniently);
|
||||
}
|
||||
walk(query, queryWalker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class providing methods related with default query walker {@link BasicQueryWalker}.
|
||||
*/
|
||||
public static class DefaultWalkerOperations<R extends DefaultWalkerOperations<?>> extends QueryResolver<R>
|
||||
{
|
||||
public DefaultWalkerOperations(Query query)
|
||||
{
|
||||
super(query);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected R self()
|
||||
{
|
||||
return (R) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies that query properties and comparison types should NOT be verified strictly.
|
||||
*/
|
||||
public R leniently()
|
||||
{
|
||||
this.validateLeniently = true;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies that clause types negations are not allowed in query.
|
||||
*/
|
||||
public R withoutNegations()
|
||||
{
|
||||
this.clausesNegatable = false;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property with expected values.
|
||||
* @param propertyName Property name.
|
||||
* @return Map composed of all comparators and compared values.
|
||||
*/
|
||||
public WhereProperty getProperty(final String propertyName)
|
||||
{
|
||||
processQuery(propertyName);
|
||||
return ((BasicQueryWalker) this.queryWalker).getProperty(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple properties with it's expected values.
|
||||
* @param propertyNames Property names.
|
||||
* @return List of maps composed of all comparators and compared values.
|
||||
*/
|
||||
public List<WhereProperty> getProperties(final String... propertyNames)
|
||||
{
|
||||
processQuery(propertyNames);
|
||||
return ((BasicQueryWalker) this.queryWalker).getProperties(propertyNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple properties with it's expected values.
|
||||
* @param propertyNames Property names.
|
||||
* @return Map composed of property names and maps composed of all comparators and compared values.
|
||||
*/
|
||||
public Map<String, WhereProperty> getPropertiesAsMap(final String... propertyNames)
|
||||
{
|
||||
processQuery(propertyNames);
|
||||
return ((BasicQueryWalker) this.queryWalker).getPropertiesAsMap(propertyNames);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class allowing to specify custom {@link WalkerCallback} implementation or {@link BasicQueryWalker} extension.
|
||||
*/
|
||||
public static class WalkerSpecifier extends DefaultWalkerOperations<WalkerSpecifier>
|
||||
{
|
||||
public WalkerSpecifier(Query query)
|
||||
{
|
||||
super(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WalkerSpecifier self()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies that OR operator instead of AND should be used while resolving the query.
|
||||
*/
|
||||
public DefaultWalkerOperations<? extends DefaultWalkerOperations<?>> usingOrOperator()
|
||||
{
|
||||
this.orQueryWalkerSupplier = (propertyNames) -> new BasicQueryWalker(propertyNames)
|
||||
{
|
||||
@Override
|
||||
public void or() {/*Enable OR support, disable AND support*/}
|
||||
@Override
|
||||
public void and() {throw UNSUPPORTED;}
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to specify custom {@link BasicQueryWalker} extension, which should be used to resolve the query.
|
||||
*/
|
||||
public <T extends BasicQueryWalker> DefaultWalkerOperations<? extends DefaultWalkerOperations<?>> usingWalker(final T queryWalker)
|
||||
{
|
||||
this.queryWalker = queryWalker;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to specify custom {@link WalkerCallback} implementation, which should be used to resolve the query.
|
||||
*/
|
||||
public <T extends WalkerCallback> QueryResolver<? extends QueryResolver<?>> usingWalker(final T queryWalker)
|
||||
{
|
||||
this.queryWalker = queryWalker;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,351 +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.framework.resource.parameters.where;
|
||||
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import static org.alfresco.rest.framework.resource.parameters.where.BasicQueryWalker.MISSING_ANY_CLAUSE_OF_TYPE;
|
||||
import static org.alfresco.rest.framework.resource.parameters.where.BasicQueryWalker.MISSING_CLAUSE_TYPE;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.alfresco.rest.antlr.WhereClauseParser;
|
||||
|
||||
/**
|
||||
* Map composed of property comparison type and compared values.
|
||||
* Map key is clause (comparison) type.
|
||||
*/
|
||||
public class WhereProperty extends HashMap<WhereProperty.ClauseType, Collection<String>>
|
||||
{
|
||||
private final String name;
|
||||
private boolean validateStrictly;
|
||||
|
||||
public WhereProperty(final String name, final ClauseType clauseType, final Collection<String> values)
|
||||
{
|
||||
super(Map.of(clauseType, new HashSet<>(values)));
|
||||
this.name = name;
|
||||
this.validateStrictly = true;
|
||||
}
|
||||
|
||||
public WhereProperty(final String name, final ClauseType clauseType, final Collection<String> values, final boolean validateStrictly)
|
||||
{
|
||||
this(name, clauseType, values);
|
||||
this.validateStrictly = validateStrictly;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void addValuesToType(final ClauseType clauseType, final Collection<String> values)
|
||||
{
|
||||
if (this.containsKey(clauseType))
|
||||
{
|
||||
this.get(clauseType).addAll(values);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.put(clauseType, new HashSet<>(values));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsType(final ClauseType clauseType)
|
||||
{
|
||||
return this.containsKey(clauseType);
|
||||
}
|
||||
|
||||
public boolean containsType(final int clauseType, final boolean negated)
|
||||
{
|
||||
return this.containsKey(ClauseType.of(clauseType, negated));
|
||||
}
|
||||
|
||||
public boolean containsAllTypes(final ClauseType... clauseType)
|
||||
{
|
||||
return Arrays.stream(clauseType).distinct().filter(this::containsKey).count() == clauseType.length;
|
||||
}
|
||||
|
||||
public boolean containsAnyOfTypes(final ClauseType... clauseType)
|
||||
{
|
||||
return Arrays.stream(clauseType).distinct().anyMatch(this::containsKey);
|
||||
}
|
||||
|
||||
public Collection<String> getExpectedValuesFor(final ClauseType clauseType)
|
||||
{
|
||||
verifyAllClausesPresence(clauseType);
|
||||
return this.get(clauseType);
|
||||
}
|
||||
|
||||
public HashMap<ClauseType, Collection<String>> getExpectedValuesForAllOf(final ClauseType... clauseTypes)
|
||||
{
|
||||
verifyAllClausesPresence(clauseTypes);
|
||||
return Arrays.stream(clauseTypes)
|
||||
.distinct()
|
||||
.collect(Collectors.toMap(type -> type, this::get, (type1, type2) -> type1, MultiTypeNegatableValuesMap::new));
|
||||
}
|
||||
|
||||
public HashMap<ClauseType, Collection<String>> getExpectedValuesForAnyOf(final ClauseType... clauseTypes)
|
||||
{
|
||||
verifyAnyClausesPresence(clauseTypes);
|
||||
return Arrays.stream(clauseTypes)
|
||||
.distinct()
|
||||
.collect(Collectors.toMap(type -> type, this::get, (type1, type2) -> type1, MultiTypeNegatableValuesMap::new));
|
||||
}
|
||||
|
||||
public Collection<String> getExpectedValuesFor(final int clauseType, final boolean negated)
|
||||
{
|
||||
verifyAllClausesPresence(ClauseType.of(clauseType, negated));
|
||||
return this.get(ClauseType.of(clauseType, negated));
|
||||
}
|
||||
|
||||
public NegatableValuesMap getExpectedValuesFor(final int clauseType)
|
||||
{
|
||||
verifyAllClausesPresence(clauseType);
|
||||
final NegatableValuesMap values = new NegatableValuesMap();
|
||||
final ClauseType type = ClauseType.of(clauseType);
|
||||
final ClauseType negatedType = type.negate();
|
||||
if (this.containsKey(type))
|
||||
{
|
||||
values.put(false, this.get(type));
|
||||
}
|
||||
if (this.containsKey(negatedType))
|
||||
{
|
||||
values.put(true, this.get(negatedType));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public MultiTypeNegatableValuesMap getExpectedValuesForAllOf(final int... clauseTypes)
|
||||
{
|
||||
verifyAllClausesPresence(clauseTypes);
|
||||
return getExpectedValuesFor(clauseTypes);
|
||||
}
|
||||
|
||||
public MultiTypeNegatableValuesMap getExpectedValuesForAnyOf(final int... clauseTypes)
|
||||
{
|
||||
verifyAnyClausesPresence(clauseTypes);
|
||||
return getExpectedValuesFor(clauseTypes);
|
||||
}
|
||||
|
||||
private MultiTypeNegatableValuesMap getExpectedValuesFor(final int... clauseTypes)
|
||||
{
|
||||
final MultiTypeNegatableValuesMap values = new MultiTypeNegatableValuesMap();
|
||||
Arrays.stream(clauseTypes).distinct().forEach(clauseType -> {
|
||||
final ClauseType type = ClauseType.of(clauseType);
|
||||
final ClauseType negatedType = type.negate();
|
||||
if (this.containsKey(type))
|
||||
{
|
||||
values.put(type, this.get(type));
|
||||
}
|
||||
if (this.containsKey(negatedType))
|
||||
{
|
||||
values.put(negatedType, this.get(negatedType));
|
||||
}
|
||||
});
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if all specified clause types are present in this map, if not than throw {@link InvalidQueryException}.
|
||||
*/
|
||||
private void verifyAllClausesPresence(final ClauseType... clauseTypes)
|
||||
{
|
||||
if (validateStrictly)
|
||||
{
|
||||
Arrays.stream(clauseTypes).distinct().forEach(clauseType -> {
|
||||
if (!this.containsType(clauseType))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(MISSING_CLAUSE_TYPE, this.name, WhereClauseParser.tokenNames[clauseType.getTypeNumber()]));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if all specified clause types are present in this map, if not than throw {@link InvalidQueryException}.
|
||||
* Exception is thrown when both, negated and non-negated types are missing.
|
||||
*/
|
||||
private void verifyAllClausesPresence(final int... clauseTypes)
|
||||
{
|
||||
if (validateStrictly)
|
||||
{
|
||||
Arrays.stream(clauseTypes).distinct().forEach(clauseType -> {
|
||||
if (!this.containsType(clauseType, false) && !this.containsType(clauseType, true))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(MISSING_CLAUSE_TYPE, this.name, WhereClauseParser.tokenNames[clauseType]));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if any of specified clause types are present in this map, if not than throw {@link InvalidQueryException}.
|
||||
*/
|
||||
private void verifyAnyClausesPresence(final ClauseType... clauseTypes)
|
||||
{
|
||||
if (validateStrictly)
|
||||
{
|
||||
if (!this.containsAnyOfTypes(clauseTypes))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(MISSING_ANY_CLAUSE_OF_TYPE,
|
||||
this.name, Arrays.stream(clauseTypes).map(type -> WhereClauseParser.tokenNames[type.getTypeNumber()]).collect(Collectors.toList())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if any of specified clause types are present in this map, if not than throw {@link InvalidQueryException}.
|
||||
* Exception is thrown when both, negated and non-negated types are missing.
|
||||
*/
|
||||
private void verifyAnyClausesPresence(final int... clauseTypes)
|
||||
{
|
||||
if (validateStrictly)
|
||||
{
|
||||
final Collection<ClauseType> expectedTypes = Arrays.stream(clauseTypes)
|
||||
.distinct()
|
||||
.boxed()
|
||||
.flatMap(type -> Stream.of(ClauseType.of(type), ClauseType.of(type, true)))
|
||||
.collect(Collectors.toSet());
|
||||
if (!this.containsAnyOfTypes(expectedTypes.toArray(ClauseType[]::new)))
|
||||
{
|
||||
throw new InvalidQueryException(String.format(MISSING_ANY_CLAUSE_OF_TYPE,
|
||||
this.name, Arrays.stream(clauseTypes).mapToObj(type -> WhereClauseParser.tokenNames[type]).collect(Collectors.toList())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ClauseType
|
||||
{
|
||||
EQUALS(WhereClauseParser.EQUALS),
|
||||
NOT_EQUALS(WhereClauseParser.EQUALS, true),
|
||||
GREATER_THAN(WhereClauseParser.GREATERTHAN),
|
||||
NOT_GREATER_THAN(WhereClauseParser.GREATERTHAN, true),
|
||||
LESS_THAN(WhereClauseParser.LESSTHAN),
|
||||
NOT_LESS_THAN(WhereClauseParser.LESSTHAN, true),
|
||||
GREATER_THAN_OR_EQUALS(WhereClauseParser.GREATERTHANOREQUALS),
|
||||
NOT_GREATER_THAN_OR_EQUALS(WhereClauseParser.GREATERTHANOREQUALS, true),
|
||||
LESS_THAN_OR_EQUALS(WhereClauseParser.LESSTHANOREQUALS),
|
||||
NOT_LESS_THAN_OR_EQUALS(WhereClauseParser.LESSTHANOREQUALS, true),
|
||||
BETWEEN(WhereClauseParser.BETWEEN),
|
||||
NOT_BETWEEN(WhereClauseParser.BETWEEN, true),
|
||||
IN(WhereClauseParser.IN),
|
||||
NOT_IN(WhereClauseParser.IN, true),
|
||||
MATCHES(WhereClauseParser.MATCHES),
|
||||
NOT_MATCHES(WhereClauseParser.MATCHES, true),
|
||||
EXISTS(WhereClauseParser.EXISTS),
|
||||
NOT_EXISTS(WhereClauseParser.EXISTS, true);
|
||||
|
||||
private final int typeNumber;
|
||||
private final boolean negated;
|
||||
|
||||
ClauseType(final int typeNumber)
|
||||
{
|
||||
this.typeNumber = typeNumber;
|
||||
this.negated = false;
|
||||
}
|
||||
|
||||
ClauseType(final int typeNumber, final boolean negated)
|
||||
{
|
||||
this.typeNumber = typeNumber;
|
||||
this.negated = negated;
|
||||
}
|
||||
|
||||
public static ClauseType of(final int type)
|
||||
{
|
||||
return of(type, false);
|
||||
}
|
||||
|
||||
public static ClauseType of(final int type, final boolean negated)
|
||||
{
|
||||
return Arrays.stream(ClauseType.values())
|
||||
.filter(clauseType -> clauseType.typeNumber == type && clauseType.negated == negated)
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
public ClauseType negate()
|
||||
{
|
||||
return of(typeNumber, !negated);
|
||||
}
|
||||
|
||||
public int getTypeNumber()
|
||||
{
|
||||
return typeNumber;
|
||||
}
|
||||
|
||||
public boolean isNegated()
|
||||
{
|
||||
return negated;
|
||||
}
|
||||
}
|
||||
|
||||
public static class NegatableValuesMap extends HashMap<Boolean, Collection<String>>
|
||||
{
|
||||
public Collection<String> skipNegated()
|
||||
{
|
||||
return this.get(false);
|
||||
}
|
||||
|
||||
public Collection<String> onlyNegated()
|
||||
{
|
||||
return this.get(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultiTypeNegatableValuesMap extends HashMap<ClauseType, Collection<String>>
|
||||
{
|
||||
public Map<Integer, Collection<String>> skipNegated()
|
||||
{
|
||||
return this.keySet().stream()
|
||||
.filter(not(ClauseType::isNegated))
|
||||
.collect(Collectors.toMap(key -> key.typeNumber, this::get));
|
||||
}
|
||||
|
||||
public Collection<String> skipNegated(final int clauseType)
|
||||
{
|
||||
return this.get(ClauseType.of(clauseType));
|
||||
}
|
||||
|
||||
public Map<Integer, Collection<String>> onlyNegated()
|
||||
{
|
||||
return this.keySet().stream()
|
||||
.filter(not(ClauseType::isNegated))
|
||||
.collect(Collectors.toMap(key -> key.typeNumber, this::get));
|
||||
}
|
||||
|
||||
public Collection<String> onlyNegated(final int clauseType)
|
||||
{
|
||||
return this.get(ClauseType.of(clauseType, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,32 @@
|
||||
/*
|
||||
* #%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.workflow.api.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -52,7 +51,7 @@ import org.apache.commons.beanutils.ConvertUtils;
|
||||
* {@link InvalidArgumentException} is thrown unless the method
|
||||
* {@link #handleUnmatchedComparison(int, String, String)} returns true (default
|
||||
* implementation returns false).
|
||||
*
|
||||
*
|
||||
* @author Frederik Heremans
|
||||
* @author Tijs Rademakers
|
||||
*/
|
||||
@@ -73,21 +72,21 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
private Map<String, String> equalsProperties;
|
||||
|
||||
private Map<String, String> matchesProperties;
|
||||
|
||||
|
||||
private Map<String, String> greaterThanProperties;
|
||||
|
||||
|
||||
private Map<String, String> greaterThanOrEqualProperties;
|
||||
|
||||
|
||||
private Map<String, String> lessThanProperties;
|
||||
|
||||
|
||||
private Map<String, String> lessThanOrEqualProperties;
|
||||
|
||||
|
||||
private List<QueryVariableHolder> variableProperties;
|
||||
|
||||
|
||||
private boolean variablesEnabled;
|
||||
|
||||
|
||||
private NamespaceService namespaceService;
|
||||
|
||||
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
public MapBasedQueryWalker(Set<String> supportedEqualsParameters, Set<String> supportedMatchesParameters)
|
||||
@@ -133,7 +132,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
lessThanOrEqualProperties = new HashMap<String, String>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void enableVariablesSupport(NamespaceService namespaceService, DictionaryService dictionaryService)
|
||||
{
|
||||
variablesEnabled = true;
|
||||
@@ -149,7 +148,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
this.dictionaryService = dictionaryService;
|
||||
variableProperties = new ArrayList<QueryVariableHolder>();
|
||||
}
|
||||
|
||||
|
||||
public List<QueryVariableHolder> getVariableProperties() {
|
||||
return variableProperties;
|
||||
}
|
||||
@@ -159,9 +158,9 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
{
|
||||
if(negated)
|
||||
{
|
||||
throw new InvalidArgumentException("Cannot use negated matching for property: " + property);
|
||||
throw new InvalidArgumentException("Cannot use negated matching for property: " + property);
|
||||
}
|
||||
if (variablesEnabled && property.startsWith("variables/"))
|
||||
if (variablesEnabled && property.startsWith("variables/"))
|
||||
{
|
||||
processVariable(property, value, WhereClauseParser.MATCHES);
|
||||
}
|
||||
@@ -171,19 +170,19 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException("Cannot use matching for property: " + property);
|
||||
throw new InvalidArgumentException("Cannot use matching for property: " + property);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void comparison(int type, String propertyName, String propertyValue, boolean negated)
|
||||
{
|
||||
if (variablesEnabled && propertyName.startsWith("variables/"))
|
||||
if (variablesEnabled && propertyName.startsWith("variables/"))
|
||||
{
|
||||
processVariable(propertyName, propertyValue, type);
|
||||
processVariable(propertyName, propertyValue, type);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boolean throwError = false;
|
||||
if (type == WhereClauseParser.EQUALS)
|
||||
{
|
||||
@@ -193,7 +192,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
}
|
||||
else
|
||||
{
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
else if (type == WhereClauseParser.MATCHES)
|
||||
@@ -204,7 +203,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
}
|
||||
else
|
||||
{
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
else if (type == WhereClauseParser.GREATERTHAN)
|
||||
@@ -215,7 +214,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
}
|
||||
else
|
||||
{
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
else if (type == WhereClauseParser.GREATERTHANOREQUALS)
|
||||
@@ -226,7 +225,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
}
|
||||
else
|
||||
{
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
else if (type == WhereClauseParser.LESSTHAN)
|
||||
@@ -237,7 +236,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
}
|
||||
else
|
||||
{
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
else if (type == WhereClauseParser.LESSTHANOREQUALS)
|
||||
@@ -248,7 +247,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
}
|
||||
else
|
||||
{
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -256,24 +255,15 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
throwError = !handleUnmatchedComparison(type, propertyName, propertyValue);
|
||||
}
|
||||
|
||||
if (throwError)
|
||||
{
|
||||
throw new InvalidArgumentException("framework.exception.InvalidProperty", new Object[] {propertyName, propertyValue, WhereClauseParser.tokenNames[type]});
|
||||
if (throwError)
|
||||
{
|
||||
throw new InvalidArgumentException("framework.exception.InvalidProperty", new Object[] {propertyName, propertyValue, WhereClauseParser.tokenNames[type]});
|
||||
}
|
||||
else if (negated)
|
||||
{
|
||||
// Throw error for the unsupported negation only if the property was valid for comparison, show the more meaningful error first.
|
||||
throw new InvalidArgumentException("Cannot use NOT for " + WhereClauseParser.tokenNames[type] + " comparison.");
|
||||
}
|
||||
else if (negated)
|
||||
{
|
||||
// Throw error for the unsupported negation only if the property was valid for comparison, show the more meaningful error first.
|
||||
throw new InvalidArgumentException("Cannot use NOT for " + WhereClauseParser.tokenNames[type] + " comparison.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get expected value for property and comparison type. This class supports only non-negated comparisons, thus parameter negated is ignored in bellow method.
|
||||
*/
|
||||
@Override
|
||||
public Collection<String> getProperty(String propertyName, int type, boolean negated)
|
||||
{
|
||||
return Set.of(this.getProperty(propertyName, type));
|
||||
}
|
||||
|
||||
public String getProperty(String propertyName, int type)
|
||||
@@ -310,7 +300,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
|
||||
/**
|
||||
* Get the property value, converted to the requested type.
|
||||
*
|
||||
*
|
||||
* @param propertyName name of the parameter
|
||||
* @param type int
|
||||
* @param returnType type of object to return
|
||||
@@ -344,7 +334,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
{
|
||||
// Conversion failed, wrap in Illegal
|
||||
throw new InvalidArgumentException("Query property value for '" + propertyName + "' should be a valid "
|
||||
+ returnType.getSimpleName());
|
||||
+ returnType.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,7 +345,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
// method indicates that AND is
|
||||
// supported. OR is not supported at the same time.
|
||||
}
|
||||
|
||||
|
||||
protected void processVariable(String propertyName, String propertyValue, int type)
|
||||
{
|
||||
String localPropertyName = propertyName.replaceFirst("variables/", "");
|
||||
@@ -363,25 +353,25 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
DataTypeDefinition dataTypeDefinition = null;
|
||||
// variable scope global is default
|
||||
String scopeDef = "global";
|
||||
|
||||
|
||||
// look for variable scope
|
||||
if (localPropertyName.contains("local/"))
|
||||
{
|
||||
scopeDef = "local";
|
||||
localPropertyName = localPropertyName.replaceFirst("local/", "");
|
||||
}
|
||||
|
||||
|
||||
if (localPropertyName.contains("global/"))
|
||||
{
|
||||
localPropertyName = localPropertyName.replaceFirst("global/", "");
|
||||
}
|
||||
|
||||
|
||||
// look for variable type definition
|
||||
if ((propertyValue.contains("_") || propertyValue.contains(":")) && propertyValue.contains(" "))
|
||||
if ((propertyValue.contains("_") || propertyValue.contains(":")) && propertyValue.contains(" "))
|
||||
{
|
||||
int indexOfSpace = propertyValue.indexOf(' ');
|
||||
if ((propertyValue.contains("_") && indexOfSpace > propertyValue.indexOf("_")) ||
|
||||
(propertyValue.contains(":") && indexOfSpace > propertyValue.indexOf(":")))
|
||||
if ((propertyValue.contains("_") && indexOfSpace > propertyValue.indexOf("_")) ||
|
||||
(propertyValue.contains(":") && indexOfSpace > propertyValue.indexOf(":")))
|
||||
{
|
||||
String typeDef = propertyValue.substring(0, indexOfSpace);
|
||||
try
|
||||
@@ -396,7 +386,7 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dataTypeDefinition != null && "java.util.Date".equalsIgnoreCase(dataTypeDefinition.getJavaClassName()))
|
||||
{
|
||||
// fix for different ISO 8601 Date format classes in Alfresco (org.alfresco.util and Spring Surf)
|
||||
@@ -406,18 +396,18 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
{
|
||||
actualValue = DefaultTypeConverter.INSTANCE.convert(dataTypeDefinition, propertyValue);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
actualValue = propertyValue;
|
||||
}
|
||||
|
||||
|
||||
variableProperties.add(new QueryVariableHolder(localPropertyName, type, actualValue, scopeDef));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when unsupported property is encountered or comparison operator
|
||||
* other than equals.
|
||||
*
|
||||
*
|
||||
* @return true, if the comparison is handles successfully. False, if an
|
||||
* exception should be thrown because the comparison can't be
|
||||
* handled.
|
||||
@@ -426,25 +416,25 @@ public class MapBasedQueryWalker extends WalkerCallbackAdapter
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static class QueryVariableHolder implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
private String propertyName;
|
||||
private int operator;
|
||||
private Object propertyValue;
|
||||
private String scope;
|
||||
|
||||
|
||||
public QueryVariableHolder() {}
|
||||
|
||||
|
||||
public QueryVariableHolder(String propertyName, int operator, Object propertyValue, String scope) {
|
||||
this.propertyName = propertyName;
|
||||
this.operator = operator;
|
||||
this.propertyValue = propertyValue;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
|
||||
public String getPropertyName()
|
||||
{
|
||||
return propertyName;
|
||||
|
||||
@@ -856,9 +856,7 @@
|
||||
<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" />
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="Tags" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user