mirror of
https://github.com/Alfresco/SearchServices.git
synced 2025-09-17 14:21:20 +00:00
Merge branch 'master' of git.alfresco.com:search_discovery/insightengine into fix/SEARCH-1994
This commit is contained in:
@@ -11,9 +11,9 @@
|
|||||||
<name>Search Analytics E2E Tests</name>
|
<name>Search Analytics E2E Tests</name>
|
||||||
<description>Test Project to test Search Service and Analytics Features on a complete setup of Alfresco, Share</description>
|
<description>Test Project to test Search Service and Analytics Features on a complete setup of Alfresco, Share</description>
|
||||||
<properties>
|
<properties>
|
||||||
<tas.rest.api.version>1.18</tas.rest.api.version>
|
<tas.rest.api.version>1.20</tas.rest.api.version>
|
||||||
<tas.cmis.api.version>1.10</tas.cmis.api.version>
|
<tas.cmis.api.version>1.11</tas.cmis.api.version>
|
||||||
<tas.utility.version>3.0.15</tas.utility.version>
|
<tas.utility.version>3.0.16</tas.utility.version>
|
||||||
<rm.version>3.2.0</rm.version>
|
<rm.version>3.2.0</rm.version>
|
||||||
<suiteXmlFile>src/test/resources/SearchSuite.xml</suiteXmlFile>
|
<suiteXmlFile>src/test/resources/SearchSuite.xml</suiteXmlFile>
|
||||||
<test.exclude></test.exclude>
|
<test.exclude></test.exclude>
|
||||||
|
@@ -38,6 +38,7 @@ public class TestGroup
|
|||||||
public static final String ACS_61n = "ACS_61n"; // Alfresco Content Services 6.1 or above
|
public static final String ACS_61n = "ACS_61n"; // Alfresco Content Services 6.1 or above
|
||||||
public static final String ACS_611n = "ACS_611n"; // Alfresco Content Services 6.1.1 or above
|
public static final String ACS_611n = "ACS_611n"; // Alfresco Content Services 6.1.1 or above
|
||||||
public static final String ACS_62n = "ACS_62n"; // Alfresco Content Services 6.2 or above
|
public static final String ACS_62n = "ACS_62n"; // Alfresco Content Services 6.2 or above
|
||||||
|
public static final String ACS_63n = "ACS_63n"; // Alfresco Content Services 6.3 or above
|
||||||
|
|
||||||
public static final String AGS_302 = "AGS_302"; // Alfresco governance Services 3.0.2 or above
|
public static final String AGS_302 = "AGS_302"; // Alfresco governance Services 3.0.2 or above
|
||||||
|
|
||||||
|
@@ -6,6 +6,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.test.search.functional;
|
package org.alfresco.test.search.functional;
|
||||||
|
|
||||||
|
import static java.util.Optional.ofNullable;
|
||||||
|
|
||||||
|
import static lombok.AccessLevel.PROTECTED;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import org.alfresco.cmis.CmisWrapper;
|
import org.alfresco.cmis.CmisWrapper;
|
||||||
import org.alfresco.dataprep.ContentService;
|
import org.alfresco.dataprep.ContentService;
|
||||||
import org.alfresco.dataprep.SiteService.Visibility;
|
import org.alfresco.dataprep.SiteService.Visibility;
|
||||||
@@ -38,15 +48,10 @@ import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
|
|||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.BeforeSuite;
|
import org.testng.annotations.BeforeSuite;
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import static java.util.Optional.ofNullable;
|
|
||||||
import static lombok.AccessLevel.PROTECTED;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author meenal bhave
|
* @author meenal bhave
|
||||||
*/
|
*/
|
||||||
@ContextConfiguration("classpath:alfresco-search-e2e-context.xml")
|
@ContextConfiguration ("classpath:alfresco-search-e2e-context.xml")
|
||||||
public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringContextTests
|
public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringContextTests
|
||||||
{
|
{
|
||||||
/** The number of retries that a query will be tried before giving up. */
|
/** The number of retries that a query will be tried before giving up. */
|
||||||
@@ -76,11 +81,11 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
protected CmisWrapper cmisApi;
|
protected CmisWrapper cmisApi;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
// @Getter(value = PROTECTED)
|
// @Getter(value = PROTECTED)
|
||||||
protected DataUser dataUser;
|
protected DataUser dataUser;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Getter(value = PROTECTED)
|
@Getter (value = PROTECTED)
|
||||||
private ContentService contentService;
|
private ContentService contentService;
|
||||||
|
|
||||||
protected UserModel testUser, adminUserModel, testUser2;
|
protected UserModel testUser, adminUserModel, testUser2;
|
||||||
@@ -93,9 +98,9 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
protected enum SearchLanguage {
|
protected enum SearchLanguage {
|
||||||
CMIS,
|
CMIS,
|
||||||
AFTS
|
AFTS
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeSuite(alwaysRun = true)
|
@BeforeSuite (alwaysRun = true)
|
||||||
public void beforeSuite() throws Exception
|
public void beforeSuite() throws Exception
|
||||||
{
|
{
|
||||||
super.springTestContextPrepareTestInstance();
|
super.springTestContextPrepareTestInstance();
|
||||||
@@ -104,7 +109,7 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
deployCustomModel("model/finance-model.xml");
|
deployCustomModel("model/finance-model.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeClass(alwaysRun = true)
|
@BeforeClass (alwaysRun = true)
|
||||||
public void setup()
|
public void setup()
|
||||||
{
|
{
|
||||||
serverHealth.assertServerIsOnline();
|
serverHealth.assertServerIsOnline();
|
||||||
@@ -209,7 +214,7 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
customModel.setNodeRef(modelInRepo.getId());
|
customModel.setNodeRef(modelInRepo.getId());
|
||||||
customModel.setNodeRef(customModel.getNodeRefWithoutVersion());
|
customModel.setNodeRef(customModel.getNodeRefWithoutVersion());
|
||||||
customModel.setCmisLocation(String.format("/Data Dictionary/Models/%s", fileName));
|
customModel.setCmisLocation(String.format("/Data Dictionary/Models/%s", fileName));
|
||||||
LOGGER.info("Custom Model file: " + customModel.getCmisLocation());
|
LOGGER.info("Custom Model file: " + customModel.getCmisLocation());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -240,8 +245,8 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
/**
|
/**
|
||||||
* Wait for Solr to finish indexing and search to return appropriate results
|
* Wait for Solr to finish indexing and search to return appropriate results
|
||||||
*
|
*
|
||||||
* @param userQuery Search Query
|
* @param userQuery Search Query
|
||||||
* @param contentToFind that's expected to be included / excluded from the results
|
* @param contentToFind that's expected to be included / excluded from the results
|
||||||
* @param expectedInResults Whether we expect the content in the results or not.
|
* @param expectedInResults Whether we expect the content in the results or not.
|
||||||
* @return true if search returns expected results, i.e. is given content is found or excluded from the results
|
* @return true if search returns expected results, i.e. is given content is found or excluded from the results
|
||||||
*/
|
*/
|
||||||
@@ -281,21 +286,21 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
/**
|
/**
|
||||||
* Method to check if the contentName is returned in the SearchResponse.
|
* Method to check if the contentName is returned in the SearchResponse.
|
||||||
*
|
*
|
||||||
* @param response the search response
|
* @param response the search response
|
||||||
* @param contentName the text we are using as matching/verifying criteria.
|
* @param contentName the text we are using as matching/verifying criteria.
|
||||||
* @return true if if the item with the contentName text is returned in the SearchResponse.
|
* @return true if if the item with the contentName text is returned in the SearchResponse.
|
||||||
*/
|
*/
|
||||||
public boolean isContentInSearchResponse(SearchResponse response, String contentName)
|
public boolean isContentInSearchResponse(SearchResponse response, String contentName)
|
||||||
{
|
{
|
||||||
return response.getEntries().stream()
|
return response.getEntries().stream()
|
||||||
.map(entry -> entry.getModel().getName())
|
.map(entry -> entry.getModel().getName())
|
||||||
.anyMatch(name -> name.equalsIgnoreCase(contentName) || contentName.isBlank());
|
.anyMatch(name -> name.equalsIgnoreCase(contentName) || contentName.isBlank());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for Solr to finish indexing: Indexing has caught up = true if search returns appropriate results
|
* Wait for Solr to finish indexing: Indexing has caught up = true if search returns appropriate results
|
||||||
*
|
*
|
||||||
* @param userQuery: search query, this can include the fieldname, unique search string will guarantee accurate results
|
* @param userQuery: search query, this can include the fieldname, unique search string will guarantee accurate results
|
||||||
* @param expectedInResults, true if entry is expected in the results set
|
* @param expectedInResults, true if entry is expected in the results set
|
||||||
* @return true (indexing is finished) if search returns appropriate results
|
* @return true (indexing is finished) if search returns appropriate results
|
||||||
*/
|
*/
|
||||||
@@ -333,8 +338,8 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
/**
|
/**
|
||||||
* Wait for Solr to finish indexing: Indexing has caught up = true if search returns appropriate results
|
* Wait for Solr to finish indexing: Indexing has caught up = true if search returns appropriate results
|
||||||
*
|
*
|
||||||
* @param fieldName: specific field to search for, e.g. name. When specified, the query will become: name:'userQuery'
|
* @param fieldName: specific field to search for, e.g. name. When specified, the query will become: name:'userQuery'
|
||||||
* @param userQuery: search string, unique search string will guarantee accurate results
|
* @param userQuery: search string, unique search string will guarantee accurate results
|
||||||
* @param expectedInResults, true if entry is expected in the results set
|
* @param expectedInResults, true if entry is expected in the results set
|
||||||
* @return true (indexing is finished) if search returns appropriate results
|
* @return true (indexing is finished) if search returns appropriate results
|
||||||
*/
|
*/
|
||||||
@@ -359,7 +364,7 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
/**
|
/**
|
||||||
* Run a search as given user and return the response
|
* Run a search as given user and return the response
|
||||||
*
|
*
|
||||||
* @param user: UserModel for the user you wish to run the query as
|
* @param user: UserModel for the user you wish to run the query as
|
||||||
* @param queryString: string to search for, unique search string will guarantee accurate results
|
* @param queryString: string to search for, unique search string will guarantee accurate results
|
||||||
* @return the search response from the API
|
* @return the search response from the API
|
||||||
*/
|
*/
|
||||||
@@ -374,8 +379,8 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a search with Spellcheck as given user and return the response
|
* Run a search with Spellcheck as given user and return the response
|
||||||
* @param user UserModel for the user you wish to run the query as
|
* @param user UserModel for the user you wish to run the query as
|
||||||
* @param queryModel The queryModel to search for, containing the query
|
* @param queryModel The queryModel to search for, containing the query
|
||||||
* @param spellcheckQuery The Spellcheck Model containing the query
|
* @param spellcheckQuery The Spellcheck Model containing the query
|
||||||
* @return the search response from the API
|
* @return the search response from the API
|
||||||
*/
|
*/
|
||||||
@@ -424,28 +429,76 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to test if the search query works and count matches where provided
|
* Helper method to test if the search query works and count matches where provided
|
||||||
* @param query: AFTS or cmis query string
|
*
|
||||||
|
* @param query: AFTS or cmis query string
|
||||||
* @param expectedCount: Only successful response is checked, when expectedCount is null (can not be exactly specified),
|
* @param expectedCount: Only successful response is checked, when expectedCount is null (can not be exactly specified),
|
||||||
* @return SearchResponse
|
* @return SearchResponse
|
||||||
*/
|
*/
|
||||||
protected SearchResponse testSearchQuery(String query, Integer expectedCount, SearchLanguage queryLanguage)
|
protected SearchResponse testSearchQuery(String query, Integer expectedCount, SearchLanguage queryLanguage)
|
||||||
|
{
|
||||||
|
SearchResponse response = performSearch(testUser, query, queryLanguage);
|
||||||
|
|
||||||
|
if (ofNullable(expectedCount).isPresent())
|
||||||
|
{
|
||||||
|
restClient.onResponse().assertThat().body("list.pagination.count", Matchers.equalTo(expectedCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to test if the search query returns the expected results in the order given.
|
||||||
|
*
|
||||||
|
* @param query: AFTS or cmis query string
|
||||||
|
* @param expectedNames: The ordered list of names expected to be returned,
|
||||||
|
* @return SearchResponse
|
||||||
|
*/
|
||||||
|
protected SearchResponse testSearchQueryOrdered(String query, List<String> expectedNames, SearchLanguage queryLanguage)
|
||||||
|
{
|
||||||
|
SearchResponse response = performSearch(testUser, query, queryLanguage);
|
||||||
|
|
||||||
|
List<String> names = response.getEntries().stream().map(s -> s.getModel().getName()).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Include lists in failure message as TestNG won't do this for lists.
|
||||||
|
assertEquals(names, expectedNames, "Unexpected results for query: " + query + " Expected: " + expectedNames + " but got " + names);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to test if the search query returns the expected set of results.
|
||||||
|
*
|
||||||
|
* @param query: AFTS or cmis query string
|
||||||
|
* @param expectedNames: The ordered list of names expected to be returned,
|
||||||
|
* @return SearchResponse
|
||||||
|
*/
|
||||||
|
protected SearchResponse testSearchQueryUnordered(String query, Set<String> expectedNames, SearchLanguage queryLanguage)
|
||||||
|
{
|
||||||
|
SearchResponse response = performSearch(testUser, query, queryLanguage);
|
||||||
|
|
||||||
|
Set<String> names = response.getEntries().stream().map(s -> s.getModel().getName()).collect(Collectors.toSet());
|
||||||
|
|
||||||
|
assertEquals(names, expectedNames, "Unexpected results for query: " + query);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchResponse performSearch(UserModel asUser, String query, SearchLanguage queryLanguage)
|
||||||
{
|
{
|
||||||
RestRequestQueryModel queryModel = new RestRequestQueryModel();
|
RestRequestQueryModel queryModel = new RestRequestQueryModel();
|
||||||
queryModel.setQuery(query);
|
queryModel.setQuery(query);
|
||||||
|
|
||||||
|
if (!ofNullable(asUser).isPresent())
|
||||||
|
{
|
||||||
|
asUser = testUser;
|
||||||
|
}
|
||||||
|
|
||||||
if (ofNullable(queryLanguage).isPresent())
|
if (ofNullable(queryLanguage).isPresent())
|
||||||
{
|
{
|
||||||
queryModel.setLanguage(queryLanguage.toString());
|
queryModel.setLanguage(queryLanguage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchResponse response = queryAsUser(testUser, queryModel);
|
SearchResponse response = queryAsUser(asUser, queryModel);
|
||||||
|
|
||||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
|
||||||
|
|
||||||
if (ofNullable(expectedCount).isPresent())
|
|
||||||
{
|
|
||||||
restClient.onResponse().assertThat().body("list.pagination.count", Matchers.equalTo(expectedCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -462,7 +515,7 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
RestRequestSpellcheckModel spellCheck = new RestRequestSpellcheckModel();
|
RestRequestSpellcheckModel spellCheck = new RestRequestSpellcheckModel();
|
||||||
spellCheck.setQuery(userQuery);
|
spellCheck.setQuery(userQuery);
|
||||||
|
|
||||||
UserModel searchUser = ofNullable(user).isPresent()? user: testUser;
|
UserModel searchUser = ofNullable(user).isPresent() ? user : testUser;
|
||||||
SearchRequest searchReq = new SearchRequest();
|
SearchRequest searchReq = new SearchRequest();
|
||||||
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
RestRequestQueryModel queryReq = new RestRequestQueryModel();
|
||||||
queryReq.setQuery(query);
|
queryReq.setQuery(query);
|
||||||
@@ -475,8 +528,8 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to check the spellcheck object returned in the Search Response
|
* Method to check the spellcheck object returned in the Search Response
|
||||||
* @param response SearchResponse
|
* @param response SearchResponse
|
||||||
* @param spellCheckType String Values: searchInsteadFor, didYouMean or null
|
* @param spellCheckType String Values: searchInsteadFor, didYouMean or null
|
||||||
* @param spellCheckSuggestion String Values: suggestion string or null
|
* @param spellCheckSuggestion String Values: suggestion string or null
|
||||||
*/
|
*/
|
||||||
public void testSearchSpellcheckResponse(SearchResponse response, String spellCheckType, String spellCheckSuggestion)
|
public void testSearchSpellcheckResponse(SearchResponse response, String spellCheckType, String spellCheckSuggestion)
|
||||||
|
@@ -0,0 +1,326 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd. All rights reserved.
|
||||||
|
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||||
|
* pursuant to a written agreement and any use of this program without such an
|
||||||
|
* agreement is prohibited.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.test.search.functional.searchServices.search;
|
||||||
|
|
||||||
|
import static java.util.List.of;
|
||||||
|
|
||||||
|
import static jersey.repackaged.com.google.common.collect.Sets.newHashSet;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.alfresco.rest.model.RestNodeAssociationModelCollection;
|
||||||
|
import org.alfresco.rest.model.RestNodeChildAssociationModel;
|
||||||
|
import org.alfresco.rest.search.SearchResponse;
|
||||||
|
import org.alfresco.search.TestGroup;
|
||||||
|
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 org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class tests AFTS Search In Field works
|
||||||
|
* Created for Search-840
|
||||||
|
*
|
||||||
|
* @author Meenal Bhave
|
||||||
|
*/
|
||||||
|
public class SearchAFTSInFieldTest extends AbstractE2EFunctionalTest
|
||||||
|
{
|
||||||
|
private FolderModel folder1, folder2;
|
||||||
|
private FileModel file1, file2, file3, file4, file5;
|
||||||
|
|
||||||
|
@BeforeClass(alwaysRun = true)
|
||||||
|
public void dataPreparation()
|
||||||
|
{
|
||||||
|
// Create Folders:
|
||||||
|
// Folder1: Expected to be found with file.txt
|
||||||
|
folder1 = new FolderModel("file txt folder");
|
||||||
|
dataContent.usingUser(testUser).usingSite(testSite).createFolder(folder1);
|
||||||
|
|
||||||
|
// Folder2: Not expected to be found with file.txt
|
||||||
|
folder2 = new FolderModel("txt files folder");
|
||||||
|
dataContent.usingUser(testUser).usingSite(testSite).createFolder(folder2);
|
||||||
|
|
||||||
|
// Create File(s): Expected to be found with file.txt
|
||||||
|
file1 = new FileModel("file.txt", "file.txt", "", FileType.TEXT_PLAIN, "file.txt");
|
||||||
|
|
||||||
|
file2 = new FileModel("1-file.txt", "1-file.txt", "", FileType.TEXT_PLAIN, "1-file.txt");
|
||||||
|
|
||||||
|
file3 = new FileModel("file1.txt", "file1.txt", "", FileType.TEXT_PLAIN, "file1.txt");
|
||||||
|
|
||||||
|
file4 = new FileModel("txt file", "txt file", "", FileType.TEXT_PLAIN, "txt file");
|
||||||
|
|
||||||
|
// Not Expected to be found with file.txt
|
||||||
|
file5 = new FileModel("txt files", "txt files", "", FileType.TEXT_PLAIN, "txt files");
|
||||||
|
|
||||||
|
of(file1, file2, file3, file4, file5).forEach(
|
||||||
|
f -> dataContent.usingUser(testUser).usingSite(testSite).usingResource(folder1).createContent(f));
|
||||||
|
|
||||||
|
waitForContentIndexing(file5.getContent(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 1, groups = { TestGroup.ACS_63n })
|
||||||
|
public void testSearchInFieldName()
|
||||||
|
{
|
||||||
|
// Field names in various formats
|
||||||
|
Stream<String> fieldNames = Stream.of("{http://www.alfresco.org/model/content/1.0}name",
|
||||||
|
"@{http://www.alfresco.org/model/content/1.0}name",
|
||||||
|
"cm_name",
|
||||||
|
"cm:name",
|
||||||
|
"@cm:name",
|
||||||
|
"name");
|
||||||
|
|
||||||
|
// For each field name, check that queries return consistent results with / out ''
|
||||||
|
fieldNames.forEach(fieldName ->
|
||||||
|
{
|
||||||
|
// Query string without quotes
|
||||||
|
String query = fieldName + ":file.txt";
|
||||||
|
|
||||||
|
Set<String> expectedNames = newHashSet();
|
||||||
|
expectedNames.add("file.txt"); // file1
|
||||||
|
expectedNames.add("1-file.txt"); // file2
|
||||||
|
expectedNames.add("file1.txt"); // file3
|
||||||
|
expectedNames.add("txt file"); // file4
|
||||||
|
expectedNames.add("file txt folder"); // folder1
|
||||||
|
|
||||||
|
testSearchQueryUnordered(query, expectedNames, SearchLanguage.AFTS);
|
||||||
|
|
||||||
|
// Query string in single quotes
|
||||||
|
query = fieldName + ":'file.txt'";
|
||||||
|
testSearchQueryUnordered(query, expectedNames, SearchLanguage.AFTS);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 2, groups = { TestGroup.ACS_63n })
|
||||||
|
public void testSearchInFieldTitle()
|
||||||
|
{
|
||||||
|
// Field names in various formats
|
||||||
|
Stream<String> fieldNames = Stream.of("{http://www.alfresco.org/model/content/1.0}title",
|
||||||
|
"@{http://www.alfresco.org/model/content/1.0}title",
|
||||||
|
"cm_title",
|
||||||
|
"cm:title",
|
||||||
|
"@cm:title");
|
||||||
|
|
||||||
|
// For each field name, check that queries return consistent results with / out ''
|
||||||
|
fieldNames.forEach(fieldName ->
|
||||||
|
{
|
||||||
|
String query = fieldName + ":" + file2.getName();
|
||||||
|
boolean fileFound = isContentInSearchResults(query, file2.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "File Not found for query: " + query);
|
||||||
|
|
||||||
|
testSearchQuery(query, 1, SearchLanguage.AFTS);
|
||||||
|
|
||||||
|
query = fieldName + ":'" + file2.getName() + "\'";
|
||||||
|
fileFound = isContentInSearchResults(query, file2.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "File Not found for query: " + query);
|
||||||
|
|
||||||
|
testSearchQuery(query, 1, SearchLanguage.AFTS);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 3, groups = { TestGroup.ACS_63n })
|
||||||
|
public void testSearchInFieldContent()
|
||||||
|
{
|
||||||
|
// Field names in various formats
|
||||||
|
List<String> fieldNames = new ArrayList<>();
|
||||||
|
fieldNames.add("TEXT");
|
||||||
|
fieldNames.add("{http://www.alfresco.org/model/dictionary/1.0}content");
|
||||||
|
fieldNames.add("cm:content");
|
||||||
|
fieldNames.add("d:content");
|
||||||
|
|
||||||
|
// For each field name, check that queries return consistent results with / out ''
|
||||||
|
fieldNames.forEach(fieldName ->
|
||||||
|
{
|
||||||
|
String query = fieldName + ":" + file3.getContent();
|
||||||
|
boolean fileFound = isContentInSearchResults(query, file3.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "File Not found for query: " + query);
|
||||||
|
|
||||||
|
Integer resultCount1 = testSearchQuery(query, null, SearchLanguage.AFTS).getPagination().getTotalItems();
|
||||||
|
|
||||||
|
query = fieldName + ":'" + file3.getContent() + "\'";
|
||||||
|
fileFound = isContentInSearchResults(query, file3.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "File Not found for query: " + query);
|
||||||
|
|
||||||
|
testSearchQuery(query, resultCount1, SearchLanguage.AFTS).getPagination().getTotalItems();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 4)
|
||||||
|
public void testSearchInFieldSITE()
|
||||||
|
{
|
||||||
|
String query = "SITE:" + testSite.getId();
|
||||||
|
boolean fileFound = isContentInSearchResults(query, folder1.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "Site Not found for query: " + query);
|
||||||
|
|
||||||
|
Integer resultCount1 = testSearchQuery(query, 8, SearchLanguage.AFTS).getPagination().getTotalItems();
|
||||||
|
|
||||||
|
query = "SITE:'" + testSite.getId() + "\'";
|
||||||
|
fileFound = isContentInSearchResults(query, folder1.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "Site Not found for query: " + query);
|
||||||
|
|
||||||
|
testSearchQuery(query, resultCount1, SearchLanguage.AFTS).getPagination().getTotalItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 5)
|
||||||
|
public void testSearchInFieldTYPE()
|
||||||
|
{
|
||||||
|
// Field names in various formats
|
||||||
|
List<String> fieldNames = new ArrayList<>();
|
||||||
|
fieldNames.add("TYPE");
|
||||||
|
fieldNames.add("EXACTTYPE");
|
||||||
|
|
||||||
|
// For each field name, check that queries return consistent results with / out ''
|
||||||
|
fieldNames.forEach(fieldName -> {
|
||||||
|
|
||||||
|
String query = fieldName + ":cm\\:content" + " and =cm:name:" + file1.getName();
|
||||||
|
boolean fileFound = isContentInSearchResults(query, file1.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "Content Not found for query: " + query);
|
||||||
|
|
||||||
|
Integer resultCount1 = testSearchQuery(query, 1, SearchLanguage.AFTS).getPagination().getTotalItems();
|
||||||
|
|
||||||
|
query = fieldName + ":'cm:content'" + " and =cm:name:" + file1.getName();
|
||||||
|
fileFound = isContentInSearchResults(query, file1.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "Content Not found for query: " + query);
|
||||||
|
|
||||||
|
testSearchQuery(query, resultCount1, SearchLanguage.AFTS).getPagination().getTotalItems();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 6)
|
||||||
|
public void testSearchInFieldID() throws Exception
|
||||||
|
{
|
||||||
|
String query = "ID:'workspace://SpacesStore/" + file1.getNodeRefWithoutVersion() + "'";
|
||||||
|
boolean fileFound = isContentInSearchResults(query, file1.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "Content Not found for query: " + query);
|
||||||
|
|
||||||
|
testSearchQuery(query, 1, SearchLanguage.AFTS).getPagination().getTotalItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 7)
|
||||||
|
public void testSearchInFieldPARENT()
|
||||||
|
{
|
||||||
|
String query = "PARENT:" + folder1.getNodeRefWithoutVersion();
|
||||||
|
|
||||||
|
Set<String> expectedNames = newHashSet();
|
||||||
|
expectedNames.add(file1.getName());
|
||||||
|
expectedNames.add(file2.getName());
|
||||||
|
expectedNames.add(file3.getName());
|
||||||
|
expectedNames.add(file4.getName());
|
||||||
|
expectedNames.add(file5.getName());
|
||||||
|
|
||||||
|
testSearchQueryUnordered(query, expectedNames, SearchLanguage.AFTS);
|
||||||
|
|
||||||
|
query = "PARENT:'" + folder1.getNodeRefWithoutVersion() + "\'";
|
||||||
|
|
||||||
|
testSearchQueryUnordered(query, expectedNames, SearchLanguage.AFTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 8)
|
||||||
|
public void testSearchInFieldPRIMARYPARENT() throws Exception
|
||||||
|
{
|
||||||
|
// Create Secondary association in testFolder2
|
||||||
|
RestNodeChildAssociationModel childAssoc1 = new RestNodeChildAssociationModel(file1.getNodeRefWithoutVersion(), "cm:contains");
|
||||||
|
String secondaryChildrenBody = "[" + childAssoc1.toJson() + "]";
|
||||||
|
|
||||||
|
restClient.authenticateUser(testUser).withCoreAPI().usingResource(folder2).createSecondaryChildren(secondaryChildrenBody);
|
||||||
|
RestNodeAssociationModelCollection secondaryChildren = restClient.authenticateUser(testUser).withCoreAPI().usingResource(folder2).getSecondaryChildren();
|
||||||
|
secondaryChildren.getEntryByIndex(0).assertThat().field("id").is(file1.getNodeRefWithoutVersion());
|
||||||
|
|
||||||
|
String query = "PRIMARYPARENT:'workspace://SpacesStore/" + folder1.getNodeRef() + "'";
|
||||||
|
|
||||||
|
Set<String> expectedNames = newHashSet();
|
||||||
|
expectedNames.add(file1.getName());
|
||||||
|
expectedNames.add(file2.getName());
|
||||||
|
expectedNames.add(file3.getName());
|
||||||
|
expectedNames.add(file4.getName());
|
||||||
|
expectedNames.add(file5.getName());
|
||||||
|
|
||||||
|
testSearchQueryUnordered(query, expectedNames, SearchLanguage.AFTS);
|
||||||
|
|
||||||
|
query = "PARENT:'workspace://SpacesStore/" + folder2.getNodeRef() + "'";
|
||||||
|
boolean fileFound = isContentInSearchResults(query, file1.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "Expected Content Not found for query: " + query);
|
||||||
|
|
||||||
|
testSearchQuery(query, 1, SearchLanguage.AFTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 9, groups = { TestGroup.ACS_63n })
|
||||||
|
public void testSearchInFieldNameExactMatch()
|
||||||
|
{
|
||||||
|
// Check that queries return consistent results with / out ''
|
||||||
|
String query = "=name:" + file1.getName();
|
||||||
|
boolean fileFound = isContentInSearchResults(query, file1.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "File Not found for query: " + query);
|
||||||
|
|
||||||
|
Integer resultCount1 = testSearchQuery(query, 1, SearchLanguage.AFTS).getPagination().getTotalItems();
|
||||||
|
Assert.assertSame(resultCount1, 1, "File count does not match for query: " + query);
|
||||||
|
|
||||||
|
query = "=name:'" + file1.getName() + "\'";
|
||||||
|
fileFound = isContentInSearchResults(query, file1.getName(), true);
|
||||||
|
Assert.assertTrue(fileFound, "File Not found for query: " + query);
|
||||||
|
|
||||||
|
testSearchQuery(query, resultCount1, SearchLanguage.AFTS).getPagination().getTotalItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 10, groups = { TestGroup.ACS_63n })
|
||||||
|
public void testSearchInFieldNameQueryExpansion()
|
||||||
|
{
|
||||||
|
// Check that queries return consistent results with / out ''
|
||||||
|
String query = "~name:" + file1.getName();
|
||||||
|
|
||||||
|
Set<String> expectedNames = newHashSet();
|
||||||
|
expectedNames.add(file1.getName());
|
||||||
|
expectedNames.add(file2.getName());
|
||||||
|
expectedNames.add(file3.getName());
|
||||||
|
expectedNames.add(file4.getName());
|
||||||
|
expectedNames.add(folder1.getName());
|
||||||
|
|
||||||
|
testSearchQueryUnordered(query, expectedNames, SearchLanguage.AFTS);
|
||||||
|
|
||||||
|
query = "~name:'" + file1.getName() + "\'";
|
||||||
|
testSearchQueryUnordered(query, expectedNames, SearchLanguage.AFTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 11, groups = { TestGroup.ACS_63n })
|
||||||
|
public void testWithConjunctionDisjunctionAndNegation()
|
||||||
|
{
|
||||||
|
// Query string to include Conjunction, Disjunction and Negation
|
||||||
|
|
||||||
|
String query1 = "~name:" + file1.getName(); // Query expected to return 5 results
|
||||||
|
String query2 = "=name:" + file2.getName(); // Query expected to return 1 result
|
||||||
|
String query3 = "=name:" + file3.getName(); // Query expected to return 1 result
|
||||||
|
|
||||||
|
// Check Query with Conjunction, Negation, Disjunction: returns right results
|
||||||
|
// "~name:file.txt and ! (=name:1-file.txt or =name:file1.txt)"
|
||||||
|
String query = query1 + " and ! (" + query2 + " or " + query3 + ")";
|
||||||
|
|
||||||
|
// Check that expected files are included in the results
|
||||||
|
Set<String> expectedNames = newHashSet();
|
||||||
|
expectedNames.add("file.txt"); // file1
|
||||||
|
expectedNames.add("txt file"); // file4
|
||||||
|
expectedNames.add("file txt folder"); // folder1
|
||||||
|
|
||||||
|
SearchResponse response = testSearchQueryUnordered(query, expectedNames, SearchLanguage.AFTS);
|
||||||
|
|
||||||
|
// Check result count is 5-(1+1)=3
|
||||||
|
int resultCount = response.getPagination().getTotalItems();
|
||||||
|
Assert.assertEquals(resultCount, 3, "File count does not match for query: " + query);
|
||||||
|
|
||||||
|
// Check that file2 and file3 are excluded from the results
|
||||||
|
boolean fileFound = isContentInSearchResponse(response, file2.getName());
|
||||||
|
Assert.assertFalse(fileFound, "File2 found for query: " + query);
|
||||||
|
|
||||||
|
fileFound = isContentInSearchResponse(response, file3.getName());
|
||||||
|
Assert.assertFalse(fileFound, "File3 found for query: " + query);
|
||||||
|
}
|
||||||
|
}
|
@@ -22,7 +22,7 @@
|
|||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<dependency.alfresco-data-model.version>8.57</dependency.alfresco-data-model.version>
|
<dependency.alfresco-data-model.version>8.60</dependency.alfresco-data-model.version>
|
||||||
<dependency.jackson.version>2.10.1</dependency.jackson.version>
|
<dependency.jackson.version>2.10.1</dependency.jackson.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Alfresco Search Services ${project.version} Docker Image
|
# Alfresco Search Services ${project.version} Docker Image
|
||||||
|
|
||||||
FROM alfresco/alfresco-base-java:11.0.1-openjdk-centos-7-6784d76a7b81
|
FROM alfresco/alfresco-base-java:11.0.1-openjdk-centos-7-7a6031154417
|
||||||
LABEL creator="Gethin James" maintainer="Alfresco Search Services Team"
|
LABEL creator="Gethin James" maintainer="Alfresco Search Services Team"
|
||||||
|
|
||||||
ENV DIST_DIR /opt/alfresco-search-services
|
ENV DIST_DIR /opt/alfresco-search-services
|
||||||
|
@@ -58,16 +58,16 @@ jackson-core-2.10.1.jar https://github.com/FasterXML/jackson
|
|||||||
jackson-annotations-2.10.1.jar https://github.com/FasterXML/jackson
|
jackson-annotations-2.10.1.jar https://github.com/FasterXML/jackson
|
||||||
jackson-databind-2.10.1.jar https://github.com/FasterXML/jackson
|
jackson-databind-2.10.1.jar https://github.com/FasterXML/jackson
|
||||||
commons-httpclient-3.1-HTTPCLIENT-1265.jar http://jakarta.apache.org/commons/
|
commons-httpclient-3.1-HTTPCLIENT-1265.jar http://jakarta.apache.org/commons/
|
||||||
spring-aop-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-aop-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
spring-beans-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-beans-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
spring-context-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-context-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
spring-context-support-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-context-support-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
spring-core-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-core-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
spring-expression-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-expression-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
spring-jdbc-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-jdbc-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
spring-orm-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-orm-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
spring-tx-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-tx-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
spring-web-5.1.8.RELEASE.jar http://projects.spring.io/spring-framework/
|
spring-web-5.2.2.RELEASE.jar http://projects.spring.io/spring-framework/
|
||||||
xercesImpl-2.12.0-alfresco-patched-20191004.jar http://xerces.apache.org/xerces2-j
|
xercesImpl-2.12.0-alfresco-patched-20191004.jar http://xerces.apache.org/xerces2-j
|
||||||
guessencoding-1.4.jar http://docs.codehaus.org/display/GUESSENC/
|
guessencoding-1.4.jar http://docs.codehaus.org/display/GUESSENC/
|
||||||
xml-apis-1.4.01.jar https://github.com/FasterXML/jackson
|
xml-apis-1.4.01.jar https://github.com/FasterXML/jackson
|
||||||
|
Reference in New Issue
Block a user