diff --git a/e2e-test/src/test/java/org/alfresco/test/search/functional/AbstractE2EFunctionalTest.java b/e2e-test/src/test/java/org/alfresco/test/search/functional/AbstractE2EFunctionalTest.java
index 81dd4430b..7a26b8b7d 100644
--- a/e2e-test/src/test/java/org/alfresco/test/search/functional/AbstractE2EFunctionalTest.java
+++ b/e2e-test/src/test/java/org/alfresco/test/search/functional/AbstractE2EFunctionalTest.java
@@ -83,7 +83,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringContextTests
{
/** The number of retries that a query will be tried before giving up. */
- protected static final int SEARCH_MAX_ATTEMPTS = 60;
+ protected static final int SEARCH_MAX_ATTEMPTS = 120;
private static final Logger LOGGER = LogFactory.getLogger();
diff --git a/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/AbstractSearchServicesE2ETest.java b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/AbstractSearchServicesE2ETest.java
index 4ebb66e9f..9bc8ca2ce 100644
--- a/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/AbstractSearchServicesE2ETest.java
+++ b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/AbstractSearchServicesE2ETest.java
@@ -2,23 +2,23 @@
* #%L
* Alfresco Search Services E2E Test
* %%
- * Copyright (C) 2005 - 2020 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
- * the paid license agreement will prevail. Otherwise, the software is
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
- *
+ *
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see .
* #L%
@@ -30,6 +30,7 @@ import org.alfresco.test.search.functional.AbstractE2EFunctionalTest;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.FolderModel;
+import org.testng.Assert;
import static java.util.List.of;
@@ -47,10 +48,15 @@ public abstract class AbstractSearchServicesE2ETest extends AbstractE2EFunctiona
{
private static final String SEARCH_DATA_SAMPLE_FOLDER = "FolderSearch";
+ /** The maximum time to wait for content indexing to complete (in ms). */
+ private static final int MAX_TIME = 120 * 1000;
+ /** The frequency to check the report (in ms). */
+ private static final int RETRY_INTERVAL = 30000;
+
protected FileModel file, file2, file3, file4;
protected FolderModel folder;
- public void searchServicesDataPreparation()
+ public void searchServicesDataPreparation() throws InterruptedException
{
/*
* Create the following file structure for preconditions :
@@ -71,20 +77,31 @@ public abstract class AbstractSearchServicesE2ETest extends AbstractE2EFunctiona
file = new FileModel("pangram.txt", "pangram" + title, description, FileType.TEXT_PLAIN,
description + " The quick brown fox jumps over the lazy dog");
- file2 = new FileModel("cars.txt", "cars" + title, description, FileType.TEXT_PLAIN,
- "The landrover discovery is not a sports car ");
+ file2 = new FileModel("cars.PDF", "cars", description, FileType.TEXT_PLAIN,
+ "The landrover discovery is not a sports car");
- file3 = new FileModel("alfresco.txt", "alfresco", "alfresco", FileType.TEXT_PLAIN,
+ file3 = new FileModel("alfresco.docx", "alfresco", "alfresco", FileType.TEXT_PLAIN,
"Alfresco text file for search ");
- file4 = new FileModel(unique_searchString + ".txt", "uniquee" + title, description, FileType.TEXT_PLAIN,
+ file4 = new FileModel(unique_searchString + ".ODT", "uniquee" + title, description, FileType.TEXT_PLAIN,
"Unique text file for search ");
of(file, file2, file3, file4).forEach(
f -> dataContent.usingUser(testUser).usingSite(testSite).usingResource(folder).createContent(f)
- );
-
+ );
waitForMetadataIndexing(file4.getName(), true);
}
+
+ protected FileModel createFileWithProvidedText(String filename, String providedText) throws InterruptedException
+ {
+ String title = "Title: File containing " + providedText;
+ String description = "Description: Contains provided string: " + providedText;
+ FileModel uniqueFile = new FileModel(filename, title, description, FileType.TEXT_PLAIN,
+ "The content " + providedText + " is a provided string");
+ dataContent.usingUser(testUser).usingSite(testSite).usingResource(folder).createContent(uniqueFile);
+ Assert.assertTrue(waitForContentIndexing(providedText, true));
+
+ return uniqueFile;
+ }
}
diff --git a/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchCasesTest.java b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchCasesTest.java
new file mode 100644
index 000000000..429c45206
--- /dev/null
+++ b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchCasesTest.java
@@ -0,0 +1,336 @@
+/*
+ * #%L
+ * Alfresco Search Services E2E Test
+ * %%
+ * Copyright (C) 2005 - 2022 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.test.search.functional.searchServices.search;
+
+import org.alfresco.rest.search.FacetFieldBucket;
+import org.alfresco.rest.search.RestRequestFacetFieldModel;
+import org.alfresco.rest.search.RestRequestFacetFieldsModel;
+import org.alfresco.rest.search.RestRequestQueryModel;
+import org.alfresco.rest.search.RestResultBucketsModel;
+import org.alfresco.rest.search.SearchRequest;
+import org.alfresco.rest.search.SearchResponse;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.hamcrest.Matchers;
+import org.springframework.http.HttpStatus;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SearchCasesTest extends AbstractSearchServicesE2ETest
+{
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ searchServicesDataPreparation();
+ Assert.assertTrue(waitForContentIndexing(file4.getContent(), true));
+ }
+
+ @Test(priority=1)
+ public void testSearchNameField()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:pangram");
+ queryReq.setUserQuery("pangram");
+ searchReq.setQuery(queryReq);
+ SearchResponse response = queryAsUser(testUser, "cm:name:pangram");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=2)
+ public void testSearchTitleField()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:title:cars");
+ queryReq.setUserQuery("cars");
+ searchReq.setQuery(queryReq);
+ SearchResponse response2 = queryAsUser(testUser, "cm:title:cars");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response2.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=3)
+ public void testSearchDescriptionField()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:description:alfresco");
+ queryReq.setUserQuery("alfresco");
+ searchReq.setQuery(queryReq);
+ SearchResponse response3 = queryAsUser(testUser, "cm:description:alfresco");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response3.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=4)
+ public void testSearchContentField()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:content:unique");
+ queryReq.setUserQuery("unique");
+ searchReq.setQuery(queryReq);
+ SearchResponse response4 = queryAsUser(testUser, "cm:content:unique");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response4.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=5)
+ public void testSearchUpdateContent() throws InterruptedException
+ {
+ String originalText = String.valueOf(System.currentTimeMillis());
+ String newText = String.valueOf(System.currentTimeMillis() + 300000);
+
+ // Create test file to be accessed only by this test method to avoid inconsistent results when querying updates
+ FileModel updateableFile = createFileWithProvidedText(originalText + ".txt", originalText);
+
+ // Verify that 1 occurrence of the original text is found
+ SearchResponse response1 = queryAsUser(testUser, "cm:content:" + originalText);
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ Assert.assertEquals(response1.getEntries().size(), 1, "Expected 1 original text before update");
+
+ // Verify that 0 occurrences of the replacement text are found
+ SearchResponse response2 = queryAsUser(testUser, "cm:content:" + newText);
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ Assert.assertEquals(response2.getEntries().size(), 0, "Expected 0 new text before update");
+
+ // Update the content
+ String newContent = "Description: Contains provided string: " + newText;
+ dataContent.usingUser(adminUserModel).usingSite(testSite).usingResource(updateableFile)
+ .updateContent(newContent);
+ Assert.assertTrue(waitForContentIndexing(newText, true));
+
+ // Verify that 0 occurrences of the original text are found
+ SearchResponse response3 = queryAsUser(testUser, "cm:content:" + originalText);
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ Assert.assertEquals(response3.getEntries().size(), 0, "Expected 0 original text after update");
+
+ // Verify that 1 occurrence of the replacement text is found
+ SearchResponse response4 = queryAsUser(testUser, "cm:content:" + newText);
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ Assert.assertEquals(response4.getEntries().size(), 1, "Expected 1 new text before update");
+ }
+
+ @Test(priority=6)
+ public void testSearchTextFile()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:pangram.txt");
+ queryReq.setUserQuery("pangram.txt");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "cm:name:pangram.txt");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=7)
+ public void testSearchPDFFile()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:cars.PDF");
+ queryReq.setUserQuery("cars.PDF");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "cm:name:cars.PDF");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=8)
+ public void testSearchDocxFile()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:alfresco.docx");
+ queryReq.setUserQuery("alfresco.docx");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "cm:name:alfresco.docx");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=9)
+ public void testSearchODTFile()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:unique.ODT");
+ queryReq.setUserQuery("unique.ODT");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "cm:name:unique.ODT");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ /**
+ * {
+ * "query": {
+ * "query": "*"
+ * },
+ * "facetFields": {
+ * "facets": [{"field": "cm:mimetype"},{"field": "modifier"}]
+ * }
+ * }
+ */
+ @Test(priority=10)
+ public void searchWithFacedFields() throws InterruptedException
+ {
+ String uniqueText = String.valueOf(System.currentTimeMillis());
+
+ // Create test file to be accessed only by this test method to avoid inconsistent results
+ createFileWithProvidedText(uniqueText + ".ODT", uniqueText);
+
+ SearchRequest query = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:content:" + uniqueText);
+ query.setQuery(queryReq);
+
+ RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel();
+ List facets = new ArrayList<>();
+ facets.add(new RestRequestFacetFieldModel("cm:mimetype"));
+ facets.add(new RestRequestFacetFieldModel("modifier"));
+ facetFields.setFacets(facets);
+ query.setFacetFields(facetFields);
+
+ SearchResponse response = query(query);
+
+ Assert.assertNotNull(response.getContext().getFacetsFields());
+ Assert.assertFalse(response.getContext().getFacetsFields().isEmpty());
+ Assert.assertNull(response.getContext().getFacetQueries());
+ Assert.assertNull(response.getContext().getFacets());
+
+ RestResultBucketsModel model = response.getContext().getFacetsFields().get(0);
+ Assert.assertEquals(model.getLabel(), "modifier");
+
+ model.assertThat().field("label").is("modifier");
+ FacetFieldBucket bucket1 = model.getBuckets().get(0);
+ bucket1.assertThat().field("label").is(testUser.getUsername());
+ bucket1.assertThat().field("display").is("FN-" + testUser.getUsername() + " LN-" + testUser.getUsername());
+ bucket1.assertThat().field("filterQuery").is("modifier:\"" + testUser.getUsername() + "\"");
+ bucket1.assertThat().field("count").is(1);
+ }
+
+ @Test(priority=12)
+ public void testSearchPhraseQueries()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:alfresco");
+ queryReq.setUserQuery("alfresco");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "The quick brown fox jumps over the lazy dog");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=13)
+ public void testSearchExactTermQueries()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:alfresco");
+ queryReq.setUserQuery("alfresco");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "=alfresco");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=14)
+ public void testSearchConjunctionQueries()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:unique");
+ queryReq.setUserQuery("unique");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "unique AND search");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=15)
+ public void testSearchDisjunctionQueries()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:cars");
+ queryReq.setUserQuery("cars");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "file OR discovery");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=16)
+ public void testSearchNegationQueries()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:pangram");
+ queryReq.setUserQuery("pangram");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "pangram NOT pan");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=17)
+ public void testSearchWildcardQueries()
+ {
+ SearchRequest searchReq = new SearchRequest();
+ RestRequestQueryModel queryReq = new RestRequestQueryModel();
+ queryReq.setQuery("cm:name:alfresco");
+ queryReq.setUserQuery("alfresco");
+ searchReq.setQuery(queryReq);
+ SearchResponse response6 = queryAsUser(testUser, "al?res*");
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ response6.assertThat().entriesListIsNotEmpty();
+ }
+
+ @Test(priority=18)
+ public void searchSpecialCharacters()
+ {
+ String specialCharfileName = "è¥äæ§ç§-åæ.pdf";
+ FileModel file = new FileModel(specialCharfileName, "è¥äæ§ç§-忬¯¸" + "è¥äæ§ç§-忬¯¸", "è¥äæ§ç§-忬¯¸", FileType.TEXT_PLAIN,
+ "Text file with Special Characters: " + specialCharfileName);
+ dataContent.usingUser(testUser).usingSite(testSite).createContent(file);
+
+ waitForIndexing(file.getName(), true);
+
+ SearchRequest searchReq = createQuery("name:'" + specialCharfileName + "'");
+ SearchResponse nodes = query(searchReq);
+
+ restClient.assertStatusCodeIs(HttpStatus.OK);
+ nodes.assertThat().entriesListIsNotEmpty();
+
+ restClient.onResponse().assertThat().body("list.entries.entry[0].name", Matchers.equalToIgnoringCase(specialCharfileName));
+ }
+}
diff --git a/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchTest.java b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchTest.java
index 3ecf2d9e2..6043656e7 100644
--- a/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchTest.java
+++ b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchTest.java
@@ -115,9 +115,9 @@ public class SearchTest extends AbstractSearchServicesE2ETest
public void searchWithOneSortClause()
{
// Tests the ascending order first
- List expectedOrder = asList("alfresco.txt", "cars.txt", "pangram.txt");
+ List expectedOrder = asList("alfresco.docx", "cars.PDF", "pangram.txt");
- SearchRequest searchRequest = createQuery("cm_name:alfresco\\.txt cm_name:cars\\.txt cm_name:pangram\\.txt");
+ SearchRequest searchRequest = createQuery("cm_name:alfresco\\.docx cm_name:cars\\.PDF cm_name:pangram\\.txt");
searchRequest.addSortClause("FIELD", "name", true);
RestRequestFilterQueryModel filters = new RestRequestFilterQueryModel();
@@ -162,9 +162,9 @@ public class SearchTest extends AbstractSearchServicesE2ETest
public void searchWithTwoSortClauses()
{
// Tests the ascending order first
- List expectedOrder = asList("alfresco.txt", "cars.txt", "pangram.txt");
+ List expectedOrder = asList("alfresco.docx", "cars.PDF", "pangram.txt");
- SearchRequest searchRequest = createQuery("cm_name:alfresco\\.txt cm_name:cars\\.txt cm_name:pangram\\.txt");
+ SearchRequest searchRequest = createQuery("cm_name:alfresco\\.docx cm_name:cars\\.PDF cm_name:pangram\\.txt");
searchRequest.addSortClause("FIELD", "name", true);
searchRequest.addSortClause("FIELD", "createdByUser.id", true);
diff --git a/e2e-test/src/test/resources/PipelineSuite.xml b/e2e-test/src/test/resources/PipelineSuite.xml
new file mode 100644
index 000000000..8716f6015
--- /dev/null
+++ b/e2e-test/src/test/resources/PipelineSuite.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+