[ SEARCH-1485 ] Consistent functional/non functional packages naming

This commit is contained in:
agazzarini
2019-04-08 18:40:53 +02:00
parent c769cd62cc
commit eb5e2378d3
55 changed files with 86 additions and 3608 deletions

View File

@@ -35,4 +35,4 @@ Search Services 1.2.0 or above or Insight Engine 1.0.0 or above
e.g.
`mvn clean install -Dtest=org.alfresco.service.search.e2e.insightEngine.sql.CustomModelTest`
`mvn clean install -Dtest=CustomModelTest`

View File

@@ -1,54 +0,0 @@
package org.alfresco.service.search.e2e.insightEngine.jdbc;
import java.sql.SQLException;
import java.util.List;
import org.alfresco.utility.network.ServerHealth;
import org.alfresco.utility.network.db.DatabaseOperationImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import static org.testng.Assert.*;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* This class is connecting via JDBC Driver (see default.properties)
*
* example:
* db.url= jdbc:alfresco://${alfresco.server}:${alfresco.port}?collection=alfresco
*
* I am using the TAS DatabaseOperationImpl service to connect
*
* @author Paul Brodner
*
*/
@ContextConfiguration("classpath:alfresco-search-e2e-context.xml")
public class JDBCDriverTest extends AbstractTestNGSpringContextTests {
@Autowired
protected ServerHealth serverHealth;
@Autowired
DatabaseOperationImpl jdbcOperation;
@BeforeClass(alwaysRun = true)
public void checkServerHealth() throws Exception {
serverHealth.assertServerIsOnline();
}
/**
* In order to work start ACS + InsightEngine service
* @throws SQLException
*/
@Test
public void iCanConnectWithJDBCDriver() throws SQLException {
assertTrue(jdbcOperation.connect(), "I can connect via JDBC Driver");
}
@Test(dependsOnMethods="iCanConnectWithJDBCDriver")
public void iCanQueryTheTotalNumberOfDocumentsFromAlfresco() {
List<Object> results = jdbcOperation.executeQuery("select cm_name from alfresco where cm_Name = 'presentation*'");
assertEquals(results.size(), 3);
}
}

View File

@@ -1,257 +0,0 @@
/*
* 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.service.search.e2e.insightEngine.sql;
import static java.util.Arrays.asList;
import static java.util.stream.IntStream.range;
import org.alfresco.service.search.e2e.AbstractSearchServiceE2E;
import org.alfresco.utility.LogFactory;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.TestGroup;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.hamcrest.Matchers;
import org.slf4j.Logger;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Purpose of this TestClass is to test that the fields name follows a given case-sensitive rule in different part of the query.
* Specifically:
*
* <ul>
* <li>When a field is declared in the field list (e.g. SELECT *a,b,c*) the case matters because a field with
* the exact case will be in the returned tuples.
* </li>
* <li>
* When a field is part of the predicate (e.g. WHERE a=somevalue) the case doesn't matter
* </li>
* <li>
* When a field is part of the expression (e.g. order by, group by) the case doesn't matter. However, specifically
* for aggregation expressions (e.g. group by), the same field with the exact case needs to be in field list (and
* here, see the first point, the case matters).
* </li>
* </ul>
*
* @author agazzarini
* {@link https://issues.alfresco.com/jira/browse/SEARCH-1491}
*/
public class CaseSensitivityInFieldsNamesTest extends AbstractSearchServiceE2E
{
private static Logger LOG = LogFactory.getLogger();
/**
* Creates the test dataset that will be used in this test case.
*/
@BeforeClass(alwaysRun = true)
public void setupEnvironment() throws Exception
{
serverHealth.assertServerIsOnline();
super.springTestContextPrepareTestInstance();
try
{
deployCustomModel("model/expense-model.xml");
}
catch (Exception e)
{
LOG.warn("Error Loading Expense Model", e);
}
FolderModel testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder();
createAndAddNewFile(testFolder, 1, "Maidenhead", "GBP", 10.2);
createAndAddNewFile(testFolder, 2, "London", "GBP", 100.4);
createAndAddNewFile(testFolder, 3, "Manchester", "GBP", 1737.22);
FileModel lastFile = createAndAddNewFile(testFolder, 4, "Liverpool", "GBP", 445.9);
waitForIndexing(lastFile.getName(), true);
}
@Test(groups = { TestGroup.INSIGHT_11 })
public void fieldsInSelectListAreCaseSensitive()
{
List<String> selectLists =
asList("EXPENSE_LOCATION,cm_name,expense_Currency",
"Expense_Currency,CM_NAME,ExPenSe_LOCATion",
"expense_location,expense_currency,cM_NaMe");
int expectedNumberOfResults = 4;
selectLists.forEach(fields -> {
String query = "select " + fields + " from alfresco where expense_Currency='GBP' and TYPE = 'expense:expenseReport'";
testSqlQuery(query, expectedNumberOfResults);
String[] expectedNames = fields.split(",");
range(0, expectedNames.length)
.forEach(labelIndex -> {
String expectedName = expectedNames[labelIndex];
for (int entryIndex = 0; entryIndex < expectedNumberOfResults; entryIndex++)
restClient.onResponse()
.assertThat()
.body("list.entries.entry[" + entryIndex + "][" + labelIndex + "].label", Matchers.equalTo(expectedName));
});
});
}
@Test(groups = { TestGroup.INSIGHT_11 })
public void fieldsInCountListAreCaseInsensitive()
{
List<String> selectLists =
asList("cm_name", "CM_NAME","cM_NaMe", "expense_Currency","EXPENSE_CURRENCY");
selectLists.forEach(field -> {
String query = "select count(" + field + ") from alfresco where expense_Currency='GBP' and TYPE = 'expense:expenseReport'";
testSqlQuery(query, 1);
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.equalTo("EXPR$0"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalTo("4"));
});
}
@Test(groups = { TestGroup.INSIGHT_11 })
public void fieldsInPredicateAreCaseInsensitive()
{
List<String> queries =
asList("select TYPE from alfresco where expense_Currency='GBP' and type = 'expense:expenseReport'",
"select TYPE from alfresco where EXPENSE_CURRENCY='GBP' and TYPE = 'expense:expenseReport'",
"select TYPE from alfresco where ExPeNsE_CurrENCY='GBP' and TyPe = 'expense:expenseReport'");
int expectedNumberOfResults = 4;
queries.forEach(query -> {
testSqlQuery(query, expectedNumberOfResults);
range(0, expectedNumberOfResults)
.forEach(entryIndex -> {
restClient.onResponse().assertThat().body("list.entries.entry[" + entryIndex + "][0].label", Matchers.equalTo("TYPE"));
restClient.onResponse().assertThat().body("list.entries.entry[" + entryIndex + "][0].value", Matchers.equalTo("{http://www.mycompany.com/model/expense/1.0}expenseReport"));
});
});
}
@Test(groups = { TestGroup.INSIGHT_11 })
public void fieldsInExpressionsAreCaseInsensitive()
{
List<String> fieldNames = asList("expense_Currency", "EXPENSE_CURRENCY", "ExPeNsE_CurrENCY");
List<String> queries = fieldNames.stream()
.map(fieldName -> asList(
"select " + fieldName + " from alfresco where TYPE = 'expense:expenseReport' group by " + fieldName + " having sum(EXPENSE_AMOUNT) > 0",
"select " + fieldName + " from alfresco where TYPE = 'expense:expenseReport' group by " + fieldName + " having sum(expense_Amount) > 0",
"select " + fieldName + " from alfresco where TYPE = 'expense:expenseReport' group by " + fieldName + " having sum(expense_amount) > 0"))
.flatMap(Collection::stream)
.collect(Collectors.toList());
queries.forEach(query -> {
testSqlQuery(query, 1);
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.equalToIgnoringCase("expense_Currency"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalTo("GBP"));
});
}
@Test(groups = { TestGroup.INSIGHT_11 })
public void fieldsInSortExpressionAreCaseInsensitive_descendingOrder()
{
List<String> queries =
asList("select expense_Id from alfresco where expense_Currency='GBP' and type = 'expense:expenseReport' order by expense_id desc",
"select expense_Id from alfresco where expense_Currency='GBP' and TYPE = 'expense:expenseReport' order by expense_id desc",
"select expense_Id from alfresco where expense_Currency='GBP' and TyPe = 'expense:expenseReport' order by expense_id desc");
int expectedNumberOfResults = 4;
queries.forEach(query -> {
testSqlQuery(query, expectedNumberOfResults);
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.equalToIgnoringCase("expense_Id"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalTo("4"));
restClient.onResponse().assertThat().body("list.entries.entry[1][0].label", Matchers.equalToIgnoringCase("expense_Id"));
restClient.onResponse().assertThat().body("list.entries.entry[1][0].value", Matchers.equalTo("3"));
restClient.onResponse().assertThat().body("list.entries.entry[2][0].label", Matchers.equalToIgnoringCase("expense_Id"));
restClient.onResponse().assertThat().body("list.entries.entry[2][0].value", Matchers.equalTo("2"));
restClient.onResponse().assertThat().body("list.entries.entry[3][0].label", Matchers.equalToIgnoringCase("expense_Id"));
restClient.onResponse().assertThat().body("list.entries.entry[3][0].value", Matchers.equalTo("1"));
});
}
@Test(groups = { TestGroup.INSIGHT_11 })
public void fieldsInSortExpressionAreCaseInsensitive_ascendingOrder()
{
List<String> queries =
asList("select expense_Id from alfresco where expense_Currency='GBP' and type = 'expense:expenseReport' order by expense_id asc",
"select expense_Id from alfresco where expense_Currency='GBP' and TYPE = 'expense:expenseReport' order by expense_id asc",
"select expense_Id from alfresco where expense_Currency='GBP' and TyPe = 'expense:expenseReport' order by expense_id asc",
"select expense_Id from alfresco where expense_Currency='GBP' and TYPE = 'expense:expenseReport' order by expense_id asc");
int expectedNumberOfResults = 4;
queries.forEach(query -> {
testSqlQuery(query, expectedNumberOfResults);
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.equalToIgnoringCase("expense_Id"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalTo("1"));
restClient.onResponse().assertThat().body("list.entries.entry[1][0].label", Matchers.equalToIgnoringCase("expense_Id"));
restClient.onResponse().assertThat().body("list.entries.entry[1][0].value", Matchers.equalTo("2"));
restClient.onResponse().assertThat().body("list.entries.entry[2][0].label", Matchers.equalToIgnoringCase("expense_Id"));
restClient.onResponse().assertThat().body("list.entries.entry[2][0].value", Matchers.equalTo("3"));
restClient.onResponse().assertThat().body("list.entries.entry[3][0].label", Matchers.equalToIgnoringCase("expense_Id"));
restClient.onResponse().assertThat().body("list.entries.entry[3][0].value", Matchers.equalTo("4"));
});
}
/**
* Internal method used for creating a sample file, with some data used within the tests.
*
* @param parentFolder the parent folder.
* @param id the file identifier.
* @param location the location (a String property)
* @param currency the currency (another String property)
* @param amount the amount
* @return the just created {@link FileModel} instance.
*/
private FileModel createAndAddNewFile(final FolderModel parentFolder, int id, String location, String currency, double amount) throws Exception
{
FileModel file = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content #" + System.currentTimeMillis());
file.setName("file-"+ file.getName());
Map<String, Object> properties = new HashMap<>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:expense:expenseReport");
properties.put(PropertyIds.NAME, file.getName());
properties.put("expense:id", id);
properties.put("expense:Location", location);
properties.put("expense:Currency", currency);
properties.put("expense:Approved", true);
properties.put("expense:Amount", amount);
cmisApi.authenticateUser(testUser)
.usingSite(testSite)
.usingResource(parentFolder)
.createFile(file, properties, VersioningState.MAJOR)
.assertThat()
.existsInRepo();
return file;
}
}

View File

@@ -1,224 +0,0 @@
package org.alfresco.service.search.e2e.insightEngine.sql;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.rest.search.SearchSqlRequest;
import org.alfresco.service.search.e2e.AbstractSearchServiceE2E;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.*;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.hamcrest.Matchers;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.HashMap;
import java.util.Map;
public class CustoModelGroupByFacetableTest extends AbstractSearchServiceE2E
{
protected SiteModel testSite;
private UserModel testUser;
private FolderModel testFolder;
private String filename1;
private String filename2;
private String filename3;
private String filename4;
private String filecontent1;
private String filecontent2;
private String filecontent3;
private String filecontent4;
private String author1;
private String author2;
private Boolean exists;
private int quantity1;
private int quantity2;
private int quantity3;
@BeforeClass(alwaysRun = true)
public void setupEnvironment() throws Exception
{
serverHealth.assertServerIsOnline();
deployCustomModel("model/facetable-aspect-model.xml");
testSite = dataSite.createPublicRandomSite();
// Create test user and add the user as a SiteContributor
testUser = dataUser.createRandomTestUser();
dataUser.addUserToSite(testUser, testSite, UserRole.SiteContributor);
testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder();
filename1 = "file1";
filename2 = "file2";
filename3 = "file3";
filename4 = "file4";
filecontent1 = "file content 1";
filecontent2 = "content file 2";
filecontent3 = "content file 3";
filecontent4 = "content file 4";
author1 = "Giuseppe Verdi";
author2 = "Mario Rossi";
exists = true;
quantity1 = 9;
quantity2 = 10;
quantity3 = 12;
FileModel customFile = new FileModel(filename1, FileType.TEXT_PLAIN, filecontent1);
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
properties.put(PropertyIds.NAME, customFile.getName());
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).createFile(customFile, properties, VersioningState.MAJOR).assertThat()
.existsInRepo();
cmisApi.authenticateUser(testUser).usingResource(customFile).addSecondaryTypes("P:csm:author").assertThat().secondaryTypeIsAvailable("P:csm:author");
cmisApi.authenticateUser(testUser).usingResource(customFile).addSecondaryTypes("P:csm:nontexttypes").assertThat()
.secondaryTypeIsAvailable("P:csm:nontexttypes");
cmisApi.authenticateUser(testUser).usingResource(customFile).updateProperty("csm:author", author2);
cmisApi.authenticateUser(testUser).usingResource(customFile).updateProperty("csm:quantity", quantity3);
cmisApi.authenticateUser(testUser).usingResource(customFile).updateProperty("csm:exists", exists);
FileModel customFile2 = new FileModel(filename2, FileType.TEXT_PLAIN, filecontent2);
properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
properties.put(PropertyIds.NAME, customFile2.getName());
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).createFile(customFile2, properties, VersioningState.MAJOR).assertThat()
.existsInRepo();
cmisApi.authenticateUser(testUser).usingResource(customFile2).addSecondaryTypes("P:csm:author").assertThat().secondaryTypeIsAvailable("P:csm:author");
cmisApi.authenticateUser(testUser).usingResource(customFile2).addSecondaryTypes("P:csm:nontexttypes").assertThat()
.secondaryTypeIsAvailable("P:csm:nontexttypes");
cmisApi.authenticateUser(testUser).usingResource(customFile2).updateProperty("csm:author", author1);
cmisApi.authenticateUser(testUser).usingResource(customFile2).updateProperty("csm:quantity", quantity2);
cmisApi.authenticateUser(testUser).usingResource(customFile2).updateProperty("csm:exists", exists);
FileModel customFile3 = new FileModel(filename3, FileType.TEXT_PLAIN, filecontent3);
properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
properties.put(PropertyIds.NAME, customFile3.getName());
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).createFile(customFile3, properties, VersioningState.MAJOR).assertThat()
.existsInRepo();
cmisApi.authenticateUser(testUser).usingResource(customFile3).addSecondaryTypes("P:csm:author").assertThat().secondaryTypeIsAvailable("P:csm:author");
cmisApi.authenticateUser(testUser).usingResource(customFile3).addSecondaryTypes("P:csm:nontexttypes").assertThat()
.secondaryTypeIsAvailable("P:csm:nontexttypes");
cmisApi.authenticateUser(testUser).usingResource(customFile3).updateProperty("csm:author", author1);
cmisApi.authenticateUser(testUser).usingResource(customFile3).updateProperty("csm:quantity", quantity2);
cmisApi.authenticateUser(testUser).usingResource(customFile3).updateProperty("csm:exists", exists);
FileModel customFile4 = new FileModel(filename4, FileType.TEXT_PLAIN, filecontent4);
properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
properties.put(PropertyIds.NAME, customFile4.getName());
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).createFile(customFile4, properties, VersioningState.MAJOR).assertThat()
.existsInRepo();
cmisApi.authenticateUser(testUser).usingResource(customFile4).addSecondaryTypes("P:csm:nontexttypes").assertThat()
.secondaryTypeIsAvailable("P:csm:nontexttypes");
cmisApi.authenticateUser(testUser).usingResource(customFile4).updateProperty("csm:quantity", quantity1);
cmisApi.authenticateUser(testUser).usingResource(customFile4).updateProperty("csm:exists", !exists);
// wait for indexing
waitForIndexing("cm:name:'" + customFile4.getName() + "'", true);
waitForIndexing("cm:name:'" + testFolder.getName() + "'", true);
}
@Test(priority = 1, groups = { TestGroup.INSIGHT_11 })
public void testGroupByTextFacetableModel() throws Exception
{
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select cm_name, csm_author from alfresco group by cm_name, csm_author");
RestResponse response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.equalToIgnoringCase("cm_name"));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].label", Matchers.equalToIgnoringCase("csm_author"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalToIgnoringCase(filename1));
restClient.onResponse().assertThat().body("list.entries.entry[1][0].value", Matchers.equalToIgnoringCase(filename2));
restClient.onResponse().assertThat().body("list.entries.entry[2][0].value", Matchers.equalToIgnoringCase(filename3));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].value", Matchers.equalToIgnoringCase(author2));
restClient.onResponse().assertThat().body("list.entries.entry[1][1].value", Matchers.equalToIgnoringCase(author1));
restClient.onResponse().assertThat().body("list.entries.entry[2][1].value", Matchers.equalToIgnoringCase(author1));
// Test changing the order of fields.
sqlRequest.setSql("select csm_author, cm_name from alfresco group by csm_author, cm_name");
response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("list.pagination.count", Matchers.equalTo(3));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.equalToIgnoringCase("cm_name"));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].label", Matchers.equalToIgnoringCase("csm_author"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalToIgnoringCase(filename2));
restClient.onResponse().assertThat().body("list.entries.entry[1][0].value", Matchers.equalToIgnoringCase(filename3));
restClient.onResponse().assertThat().body("list.entries.entry[2][0].value", Matchers.equalToIgnoringCase(filename1));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].value", Matchers.equalToIgnoringCase(author1));
restClient.onResponse().assertThat().body("list.entries.entry[1][1].value", Matchers.equalToIgnoringCase(author1));
restClient.onResponse().assertThat().body("list.entries.entry[2][1].value", Matchers.equalToIgnoringCase(author2));
}
@Test(priority = 2, groups = { TestGroup.INSIGHT_11 })
public void testGroupByTextInteger() throws Exception
{
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select csm_quantity, csm_author from alfresco group by csm_quantity, csm_author");
RestResponse response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("list.pagination.count", Matchers.equalTo(2));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.equalToIgnoringCase("csm_author"));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].label", Matchers.equalToIgnoringCase("csm_quantity"));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].value", Matchers.equalToIgnoringCase(Integer.toString(quantity2)));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalToIgnoringCase(author1));
restClient.onResponse().assertThat().body("list.entries.entry[1][1].value", Matchers.equalToIgnoringCase(Integer.toString(quantity3)));
restClient.onResponse().assertThat().body("list.entries.entry[1][0].value", Matchers.equalToIgnoringCase(author2));
}
@Test(priority = 3, groups = { TestGroup.INSIGHT_11 })
public void testGroupByBoolAggregation() throws Exception
{
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select csm_exists, max(csm_quantity) from alfresco group by csm_exists");
RestResponse response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("list.pagination.count", Matchers.equalTo(2));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalToIgnoringCase(Boolean.toString(!exists)));
restClient.onResponse().assertThat().body("list.entries.entry[1][0].value", Matchers.equalToIgnoringCase(Boolean.toString(exists)));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].value", Matchers.equalToIgnoringCase(Integer.toString(quantity1)));
restClient.onResponse().assertThat().body("list.entries.entry[1][1].value", Matchers.equalToIgnoringCase(Integer.toString(quantity3)));
}
}

View File

@@ -1,126 +0,0 @@
/*
* Copyright 2018 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.service.search.e2e.insightEngine.sql;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.rest.search.SearchSqlRequest;
import org.alfresco.service.search.e2e.AbstractSearchServiceE2E;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
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.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.hamcrest.Matchers;
import org.springframework.http.HttpStatus;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Purpose of this TestClass is to test that the SQLs work after model changes
*
* @author meenal bhave
*/
public class CustomModelChangesTest extends AbstractSearchServiceE2E
{
protected SiteModel testSite;
private UserModel testUser;
private FolderModel testFolder;
@BeforeClass(alwaysRun = true)
public void setupEnvironment() throws Exception
{
serverHealth.assertServerIsOnline();
deployCustomModel("model/flipStatus-model.xml");
testSite = dataSite.createPublicRandomSite();
// Create test user and add the user as a SiteContributor
testUser = dataUser.createRandomTestUser();
dataUser.addUserToSite(testUser, testSite, UserRole.SiteContributor);
testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder();
// Wait for the file to be indexed
waitForIndexing(testFolder.getName(), true);
}
@AfterClass(alwaysRun=true)
public void deleteModel()
{
deleteCustomModel("flipStatus-model.xml");
}
// SQL works after model is deactivated
@Test(priority = 1, groups = { TestGroup.INSIGHT_10 })
public void testSqlWorksAfterDeactivatingModel() throws Exception
{
FileModel customFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:flipFlop:song");
properties.put(PropertyIds.NAME, customFile.getName());
properties.put("flipFlop:genre", "Pop");
properties.put("flipFlop:lyricist", "SomeLyricist");
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
.createFile(customFile, properties, VersioningState.MAJOR)
.assertThat().existsInRepo();
// Wait for the file to be indexed
waitForIndexing(customFile.getName(), true);
// Query custom model fields
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select cm_name, flipFlop_genre, flipFlop_lyricist from alfresco where cm_name = '" + customFile.getName() + "'");
sqlRequest.setLimit(10);
RestResponse response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("list.pagination.count", Matchers.equalTo(1));
// Delete File and Delete from trash
dataContent.usingSite(testSite).usingUser(testUser).usingResource(customFile).deleteContent();
restClient.withCoreAPI().usingTrashcan().deleteNodeFromTrashcan(customFile);
// Wait for the file delete transaction to be indexed, until Search API returns no results
Boolean fileFound = waitForIndexing("cm:name:'" + customFile.getName() + "'", false);
Assert.assertTrue(fileFound, "File appears in the search results when deleted from trash");
// Query custom model fields: No matching content
response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Deactivate the Model
deactivateCustomModel("flipStatus-model.xml");
fileFound = waitForIndexing("TYPE:'" + "flipFlop:song" + "'", false);
Assert.assertTrue(fileFound, "Indexes are not updated after deactivating a model");
// Query OOTB fields: Custom Model Deactivated
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select count(*) as TotalDocuments from alfresco where type = 'cm:content'");
response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("list.pagination.count", Matchers.equalTo(1));
}
}

View File

@@ -1,113 +0,0 @@
/*
* Copyright 2018 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.service.search.e2e.insightEngine.sql;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.rest.search.SearchSqlRequest;
import org.alfresco.service.search.e2e.AbstractSearchServiceE2E;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.data.DataContent;
import org.alfresco.utility.data.DataSite;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
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.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.hamcrest.Matchers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Purpose of this TestClass is to test that the SQL end point works as expected with CustomModels
*
* @author meenal bhave
*/
public class CustomModelTest extends AbstractSearchServiceE2E
{
@Autowired
protected DataSite dataSite;
@Autowired
protected DataContent dataContent;
protected SiteModel testSite;
private UserModel testUser;
private FolderModel testFolder;
@BeforeClass(alwaysRun = true)
public void setupEnvironment() throws Exception
{
serverHealth.assertServerIsOnline();
testSite = dataSite.createPublicRandomSite();
// Create test user and add the user as a SiteContributor
testUser = dataUser.createRandomTestUser();
dataUser.addUserToSite(testUser, testSite, UserRole.SiteContributor);
testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder();
}
// Content of Custom Type is added to the Repo
@Test(priority = 1, groups = { TestGroup.INSIGHT_10 })
public void testSqlListCustomFields() throws Exception
{
Long uniqueRef = System.currentTimeMillis();
FileModel customFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:finance:Receipt");
properties.put(PropertyIds.NAME, customFile.getName());
properties.put("finance:ReceiptNo", uniqueRef);
properties.put("finance:ReceiptValue", 30);
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
.createFile(customFile, properties, VersioningState.MAJOR).assertThat().existsInRepo();
// Wait for the file to be indexed
waitForIndexing(customFile.getName(), true);
// Select distinct site: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select finance_ReceiptNo, finance_ReceiptValue from alfresco where finance_ReceiptNo = " + uniqueRef);
sqlRequest.setLimit(10);
RestResponse response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("list.pagination.maxItems", Matchers.equalTo(10));
response.assertThat().body("list.pagination.count", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.equalToIgnoringCase("finance_ReceiptValue"));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].label", Matchers.equalToIgnoringCase("finance_ReceiptNo"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", Matchers.equalToIgnoringCase("30.0"));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].value", Matchers.equalTo(uniqueRef.toString()));
// Select distinct cm_name: solr format
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select finance_ReceiptNo, finance_ReceiptValue from alfresco where finance_ReceiptNo = " + uniqueRef + " limit 10");
sqlRequest.setFormat("solr");
response = restClient.authenticateUser(testUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set.docs[0].finance_ReceiptValue", Matchers.equalTo(30));
restClient.onResponse().assertThat().body("result-set.docs[0].finance_ReceiptNo", Matchers.equalTo(uniqueRef));
}
}

View File

@@ -1,781 +0,0 @@
/*
* Copyright (C) 2018 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.service.search.e2e.insightEngine.sql;
import static java.util.Arrays.asList;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isIn;
import static org.hamcrest.Matchers.not;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.service.search.e2e.searchservices.AbstractSearchTest;
import org.alfresco.rest.search.SearchSqlRequest;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.hamcrest.Matchers;
import org.springframework.http.HttpStatus;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* Tests for /sql end point Search API.
*
* @author Meenal Bhave
*/
public class SearchSQLAPITest extends AbstractSearchTest
{
/**
* Path selector to get the values of all cm_name entries for returned search results.
* <p>
* For example it will retrieve the "alfresco.txt" from:
* <pre>
* {"list": {
* "entries": [
* {"entry": [{
* "label": "cm_name",
* "value": "alfresco.txt"
* }]},
* ...
* </pre>
*/
private static final String CM_NAME_VALUES = "list.entries.collect {it.entry.findAll {it.label == 'cm_name'}}.flatten().value";
String sql = "select SITE, CM_OWNER from alfresco group by SITE,CM_OWNER";
String[] locales = { "en-US" };
String solrFormat = "solr";
/**
* API post:
* {
* "stmt": "select SITE from alfresco",
* "locales" : ["en_US"],
* "format" : "solr",
* "timezone":"",
* "includeMetadata":false
* }
* Example Response: In Solr Format
* {
* "result-set":
* {
* "docs":
* [
* {
* "SITE":
* [
* "swsdp"
* ]
* },
* {
* "SITE":
* [
* "swsdp"
* ]
* }
* ]
* }
*/
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 01)
public void testWithSolr() throws Exception
{
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setFormat(solrFormat);
sqlRequest.setLocales(locales);
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs", Matchers.notNullValue());
}
/**
* API post example:
* {
* "stmt": "select SITE from alfresco",
* "locales" : ["en_US"],
* "format" : "json",
* "timezone":"",
* "includeMetadata":false
* }
* Example Response: In json Format
* {
* "list":
* {
* "pagination":
* {
"count": 103,
"hasMoreItems": false,
"totalItems": 103,
"skipCount": 0,
"maxItems": 1000
},
* "entries":
* [
* "entry": [
{
"label": "SITE",
"value": "[\"swsdp\"]"
}
],
"entry": [
{
"label": "SITE",
"value": "[\"swsdp\"]"
}
]
* ]
* }
*/
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 02)
public void testWithJson() throws Exception
{
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLocales(locales);
// Format not set
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.nullValue());
restClient.onResponse().assertThat().body("list.entries", Matchers.notNullValue());
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLocales(locales);
sqlRequest.setFormat("json"); // Format json
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.nullValue());
restClient.onResponse().assertThat().body("list.entries", Matchers.notNullValue());
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLocales(locales);
sqlRequest.setFormat("abcd"); // Format any other than solr
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.nullValue());
restClient.onResponse().assertThat().body("list.entries", Matchers.notNullValue());
}
/**
* API post:
* {
* "stmt": "select SITE from alfresco",
* "locales" : ["en_US"],
* "format" : "solr",
* "timezone":"",
* "includeMetadata":true
* }
* Example Response: In Solr Format: Includes metadata: aliases, fields, isMetadata=true
* {
* "result-set": {
* "docs": [
* {
* "aliases": {
* "SITE": "SITE"
* },
* "isMetadata": true,
* "fields": [
* "SITE"
* ]
* },
* {
* "SITE": [
* "swsdp"
* ]
* },
* {
* "SITE": [
* "swsdp"
* ]
* },
* {
* "RESPONSE_TIME": 79,
* "EOF": true
* }
* ]
* }
* }
*/
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 03)
public void testWithSolrIncludeMetadata() throws Exception
{
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setFormat(solrFormat);
sqlRequest.setLocales(locales);
sqlRequest.setIncludeMetadata(true);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.SITE", equalToIgnoringCase("SITE"));
restClient.onResponse().assertThat().body("result-set.docs[0].isMetadata", is(true));
restClient.onResponse().assertThat().body("result-set.docs[0].fields[0]", equalToIgnoringCase("SITE"));
}
/**
* API post example:
* {
* "stmt": "select SITE from alfresco limit 2",
* "locales" : ["en_US"],
* "format" : "json",
* "timezone":"",
* "includeMetadata":false
* }
* Example Response: In json Format
* {
* "list":
* {
* "pagination":
* {
"count": 3,
"hasMoreItems": false,
"totalItems": 3,
"skipCount": 0,
"maxItems": 1000
},
* "entries":
* [
* "entry": [
{
"label": "aliases",
"value": "{\"SITE\":\"SITE\"}"
},
{
"label": "isMetadata",
"value": "true"
},
{
"label": "fields",
"value": "[\"SITE\"]"
}
]
},
* "entry": [
{
"label": "SITE",
"value": "[\"swsdp\"]"
}
],
"entry": [
{
"label": "SITE",
"value": "[\"swsdp\"]"
}
]
* ]
* }
*/
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 04)
public void testWithJsonIncludeMetadata() throws Exception
{
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setFormat("");
sqlRequest.setLocales(locales);
sqlRequest.setIncludeMetadata(true);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.nullValue());
restClient.onResponse().assertThat().body("list.entries", Matchers.notNullValue());
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", equalToIgnoringCase("aliases"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", equalToIgnoringCase("{\"SITE\":\"SITE\",\"cm_owner\":\"CM_OWNER\"}"));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].label", equalToIgnoringCase("isMetadata"));
restClient.onResponse().assertThat().body("list.entries.entry[0][1].value", is("true"));
restClient.onResponse().assertThat().body("list.entries.entry[0][2].label", equalToIgnoringCase("fields"));
restClient.onResponse().assertThat().body("list.entries.entry[0][2].value", equalToIgnoringCase("[\"SITE\",\"cm_owner\"]"));
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 05)
public void testIncludeMetadataFalse() throws Exception
{
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setFormat("solr"); // Format solr
sqlRequest.setIncludeMetadata(false);
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases", Matchers.nullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].isMetadata", Matchers.nullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].fields", Matchers.nullValue());
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setIncludeMetadata(false);
sqlRequest.setFormat("json"); // Format json
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.nullValue());
restClient.onResponse().assertThat().body("list.entries", Matchers.notNullValue());
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.notNullValue());
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", not("aliases"));
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setIncludeMetadata(false); // Format not set
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.nullValue());
restClient.onResponse().assertThat().body("list.entries", Matchers.notNullValue());
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", Matchers.notNullValue());
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", not("aliases"));
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setFormat(solrFormat); // IncludeMetadata = false when not specified
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases", Matchers.nullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].isMetadata", Matchers.nullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].fields", Matchers.nullValue());
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 06)
public void testLocales() throws Exception
{
String[] noLocales = {}; // Not specified
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLocales(noLocales);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
String[] singleLocale = { "en-Uk" };
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLocales(singleLocale);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
String[] multipleLocales = { "en-US", "ja" };
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLocales(multipleLocales);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 07)
public void testTimezone() throws Exception
{
String timezone = ""; // Not specified
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setTimezone(timezone);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
timezone = "UTC"; // UTC
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setTimezone(timezone);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
timezone = "false"; // Invalid timezone is ignored
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setTimezone(timezone);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 8)
public void testAggregateSQL() throws Exception
{
String agSql = "select count(*) FROM alfresco where TYPE='cm:content'";
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(agSql);
RestResponse response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("list.entries", Matchers.notNullValue());
response.assertThat().body("list.entries.entry[0][0].value", not("0"));
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 9)
public void testLimit() throws Exception
{
Integer defaultLimit = 1000;
Integer limit = null; // Limit defaults to the default setting when null
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLimit(limit);
RestResponse response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("list.pagination.maxItems", Matchers.equalTo(defaultLimit));
limit = 0; // Limit defaults to the default setting when 0
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLimit(limit);
response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("list.pagination.maxItems", Matchers.equalTo(defaultLimit));
limit = 100; // Limit is applied correctly, with maxItems = limit
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLimit(limit);
response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("list.pagination.maxItems", Matchers.equalTo(limit));
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 10)
public void testAuthenticationError() throws Exception
{
UserModel dummyUser = dataUser.createRandomTestUser("UserSearchDummy");
dummyUser.setPassword("incorrect-password");
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLocales(locales);
restClient.authenticateUser(dummyUser).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.UNAUTHORIZED);
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 11)
public void testPermissions() throws Exception
{
UserModel userNoPerm = dataUser.createRandomTestUser("UserSearchNoPerm");
UserModel userPerm = dataUser.createRandomTestUser("UserSearchPerm");
dataUser.addUserToSite(userPerm, siteModel, UserRole.SiteContributor);
String siteSQL = "select SITE, CM_OWNER from alfresco where SITE='" + siteModel.getId() + "'";
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(siteSQL);
// 0 results expected for query as User does not have access to the private site
restClient.authenticateUser(userNoPerm).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("list.pagination.count", is(0));
restClient.onResponse().assertThat().body("list.pagination.totalItems", is(0));
restClient.onResponse().assertThat().body("list.pagination.hasMoreItems", is(false));
restClient.onResponse().assertThat().body("list.entries", empty());
// Results expected for query as User does has access to the private site
restClient.authenticateUser(userPerm).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("list.pagination.count", greaterThan(0));
restClient.onResponse().assertThat().body("list.pagination.totalItems", greaterThan(0));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", equalToIgnoringCase("SITE"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", equalToIgnoringCase("[\"" + siteModel.getId() + "\"]"));
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 12)
public void testErrors() throws Exception
{
String incorrectSQL = ""; // Missing SQL
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(incorrectSQL);
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST);
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.notNullValue());
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.containsString("Required stmt parameter is missing"));
incorrectSQL = "select SITE from unknownTable"; // Wrong table name
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(incorrectSQL);
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST);
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.notNullValue());
// restClient.onResponse().assertThat().body("error.briefSummary", Matchers.containsString("Table 'unknownTable' not found"));
incorrectSQL = "select Column1 from alfresco"; // Wrong ColumnName
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(incorrectSQL);
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST);
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.notNullValue());
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.containsString("Column 'Column1' not found"));
incorrectSQL = "select SITE alfresco"; // BAD SQL Grammar: from missing
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(incorrectSQL);
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST);
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.notNullValue());
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.containsString("Unable to execute the query"));
incorrectSQL = "select SITE, CM_OWNER from alfresco group by SITE"; // BAD SQL Grammar: CM_OWNER is not being grouped
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(incorrectSQL);
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST);
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.notNullValue());
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.containsString("Expression 'CM_OWNER' is not being grouped"));
incorrectSQL = "delete SITE from alfresco"; // BAD SQL Grammar
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(incorrectSQL);
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST);
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.notNullValue());
restClient.onResponse().assertThat().body("error.briefSummary", Matchers.containsString("Was expecting one of"));
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.NOT_INSIGHT_ENGINE }, priority = 13)
public void testErrorForSQLAPIWithASS() throws Exception
{
String acsVersion = serverHealth.getAlfrescoVersion();
HttpStatus expectedStatus = HttpStatus.OK;
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(sql);
sqlRequest.setLocales(locales);
// Set expected result based on ACS Version and ASS Version
if (!acsVersion.startsWith("6"))
{
expectedStatus = HttpStatus.NOT_FOUND;
}
else
{
expectedStatus = HttpStatus.BAD_REQUEST;
}
restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(expectedStatus);
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 14)
public void testSelectStar() throws Exception
{
// Select * with Limit, json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select * from alfresco");
sqlRequest.setLimit(1);
RestResponse response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("list.pagination.maxItems", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", equalToIgnoringCase("PATH"));
// Select * with Limit, solr format: Also covered in JDBC
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select * from alfresco");
sqlRequest.setFormat("solr");
sqlRequest.setIncludeMetadata(true);
sqlRequest.setLimit(1);
response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_name", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_created", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_creator", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_modified", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_modifier", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_owner", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.OWNER", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.TYPE", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.LID", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.DBID", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_title", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_description", Matchers.notNullValue());
// This type of assertion is required because of a '.' in the field name
Assert.assertTrue(response.getResponse().body().jsonPath().get("result-set.docs[0].aliases").toString().contains("cm_content.size=cm_content.size"));
Assert.assertTrue(response.getResponse().body().jsonPath().get("result-set.docs[0].aliases").toString().contains("cm_content.mimetype=cm_content.mimetype"));
Assert.assertTrue(response.getResponse().body().jsonPath().get("result-set.docs[0].aliases").toString().contains("cm_content.encoding=cm_content.encoding"));
Assert.assertTrue(response.getResponse().body().jsonPath().get("result-set.docs[0].aliases").toString().contains("cm_content.locale=cm_content.locale"));
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_lockOwner", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.SITE", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.PARENT", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.PATH", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.PRIMARYPARENT", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.ASPECT", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.QNAME", Matchers.notNullValue());
// Test that cm_content and any other random field does not appear in the response
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.cm_content", Matchers.nullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].aliases.RandomNonExistentField", Matchers.nullValue());
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 15)
public void testDistinct() throws Exception
{
// Select distinct site: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select distinct Site from alfresco");
sqlRequest.setLimit(10);
RestResponse response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("list.pagination.maxItems", Matchers.equalTo(10));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", equalToIgnoringCase("site"));
// Select distinct cm_name: solr format
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select distinct cm_name from alfresco limit 5");
sqlRequest.setFormat("solr");
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set.docs[0].cm_name", Matchers.notNullValue());
}
/** Check that a filter query can affect which results are included. */
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_11 }, priority = 16)
public void testFilterQuery() throws Exception
{
SearchSqlRequest sqlRequest = new SearchSqlRequest();
String siteSQL = "select SITE, CM_OWNER from alfresco where SITE='" + siteModel.getId() + "'";
sqlRequest.setSql(siteSQL);
// Add a filter query to only include results from inside the site (i.e. all results).
String[] filterQuery = { "SITE:'" + siteModel.getId() + "'" };
sqlRequest.setFilterQuery(filterQuery);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("list.pagination.count", greaterThan(0));
restClient.onResponse().assertThat().body("list.pagination.totalItems", greaterThan(0));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].label", equalToIgnoringCase("SITE"));
restClient.onResponse().assertThat().body("list.entries.entry[0][0].value", equalToIgnoringCase("[\"" + siteModel.getId() + "\"]"));
// Now try instead removing everything from the site (i.e. all results).
String[] inverseFilterQuery = { "-SITE:'" + siteModel.getId() + "'" };
sqlRequest.setFilterQuery(inverseFilterQuery);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("list.pagination.count", is(0));
restClient.onResponse().assertThat().body("list.pagination.totalItems", is(0));
restClient.onResponse().assertThat().body("list.pagination.hasMoreItems", is(false));
restClient.onResponse().assertThat().body("list.entries", empty());
}
/** Check that the combination of multiple filter queries produce the intersection of results. */
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_11 }, priority = 17)
public void testCombiningFilterQueries() throws Exception
{
String siteSQL = "select cm_name from alfresco where SITE='" + siteModel.getId() + "'";
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(siteSQL);
// Add a filter query to only include results from inside the site (i.e. all results).
String[] filterQueries = { "-cm_name:'cars'", "-cm_name:'pangram'" };
sqlRequest.setFilterQuery(filterQueries);
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("list.pagination.count", greaterThan(0));
restClient.onResponse().assertThat().body("list.pagination.totalItems", greaterThan(0));
// Check that pangram.txt and cars.txt were both filtered out.
restClient.onResponse().assertThat()
.body(CM_NAME_VALUES, everyItem(not(isIn(asList("pangram.txt", "cars.txt")))));
}
/** Check that an empty list of filter queries doesn't remove anything from the results. */
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_11 }, priority = 18)
public void testEmptyFilterQuery() throws Exception
{
String siteSQL = "select cm_name from alfresco where SITE='" + siteModel.getId() + "'";
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(siteSQL);
// Add an empty list of filter queries.
sqlRequest.setFilterQuery(new String[]{});
searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Check that the cm_names of all nodes in the site are returned.
restClient.onResponse().assertThat()
.body(CM_NAME_VALUES, containsInAnyOrder("documentLibrary", SEARCH_DATA_SAMPLE_FOLDER, "pangram.txt", "cars.txt", "alfresco.txt", unique_searchString + ".txt"));
}
}

View File

@@ -1,256 +0,0 @@
/*
* Copyright (C) 2018 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.service.search.e2e.insightEngine.sql;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.service.search.e2e.searchservices.AbstractSearchTest;
import org.alfresco.rest.search.SearchSqlJDBCRequest;
import org.alfresco.rest.search.SearchSqlRequest;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.TestGroup;
import org.springframework.http.HttpStatus;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.hamcrest.Matchers;
/**
* Tests for /sql end point Search API: Phrase Searching.
*
* @author Meenal Bhave
*/
public class SearchSQLPhraseTest extends AbstractSearchTest
{
FileModel fileBanana, fileYellowBanana, fileBigYellowBanana, fileBigBananaBoat, fileYellowBananaBigBoat, fileBigYellowBoat;
List expectedContent = new ArrayList<String>();
@BeforeClass(alwaysRun = true)
public void dataPreparation() throws Exception
{
super.dataPreparation();
// Create files with different phrases
fileBanana = new FileModel(unique_searchString + "-1.txt", "banana", "phrase searching", FileType.TEXT_PLAIN, "banana");
dataContent.usingUser(userModel).usingSite(siteModel).createContent(fileBanana);
fileYellowBanana = new FileModel(unique_searchString + "-2.txt", "yellow banana", "phrase searching", FileType.TEXT_PLAIN, "yellow banana");
dataContent.usingUser(userModel).usingSite(siteModel).createContent(fileYellowBanana);
fileBigYellowBanana = new FileModel(unique_searchString + "-3.txt", "big yellow banana", "phrase searching", FileType.TEXT_PLAIN, "big yellow banana");
dataContent.usingUser(userModel).usingSite(siteModel).createContent(fileBigYellowBanana);
fileBigBananaBoat = new FileModel(unique_searchString + "-4.txt", "big boat", "phrase searching", FileType.TEXT_PLAIN, "big boat");
dataContent.usingUser(userModel).usingSite(siteModel).createContent(fileBigBananaBoat);
fileYellowBananaBigBoat = new FileModel(unique_searchString + "-5.txt", "yellow banana big boat", "phrase searching", FileType.TEXT_PLAIN, "yellow banana big boat");
dataContent.usingUser(userModel).usingSite(siteModel).createContent(fileYellowBananaBigBoat);
fileBigYellowBoat = new FileModel(unique_searchString + "-6.txt", "big yellow boat", "phrase searching", FileType.TEXT_PLAIN, "big yellow boat");
dataContent.usingUser(userModel).usingSite(siteModel).createContent(fileBigYellowBoat);
waitForIndexing(fileBigYellowBoat.getName(), true);
}
@SuppressWarnings("unchecked")
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 1)
public void testPhraseQueries() throws Exception
{
// yellow banana: 5 results expected
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select cm_content from alfresco where cm_content = '(yellow banana)'");
sqlRequest.setLimit(10);
RestResponse response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Set Expected Result
expectedContent = new ArrayList<String>();
expectedContent.add(Arrays.asList(fileBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBananaBigBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBoat.getContent()));
// Check Result count matches
response.assertThat().body("list.pagination.count", Matchers.equalTo(expectedContent.size()));
// Check Results match
Collection<Map<String, String>> actualContent = response.getResponse().body().jsonPath().get("list.entries.entry.value");
Assert.assertTrue(actualContent.containsAll(expectedContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
Assert.assertTrue(expectedContent.containsAll(actualContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
// yellow banana big boat: 6 results expected
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select cm_content from alfresco where cm_content = '(yellow banana big boat)'");
sqlRequest.setLimit(10);
response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Set Expected Result
expectedContent = new ArrayList<String>();
expectedContent.add(Arrays.asList(fileBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBananaBigBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigBananaBoat.getContent()));
// Check Result count matches
response.assertThat().body("list.pagination.count", Matchers.equalTo(expectedContent.size()));
// Check Results match
actualContent = response.getResponse().body().jsonPath().get("list.entries.entry.value");
Assert.assertTrue(actualContent.containsAll(expectedContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
Assert.assertTrue(expectedContent.containsAll(actualContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
// yellow banana big boat: 4 results expected
sqlRequest = new SearchSqlRequest();
sqlRequest.setSql("select cm_content from alfresco where cm_content = '(big boat)'");
sqlRequest.setLimit(10);
response = searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Set Expected Result
expectedContent = new ArrayList<String>();
expectedContent.add(Arrays.asList(fileBigYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBananaBigBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigBananaBoat.getContent()));
// Check Result count matches
response.assertThat().body("list.pagination.count", Matchers.equalTo(expectedContent.size()));
// Check Results match
actualContent = response.getResponse().body().jsonPath().get("list.entries.entry.value");
Assert.assertTrue(actualContent.containsAll(expectedContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
Assert.assertTrue(expectedContent.containsAll(actualContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
}
@SuppressWarnings("unchecked")
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 2)
public void testPhraseQueriesViaJDBC() throws Exception
{
// yellow banana: 5 results expected
SearchSqlJDBCRequest sqlRequest = new SearchSqlJDBCRequest();
String sql = "select cm_content from alfresco where cm_content = '(yellow banana)'";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(userModel);
ResultSet rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
Assert.assertNotNull(rs);
Assert.assertNull(sqlRequest.getErrorDetails());
// Set Expected Result
expectedContent = new ArrayList<String>();
expectedContent.add(Arrays.asList(fileBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBananaBigBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBoat.getContent()));
Integer i = 0;
List actualContent = new ArrayList<String>();
while (rs.next())
{
// Field values are retrieved
Assert.assertNotNull(rs.getString("cm_content"));
actualContent.add(Arrays.asList(rs.getString("cm_content")));
i++;
}
Assert.assertTrue(i == expectedContent.size());
Assert.assertTrue(actualContent.containsAll(expectedContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
Assert.assertTrue(expectedContent.containsAll(actualContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
// yellow banana big boat: 6 results expected
sql = "select cm_content from alfresco where cm_content = '(yellow banana big boat)'";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(userModel);
rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
Assert.assertNotNull(rs);
Assert.assertNull(sqlRequest.getErrorDetails());
// Set Expected Result
expectedContent = new ArrayList<String>();
expectedContent.add(Arrays.asList(fileBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBananaBigBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigBananaBoat.getContent()));
i = 0;
actualContent = new ArrayList<String>();
while (rs.next())
{
// Field values are retrieved
Assert.assertNotNull(rs.getString("cm_content"));
actualContent.add(Arrays.asList(rs.getString("cm_content")));
i++;
}
Assert.assertTrue(i == expectedContent.size());
Assert.assertTrue(actualContent.containsAll(expectedContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
Assert.assertTrue(expectedContent.containsAll(actualContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
// big boat: 4 results expected
sql = "select cm_content from alfresco where cm_content = '(big boat)'";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(userModel);
rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
Assert.assertNotNull(rs);
Assert.assertNull(sqlRequest.getErrorDetails());
// Set Expected Result
expectedContent = new ArrayList<String>();
expectedContent.add(Arrays.asList(fileBigYellowBanana.getContent()));
expectedContent.add(Arrays.asList(fileYellowBananaBigBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigYellowBoat.getContent()));
expectedContent.add(Arrays.asList(fileBigBananaBoat.getContent()));
i = 0;
actualContent = new ArrayList<String>();
while (rs.next())
{
// Field values are retrieved
Assert.assertNotNull(rs.getString("cm_content"));
actualContent.add(Arrays.asList(rs.getString("cm_content")));
i++;
}
Assert.assertTrue(i == expectedContent.size());
Assert.assertTrue(actualContent.containsAll(expectedContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
Assert.assertTrue(expectedContent.containsAll(actualContent), String.format("Phrase Search Results expected: %s Actual: %s", expectedContent.toString(), actualContent.toString()));
}
}

View File

@@ -1,213 +0,0 @@
/*
* Copyright (C) 2018 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.service.search.e2e.insightEngine.sql;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.dataprep.SiteService.Visibility;
import org.alfresco.rest.requests.search.SearchSQLJDBC;
import org.alfresco.service.search.e2e.searchservices.AbstractSearchTest;
import org.alfresco.rest.search.SearchSqlJDBCRequest;
import org.alfresco.utility.data.RandomData;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import org.testng.Assert;
/**
* Search SQL end point test via JDBC.
* @author MSuzuki
* @author Meenal Bhave
*
*/
public class SearchSQLViaJDBCTest extends AbstractSearchTest
{
List<String> sites = new ArrayList<String>();
SearchSQLJDBC searchSql;
SearchSqlJDBCRequest sqlRequest = new SearchSqlJDBCRequest();
@AfterMethod(alwaysRun=true)
public void cleanUp() throws SQLException
{
restClient.withSearchSqlViaJDBC().clearSearchQuery(sqlRequest);
sqlRequest = new SearchSqlJDBCRequest();
sites = new ArrayList<String>();
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority=01)
public void testQueryPublicSite() throws SQLException
{
SiteModel publicSite = new SiteModel(RandomData.getRandomName("SiteSearch"));
publicSite.setVisibility(Visibility.PUBLIC);
publicSite = dataSite.usingUser(adminUserModel).createSite(publicSite);
String sql = "select SITE,CM_OWNER from alfresco where SITE ='" + publicSite.getTitle() + "' group by SITE,CM_OWNER";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(userModel);
ResultSet rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
while (rs.next())
{
// User can see the Public Site created by other user
Assert.assertNotNull(rs.getString("SITE"));
Assert.assertTrue(publicSite.getTitle().equalsIgnoreCase(rs.getString("SITE")));
Assert.assertNotNull(rs.getString("CM_OWNER"));
Assert.assertTrue(rs.getString("CM_OWNER").contains(adminUserModel.getUsername()));
}
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority=02)
public void testQueryMyCreatedPrivateSite() throws SQLException
{
String sql = "select distinct SITE from alfresco where SITE ='" + siteModel.getTitle() + "'";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(userModel);
ResultSet rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
while (rs.next())
{
// User can see Own Private Site
Assert.assertNotNull(rs.getString("SITE"));
Assert.assertTrue(siteModel.getTitle().equalsIgnoreCase(rs.getString("SITE")));
}
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority=03)
public void testQueryPrivateSiteWithSuperUser() throws SQLException
{
String sql = "select distinct SITE from alfresco where SITE ='" + siteModel.getTitle() + "'";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(adminUserModel);
ResultSet rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
while (rs.next())
{
// Super user can see Private Site created by other user
Assert.assertNotNull(rs.getString("SITE"));
Assert.assertTrue(siteModel.getTitle().equalsIgnoreCase(rs.getString("SITE")));
}
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority=04)
public void testQueryPrivateSiteWithSimpleUser() throws SQLException
{
UserModel managerUser = dataUser.createRandomTestUser("UserSearchMgr");
String sql = "select SITE from alfresco where SITE = '" + siteModel.getTitle() + "'";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(managerUser);
// Non admin user can NOT see Private Site created by other user
ResultSet rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
Assert.assertFalse(rs.next());
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority=05)
public void testQueryErrorReturned() throws SQLException
{
String expectedError = "Column 'SITE1' not found";
String sql = "select SITE1 from alfresco";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(userModel);
// Appropriate error is retrieved when SQL is incorrect
ResultSet rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
String error = sqlRequest.getErrorDetails();
Assert.assertNotNull(error);
Assert.assertTrue(error.contains(expectedError), "Error shown: " + error + " Error expected: " + expectedError);
// Record set is null
Assert.assertNull(rs);
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 06)
public void testQuerySelectStar() throws SQLException
{
// Select * query with limit clause
String sql = "select * from alfresco limit 5";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(userModel);
// Select * with limit clause works: No error is retrieved
ResultSet rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
Assert.assertNotNull(rs);
Assert.assertNull(sqlRequest.getErrorDetails());
while (rs.next())
{
// Field values are retrieved
Assert.assertNotNull(rs.getString("PATH"));
Assert.assertNotNull(rs.getString("DBID"));
Assert.assertNotNull(rs.getString("cm_name"));
}
// Select * query Without limit clause: No error is retrieved
sql = "select * from alfresco";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(userModel);
// No error is retrieved when SQL is incorrect
rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
Assert.assertNotNull(rs);
Assert.assertNull(sqlRequest.getErrorDetails());
while (rs.next())
{
// Field values are retrieved
Assert.assertNotNull(rs.getString("PATH"));
Assert.assertNotNull(rs.getString("DBID"));
Assert.assertNotNull(rs.getString("cm_name"));
}
}
@Test(groups = { TestGroup.SEARCH, TestGroup.REST_API, TestGroup.INSIGHT_10 }, priority = 07)
public void testQuerySelectDistinct() throws SQLException
{
// Select distinct query with limit clause
String sql = "select distinct cm_name from alfresco limit 5";
sqlRequest.setSql(sql);
sqlRequest.setAuthUser(adminUserModel);
// Select distinct with limit clause works: No error is retrieved
ResultSet rs = restClient.withSearchSqlViaJDBC().executeQueryViaJDBC(sqlRequest);
Assert.assertNotNull(rs);
Assert.assertNull(sqlRequest.getErrorDetails());
while (rs.next())
{
// Field values are retrieved
Assert.assertNotNull(rs.getString("cm_name"));
}
}
}

View File

@@ -1,218 +0,0 @@
/*
* Copyright (C) 2018 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.service.search.e2e.insightEngine.sql;
import java.util.UUID;
import org.alfresco.service.search.e2e.searchservices.AbstractSearchTest;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.data.CustomObjectTypeProperties;
import org.alfresco.utility.model.ContentModel;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.report.Bug;
import org.hamcrest.Matchers;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.alfresco.rest.RestTest;
/**
* Tests for /sql end point Search API when a custom model contains identifiers that need to be quoted in queries.
* While it seems there is not an ANSI standard for naming database objects, on the other side the most popular
* databases don't like columns starting with a number.
* In those cases, the column identifier need to be quoted. How to quote a given object identifier (a column name, in
* this case) depends on the specific database lexicon: Oracle uses double quotes ("), MySQL uses back quotes(`).
*
* At time of writing, the lexicon used by the /sql endpoint is MySql so queries that use column names starting with
* a number need to be quoted with back quotes.
*
*/
public class SearchSQLWithQuotedIdentifiers extends AbstractSearchTest
{
private String songName;
private String genre;
private String coProducer;
private String artistName;
private String voiceType;
private String bassistName;
private String drummerName;
private String saxophonistName;
private FileModel file5;
/**
* Setup fixture for this test case.
* Overrides the superlayer method because the data preparation requires a bit different preconditions.
* The method uses a transient test site created in the {@link RestTest#checkServerHealth()} and on top of that:
*
* <ul>
* <li>It adds a user which is added to the site as contributor</li>
* <li>
* It deploys a custom model which declares a set of prefixes composed by a combination of digits, hyphens
* and underscores. Those prefixes are associated with four entities (song, artist, bassist, drummer and
* sax) with their corresponding attributes.
* </li>
* <li>
* It creates a folder with 5 files associated with the types declared in the model.
* That allows those files to have a value for the properties/attributes included in the model definition.
* </li>
* </ul>
*
* @see RestTest#checkServerHealth()
* @throws Exception hopefully never, otherwise the test fails.
*/
@BeforeClass(alwaysRun = true)
public void localDataPreparation() throws Exception
{
songName = "The Dry Cleaner from Des Moines ";
genre = "Jazz, vocal jazz ";
coProducer = "Roberta Joan Mitchell ";
artistName = "Joni Mitchell " + UUID.randomUUID();
voiceType = "Blue Mezzo (1965-1984) / Cloudy Contralto (1985-present) ";
bassistName = "Jaco Pastorius";
drummerName = "Peter Erskine";
saxophonistName = "Wayne Shorter";
dataContent.usingAdmin().deployContentModel("model/search-1063-model.xml");
dataUser.addUserToSite(userModel, siteModel, UserRole.SiteContributor);
testSite = siteModel;
FolderModel testFolder = dataContent.usingSite(testSite).usingUser(userModel).createFolder();
file = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
file2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
file3 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
file4 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
file5 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
dataContent.usingUser(userModel)
.usingResource(testFolder)
.createCustomContent(
file,
"D:1:song",
new CustomObjectTypeProperties()
.addProperty("1:name", songName)
.addProperty("1:genre", genre)
.addProperty("1:co-producer", coProducer));
dataContent.usingUser(userModel)
.usingResource(testFolder)
.createCustomContent(
file2,
"D:123:artist",
new CustomObjectTypeProperties()
.addProperty("123:name", artistName)
.addProperty("123:voice_type", voiceType));
dataContent.usingUser(userModel)
.usingResource(testFolder)
.createCustomContent(
file3,
"D:1_2_3:bassist",
new CustomObjectTypeProperties()
.addProperty("1_2_3:name", bassistName));
dataContent.usingUser(userModel)
.usingResource(testFolder)
.createCustomContent(
file4,
"D:1-2-3:drummer",
new CustomObjectTypeProperties()
.addProperty("1-2-3:name", drummerName));
ContentModel content =
dataContent.usingUser(userModel)
.usingResource(testFolder)
.createCustomContent(
file5,
"D:1-2_3:saxophonist",
new CustomObjectTypeProperties()
.addProperty("1-2_3:name", saxophonistName));
waitForIndexing(content.getName(), true);
}
@Test(groups={TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_1})
@Bug(id = "SEARCH-1063")
public void prefixIsComposedByOneNumber() throws Exception
{
executeSqlAsSolr("select cm_name, `1_name`, `1_genre`, `1_co-producer` from alfresco where TYPE='1:song' and SITE='" + testSite.getId() + "'");
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set.docs[0].cm_name", Matchers.equalTo(file.getName()));
restClient.onResponse().assertThat().body("result-set.docs[0].1_name", Matchers.equalTo(songName));
restClient.onResponse().assertThat().body("result-set.docs[0].1_genre", Matchers.equalTo(genre));
restClient.onResponse().assertThat().body("result-set.docs[0].1_co-producer", Matchers.equalTo(coProducer));
}
@Test(groups={TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_1})
@Bug(id = "SEARCH-1063")
public void prefixIsComposedByMultipleNumbers() throws Exception
{
executeSqlAsSolr("select cm_name, `123_name`, `123_voice_type` from alfresco where TYPE='123:artist' and SITE='" + testSite.getId() + "'");
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set.docs[0].cm_name", Matchers.equalTo(file2.getName()));
restClient.onResponse().assertThat().body("result-set.docs[0].123_name", Matchers.equalTo(artistName));
restClient.onResponse().assertThat().body("result-set.docs[0].123_voice_type", Matchers.equalTo(voiceType));
}
@Test(groups={TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_1})
@Bug(id = "SEARCH-1063")
public void prefixIncludesUnderscore() throws Exception
{
executeSqlAsSolr("select cm_name, `1_2_3_name` from alfresco where TYPE='1_2_3:bassist' and SITE='" + testSite.getId() + "'");
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set.docs[0].cm_name", Matchers.equalTo(file3.getName()));
restClient.onResponse().assertThat().body("result-set.docs[0].1_2_3_name", Matchers.equalTo(bassistName));
}
@Test(groups={TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_1})
@Bug(id = "SEARCH-1063")
public void prefixIncludesHyphen() throws Exception
{
executeSqlAsSolr("select cm_name, `1-2-3_name` from alfresco where TYPE='1-2-3:drummer' and SITE='" + testSite.getId() + "'");
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set.docs[0].cm_name", Matchers.equalTo(file4.getName()));
restClient.onResponse().assertThat().body("result-set.docs[0].1-2-3_name", Matchers.equalTo(drummerName));
}
@Test(groups={TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_1})
@Bug(id = "SEARCH-1063")
public void prefixIncludesHyphenAndUnderscore() throws Exception
{
executeSqlAsSolr("select cm_name, `1-2_3_name` from alfresco where TYPE='1-2_3:saxophonist' and SITE='" + testSite.getId() + "'");
restClient.assertStatusCodeIs(HttpStatus.OK);
restClient.onResponse().assertThat().body("result-set.docs[0].cm_name", Matchers.equalTo(file5.getName()));
restClient.onResponse().assertThat().body("result-set.docs[0].1-2_3_name", Matchers.equalTo(saxophonistName));
}
}

View File

@@ -1,584 +0,0 @@
/*
* 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.service.search.e2e.insightEngine.sql;
import static java.util.Arrays.asList;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.service.search.e2e.AbstractSearchServiceE2E;
import org.alfresco.utility.LogFactory;
import org.alfresco.utility.data.DataContent;
import org.alfresco.utility.data.DataSite;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.TestGroup;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Purpose of this TestClass is to test that the variants of <select *> query works as expected with CustomModels
*
* @author meenal bhave
* @see <a href="https://issues.alfresco.com/jira/browse/SEARCH-873>SEARCH-873</a>
*/
public class SelectStarTest extends AbstractSearchServiceE2E
{
private static Logger LOG = LogFactory.getLogger();
@Autowired
protected DataSite dataSite;
@Autowired
protected DataContent dataContent;
private FolderModel testFolder;
/**
* expFile1: id=10, empNo=000001, Location = London,
* CostCentre=750, amount = 100, ExchangeRate=10, Approved= true,
* Recorded_At, ExpenseDate=now,
* Notes='London is a busy city'
*/
private FileModel expFile1;
/**
* expFile2: id=30, empNo= 1, Location = Paris,
* CostCentre=950, amount = 60.5, ExchangeRate=12, Approved=false,
* Recorded_At, ExpenseDate=now-1month,
* Notes='london is a busy city'
*/
private FileModel expFile2;
/**
* expFile3: id=50, empNo= 56, Location = london,
* CostCentre=750, amount = 60, ExchangeRate=12.5, Approved=true,
* Recorded_At, ExpenseDate=now-1year,
* Notes='Paris is a busy city'
*/
private FileModel expFile3;
/**
* expFile4: id=null, empNo=null, Location = null,
* CostCentre=null, amount = null, ExchangeRate=null, Approved=false,
* Recorded_At, ExpenseDate=null, Notes=null
*/
private FileModel expFile4;
/**
* expFile5: No custom property is set
*/
private FileModel expFile5;
/**
* TIME_NOW: Date Time now based on system clock
*/
private static ZonedDateTime TIME_NOW = ZonedDateTime.now();
/**
* DATE_NOW: Today's date in ISO Date format
*/
private static final String DATE_NOW = TIME_NOW.format(DateTimeFormatter.ISO_DATE).replace("Z", "");
/**
* DT_NOW: Date Time now, in ISO Instant format
*/
private static final String DT_NOW = TIME_NOW.format(DateTimeFormatter.ISO_INSTANT);
/**
* DT_NOW_MINUS_1_MONTH: ISO Date a month ago, in ISO Instant format
*/
private static final String DT_NOW_MINUS_1_MONTH = TIME_NOW.minusMonths(1).format(DateTimeFormatter.ISO_INSTANT);
/**
* DT_NOW_MINUS_1_YEAR: ISO Date a year ago, in ISO Instant format
*/
private static final String DT_NOW_MINUS_1_YEAR = TIME_NOW.minusYears(1).format(DateTimeFormatter.ISO_INSTANT);
@BeforeClass(alwaysRun = true)
public void setupEnvironment() throws Exception
{
serverHealth.assertServerIsOnline();
super.springTestContextPrepareTestInstance();
try
{
deployCustomModel("model/expense-model.xml");
}
catch (Exception e)
{
LOG.warn("Error Loading Expense Model", e);
}
testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder();
// Create 5 files with the following data:
expFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "expense1");
expFile1.setName("exp1-"+ expFile1.getName());
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:expense:expenseReport");
properties.put(PropertyIds.NAME, expFile1.getName());
properties.put("expense:id", 10);
properties.put("expense:EmpNo", 000001);
properties.put("expense:Location", "London");
properties.put("expense:CostCentre__1", "750");
properties.put("expense:Amount", 100);
properties.put("expense:Currency", "GBP");
properties.put("expense:ExchangeRate", 10);
properties.put("expense:Approved", true);
properties.put("expense:Notes", "London is a busy city");
properties.put("expense:Recorded_At", Date.from(LocalDateTime.now().toInstant(ZoneOffset.UTC)));
properties.put("expense:ExpenseDate", Date.from(LocalDateTime.now().toInstant(ZoneOffset.UTC)));
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
.createFile(expFile1, properties, VersioningState.MAJOR).assertThat().existsInRepo();
expFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "expense2");
expFile2.setName("exp2-"+ expFile2.getName());
properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:expense:expenseReport");
properties.put(PropertyIds.NAME, expFile2.getName());
properties.put("expense:id", 30);
properties.put("expense:EmpNo", 1);
properties.put("expense:Location", "Paris");
properties.put("expense:CostCentre__1", "950");
properties.put("expense:Amount", 60.5);
properties.put("expense:Currency", "GBP");
properties.put("expense:ExchangeRate", 12);
properties.put("expense:Approved", false);
properties.put("expense:Notes", "london is a busy city");
properties.put("expense:Recorded_At", Date.from(LocalDateTime.now().minusMonths(1).toInstant(ZoneOffset.UTC)));
properties.put("expense:ExpenseDate", Date.from(LocalDateTime.now().minusMonths(1).toInstant(ZoneOffset.UTC)));
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
.createFile(expFile2, properties, VersioningState.MAJOR).assertThat().existsInRepo();
expFile3 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "expense3");
expFile3.setName("exp3-"+ expFile3.getName());
properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:expense:expenseReport");
properties.put(PropertyIds.NAME, expFile3.getName());
properties.put("expense:id", 50);
properties.put("expense:EmpNo", 56);
properties.put("expense:Location", "london");
properties.put("expense:CostCentre__1", "750");
properties.put("expense:Amount", 60);
properties.put("expense:Currency", "GBP");
properties.put("expense:ExchangeRate", 12.5);
properties.put("expense:Approved", true);
properties.put("expense:Notes", "Paris is a busy city");
properties.put("expense:Recorded_At", Date.from(LocalDateTime.now().minusYears(1).toInstant(ZoneOffset.UTC)));
properties.put("expense:ExpenseDate", Date.from(LocalDateTime.now().minusYears(1).toInstant(ZoneOffset.UTC)));
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
.createFile(expFile3, properties, VersioningState.MAJOR).assertThat().existsInRepo();
expFile4 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "expense4");
expFile4.setName("exp4-"+ expFile4.getName());
properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:expense:expenseReport");
properties.put(PropertyIds.NAME, expFile4.getName());
properties.put("expense:id", null);
properties.put("expense:EmpNo", null);
properties.put("expense:Location", null);
properties.put("expense:CostCentre__1", null);
properties.put("expense:Amount", null);
properties.put("expense:Currency", "GBP");
properties.put("expense:ExchangeRate", null);
properties.put("expense:Approved", false);
properties.put("expense:Notes", null);
properties.put("expense:Recorded_At", null);
properties.put("expense:ExpenseDate", null);
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
.createFile(expFile4, properties, VersioningState.MAJOR).assertThat().existsInRepo();
expFile5 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "expense5");
expFile5.setName("exp5-"+ expFile4.getName());
properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:expense:expenseReport");
properties.put(PropertyIds.NAME, expFile5.getName());
cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
.createFile(expFile5, properties, VersioningState.MAJOR).assertThat().existsInRepo();
// Wait for the file to be indexed
waitForIndexing(expFile4.getName(), true);
}
@Test(priority = 1, groups = { TestGroup.INSIGHT_11 })
public void testTextField()
{
testSqlQuery("select * from alfresco where `expense:Location` = 'london'", 2);
testSqlQuery("select * from alfresco where `expense:Location` >= 'London'", 3);
testSqlQuery("select * from alfresco where `expense:Location` >= 'london'", 3);
testSqlQuery("select * from alfresco where `expense:Location` <= 'London'", 2);
testSqlQuery("select * from alfresco where `expense:Location` <='london'", 2);
testSqlQuery("select * from alfresco where `expense:Location` <> 'london' and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where `expense:Location` = 'Reading'", 0);
testSqlQuery("select * from alfresco where `expense:Location` != 'Reading' and TYPE = 'expense:expenseReport'", 5);
testSqlQuery("select * from alfresco where `expense:Location` not in ('Paris', 'Reading') and TYPE = 'expense:expenseReport'", 4);
testSqlQuery("select * from alfresco where `expense:Location` not in ('Paris', 'Reading') and `expense:Location` in ('london')", 2);
// Field name with _
testSqlQuery("select * from alfresco where expense_Location = 'london'", 2);
}
// TODO: Enable when fixed: Bug: Search-1457
@Test(priority = 2, groups = { TestGroup.INSIGHT_11 }, enabled = false)
public void testTextFieldNullValues()
{
testSqlQuery("select * from alfresco where `expense:Location` = '*' and TYPE = 'expense:expenseReport'", 3); //4 or 3
testSqlQuery("select * from alfresco where `expense:Location` != '*' and TYPE = 'expense:expenseReport'", 2); //0 or 1 or 2
testSqlQuery("select * from alfresco where `expense:Location` in ('Paris', 'Reading', null) and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where `expense:Location` not in ('Paris', 'Reading', null) and TYPE = 'expense:expenseReport'", 2); //0 or 2
testSqlQuery("select * from alfresco where `expense:Location` is null and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:Location` is not null and TYPE = 'expense:expenseReport'", 3);
}
@Test(priority = 3, groups = { TestGroup.INSIGHT_11 })
public void testMLTextField()
{
testSqlQuery("select * from alfresco where `expense:Notes` = 'London is a busy'", 2);
testSqlQuery("select * from alfresco where `expense:Notes` = 'london'", 2);
testSqlQuery("select * from alfresco where `expense:Notes` >= 'London'", 3);
testSqlQuery("select * from alfresco where `expense:Notes` >= 'london'", 3);
testSqlQuery("select * from alfresco where `expense:Notes` <= 'London' and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where `expense:Notes` <= 'london*' and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where `expense:Notes` in ('Paris', 'london')", 3);
testSqlQuery("select * from alfresco where `expense:Notes` not in ('London', 'london') and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where expense_Notes = 'Paris'", 1);
}
// TODO: Update on fix: Search-1457
@Test(priority = 4, groups = { TestGroup.INSIGHT_11 }, enabled=false)
public void testMLTextFieldNullValues()
{
testSqlQuery("select * from alfresco where `expense:Notes` = '*' and TYPE = 'expense:expenseReport'", 3); //4
testSqlQuery("select * from alfresco where `expense:Notes` != '*' and TYPE = 'expense:expenseReport'", 2); //0 or 1
testSqlQuery("select * from alfresco where `expense:Notes` in ('london', null) and TYPE = 'expense:expenseReport'", 4);
testSqlQuery("select * from alfresco where `expense:Notes` not in ('london', null) and TYPE = 'expense:expenseReport'", 1); //0 or 1
testSqlQuery("select * from alfresco where `expense:Notes` is Null and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:Notes` is not null and TYPE = 'expense:expenseReport'", 3);
}
@Test(priority = 5, groups = { TestGroup.INSIGHT_11 })
public void testIntegerField()
{
testSqlQuery("select * from alfresco where `expense:id` >= '10'", 3);
testSqlQuery("select * from alfresco where `expense:id` > 10", 2);
testSqlQuery("select * from alfresco where `expense:id` <= 30", 2);
testSqlQuery("select * from alfresco where `expense:id` >= 5", 3);
testSqlQuery("select * from alfresco where `expense:id`< 12 and TYPE = 'expense:expenseReport'", 1);
testSqlQuery("select * from alfresco where `expense:id` = 50", 1);
testSqlQuery("select * from alfresco where `expense:id` in (10, 30, 0)", 2);
testSqlQuery("select * from alfresco where `expense:id` not in (5, 10) and TYPE = 'expense:expenseReport'", 4);
testSqlQuery("select * from alfresco where expense_id = 50 and TYPE = 'expense:expenseReport'", 1);
}
// TODO: Update on fix: Search-1457
@Test(priority = 6, groups = { TestGroup.INSIGHT_11 }, enabled = false)
public void testIntegerFieldNullValues()
{
testSqlQuery("select * from alfresco where `expense:id` = '*' and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where `expense:id` != '*' and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:id` in (5, 10, null) and TYPE = 'expense:expenseReport'", 3); //0 or 3
testSqlQuery("select * from alfresco where `expense:id` not in (5, 10, null) and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:id` is null and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:id` is not null and TYPE = 'expense:expenseReport'", 3);
}
@Test(priority = 7, groups = { TestGroup.INSIGHT_11 })
public void testLongField()
{
testSqlQuery("select * from alfresco where `expense:EmpNo` >= '000001'", 3);
testSqlQuery("select * from alfresco where `expense:EmpNo` >=000001", 3);
testSqlQuery("select * from alfresco where `expense:EmpNo` <= 56 and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where `expense:EmpNo` >= 50", 1);
testSqlQuery("select * from alfresco where `expense:EmpNo` = 1", 2);
testSqlQuery("select * from alfresco where `expense:EmpNo` in (00001, 1, 50)", 2);
testSqlQuery("select * from alfresco where `expense:EmpNo` not in (1, 50) and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where expense_EmpNo = 56", 1);
}
// TODO: Update on fix: Search-1457
@Test(priority = 8, groups = { TestGroup.INSIGHT_11 }, enabled=false)
public void testLongFieldNullValues()
{
testSqlQuery("select * from alfresco where `expense:EmpNo` = '*' and TYPE = 'expense:expenseReport'", 3); //4
testSqlQuery("select * from alfresco where `expense:EmpNo` != '*' and TYPE = 'expense:expenseReport'", 1); //0
testSqlQuery("select * from alfresco where `expense:EmpNo` in (1, 56, null) and TYPE = 'expense:expenseReport'", 4); //0 or 1
testSqlQuery("select * from alfresco where `expense:EmpNo` not in (1, 56, null) and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:EmpNo` is null and TYPE = 'expense:expenseReport'", 1); //0 or 1
testSqlQuery("select * from alfresco where `expense:EmpNo` is not null and TYPE = 'expense:expenseReport'", 1); //0 or 1
}
@Test(priority = 9, groups = { TestGroup.INSIGHT_11 })
public void testDoubleField()
{
testSqlQuery("select * from alfresco where `expense:ExchangeRate` >= '12'", 2);
testSqlQuery("select * from alfresco where `expense:ExchangeRate` >= 12.5", 1);
testSqlQuery("select * from alfresco where `expense:ExchangeRate` <= 12 and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:ExchangeRate` >= 12.5", 1);
testSqlQuery("select * from alfresco where `expense:ExchangeRate` in (12, 10)", 2);
testSqlQuery("select * from alfresco where `expense:ExchangeRate` not in (12.5, 100) and TYPE = 'expense:expenseReport'", 4);
testSqlQuery("select * from alfresco where expense_ExchangeRate = 12.5", 1);
}
// TODO: Update on fix: Search-1457
@Test(priority = 10, groups = { TestGroup.INSIGHT_11 }, enabled = false)
public void testDoubleFieldNullValues()
{
testSqlQuery("select * from alfresco where `expense:ExchangeRate` = '*' and TYPE = 'expense:expenseReport'", 3); //4
testSqlQuery("select * from alfresco where `expense:ExchangeRate` != '*' and TYPE = 'expense:expenseReport'", 2); //0
testSqlQuery("select * from alfresco where `expense:ExchangeRate` in (12.5, 100, null) and TYPE = 'expense:expenseReport'", 4);
testSqlQuery("select * from alfresco where `expense:ExchangeRate` not in (12.5, 100, null) and TYPE = 'expense:expenseReport'", 1);
testSqlQuery("select * from alfresco where `expense:ExchangeRate` is null and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:ExchangeRate` is not null and TYPE = 'expense:expenseReport'", 3);
}
@Test(priority = 11, groups = { TestGroup.INSIGHT_11 })
public void testFloatField()
{
testSqlQuery("select * from alfresco where `expense:amount` >= '60.50'", 2);
testSqlQuery("select * from alfresco where `expense:amount` >= 60", 3);
testSqlQuery("select * from alfresco where `expense:amount` <= 60 and TYPE = 'expense:expenseReport'", 1);
testSqlQuery("select * from alfresco where `expense:amount` = 60", 1);
testSqlQuery("select * from alfresco where `expense:amount` in (60, 100)", 2);
testSqlQuery("select * from alfresco where `expense:amount` not in (60.5, 100) and TYPE = 'expense:expenseReport'", 3);
// unsupported?
// testSqlQuery("select * from alfresco where `expense:amount` not in (60.5, 100, null) and TYPE = 'expense:expenseReport'", 1);
testSqlQuery("select * from alfresco where expense_amount = 60", 1);
}
// TODO: Update on fix: Search-1457
@Test(priority = 12, groups = { TestGroup.INSIGHT_11 }, enabled=false)
public void testFloatFieldNullValues()
{
testSqlQuery("select * from alfresco where `expense:amount` >= '60.50'", 2);
testSqlQuery("select * from alfresco where `expense:amount` >= 60", 3);
testSqlQuery("select * from alfresco where `expense:amount` <= 60 and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:amount` = 60", 21);
testSqlQuery("select * from alfresco where `expense:amount` in (60, 100)", 2);
testSqlQuery("select * from alfresco where `expense:amount` not in (60.5, 100) and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where expense_amount = 60", 1);
}
@Test(priority = 13, groups = { TestGroup.INSIGHT_11 })
public void testBooleanField()
{
testSqlQuery("select * from alfresco where `expense:Approved` = 'true'", 2);
testSqlQuery("select * from alfresco where `expense:Approved` = 'false'", 2);
testSqlQuery("select * from alfresco where `expense:Approved` <= 'false'", 2); //3 Include the one that's not set
testSqlQuery("select * from alfresco where `expense:Approved` >= 'true'", 2);
testSqlQuery("select * from alfresco where expense_Approved = 'true' and `expense:Location` = 'Paris'", 0);
}
// TODO: Update on fix: Search-1457
@Test(priority = 14, groups = { TestGroup.INSIGHT_11 }, enabled = false)
public void testBooleanFieldNullValues()
{
testSqlQuery("select * from alfresco where `expense:Approved` = '*' and TYPE = 'expense:expenseReport'", 3); //4
testSqlQuery("select * from alfresco where `expense:Approved` != '*' and TYPE = 'expense:expenseReport'", 1); //0
testSqlQuery("select * from alfresco where `expense:Approved` in ('true', null)", 4);
testSqlQuery("select * from alfresco where `expense:Approved` not in ('true', null)", 1);
testSqlQuery("select * from alfresco where `expense:Approved` is null", 2);
testSqlQuery("select * from alfresco where `expense:Approved` is not null", 3);
}
@Test(priority = 15, groups = { TestGroup.INSIGHT_11 })
public void testDateField()
{
testSqlQuery("select * from alfresco where `expense:ExpenseDate` <'" + DT_NOW + "'", 2);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` < '" + DT_NOW + "'", 2);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` < '" + DT_NOW_MINUS_1_MONTH + "'", 1);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` <='NOW-1MONTH/DAY'", 1);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` <='" + DT_NOW_MINUS_1_MONTH + "'", 1);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` >='NOW/DAY'", 1);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` >'" + DT_NOW_MINUS_1_YEAR + "'", 3);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` >'NOW-1YEAR'", 2);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` >'NOW-1YEAR/DAY'", 3);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` >'" + DATE_NOW + "'", 0);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` >'" + DT_NOW + "'", 1);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` > 'NOW/DAY'", 1);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` < ('NOW/DAY') AND `expense:ExpenseDate` >= ('NOW-1YEAR/DAY')", 2);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` in ('" + DATE_NOW + "') and TYPE = 'expense:expenseReport'", 1);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` not in ('" + DT_NOW_MINUS_1_YEAR + "') and TYPE = 'expense:expenseReport'", 5);
testSqlQuery("select * from alfresco where expense_ExpenseDate >= '1970-02-01T01:01:01Z' and TYPE = 'expense:expenseReport'", 3);
}
// TODO: Update on fix: Search-1457
@Test(priority = 16, groups = { TestGroup.INSIGHT_11 }, enabled = false)
public void testDateFieldNullValues()
{
testSqlQuery("select * from alfresco where `expense:ExpenseDate` = '*' and TYPE = 'expense:expenseReport'", 3); //4
testSqlQuery("select * from alfresco where `expense:ExpenseDate` != '*' and TYPE = 'expense:expenseReport'", 2); //0
testSqlQuery("select * from alfresco where `expense:ExpenseDate` in (null, zdate) and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` not in (null, zdate) and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:ExpenseDate` is null and TYPE = 'expense:expenseReport'", 2); //4
testSqlQuery("select * from alfresco where `expense:ExpenseDate` is not null and TYPE = 'expense:expenseReport'", 3); //0
}
@Test(priority = 17, groups = { TestGroup.INSIGHT_11 })
public void testDateTimeField()
{
testSqlQuery("select * from alfresco where `expense:Recorded_At` <'NOW-1MONTH' and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:Recorded_At` < 'NOW/DAY' and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:Recorded_At` <='" + DT_NOW + "' and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:Recorded_At` >='NOW-1YEAR/YEAR'", 3);
testSqlQuery("select * from alfresco where `expense:Recorded_At` >'2018-01-01'", 3);
testSqlQuery("select * from alfresco where `expense:Recorded_At` > 'NOW-1MONTHS'", 1);
testSqlQuery("select * from alfresco where `expense:Recorded_At` <'" + DT_NOW + "' and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:Recorded_At` in ('" + DATE_NOW + "') and TYPE = 'expense:expenseReport'", 1);
testSqlQuery("select * from alfresco where `expense:Recorded_At` in ('" + DT_NOW + "') and TYPE = 'expense:expenseReport'", 0);
testSqlQuery("select * from alfresco where `expense:Recorded_At` not in ('" + DT_NOW_MINUS_1_YEAR + "') and TYPE = 'expense:expenseReport'", 5);
testSqlQuery("select * from alfresco where expense_Recorded_At >= '1970-02-01T01:01:01Z' and TYPE = 'expense:expenseReport'", 3);
}
// TODO: Update on fix: Search-1457
@Test(priority = 18, groups = { TestGroup.INSIGHT_11 }, enabled = false)
public void testDateTimeFieldNullValues()
{
testSqlQuery("select * from alfresco where `expense:Recorded_At` = '*' and TYPE = 'expense:expenseReport'", 3); //4
testSqlQuery("select * from alfresco where `expense:Recorded_At` != '*' and TYPE = 'expense:expenseReport'", 1); //0
testSqlQuery("select * from alfresco where `expense:Recorded_At` in (null, zdt) and TYPE = 'expense:expenseReport'", 3);
testSqlQuery("select * from alfresco where `expense:Recorded_At` not in (null, zdt) and TYPE = 'expense:expenseReport'", 2);
testSqlQuery("select * from alfresco where `expense:Recorded_At` is null and TYPE = 'expense:expenseReport'", 2); //4
testSqlQuery("select * from alfresco where `expense:Recorded_At` is not null and TYPE = 'expense:expenseReport'", 3); //0
}
// TODO: Search-1477: Enable, Uncomment Tests when bug is fixed
@Test(priority = 19, groups = { TestGroup.INSIGHT_11 }, enabled = false)
public void testVirtualTimeDimensions()
{
testSqlQuery("select * from alfresco where TYPE = 'expense:expenseReport' order by cm_created desc", 5);
// OOTB fields: 400: cm_created_day not found in any table
testSqlQuery("select cm_created_day, count(*) as total from alfresco"
+ " where cm_created >= 'NOW/DAY' AND `cm:name` >= 'exp'"
+ " group by cm_created_day", 5);
testSqlQuery("Select Site, cm_name, cm_created_day from alfresco "
+ " where `cm:name` >= 'exp'"
+ " group by cm_created "
+ " having sum(`expense:amount`) > 10"
+ " order by `cm:created_day` desc", 5);
//Custom fields
testSqlQuery("Select Site, cm_name, expense_Recorded_At_day from alfresco "
+ " where type = 'cm:content' and `cm:name` >= 'exp' "
+ " group by expense_Recorded_At_day"
+ " having sum(`cm:content.size`) > 1000"
+ " order by expense_Recorded_At_day desc", 5);
}
@Test(priority = 20, groups = { TestGroup.INSIGHT_11 })
public void testFieldNameWithUnderscore()
{
// Field name with _: in where clause
testSqlQuery("select * from alfresco where `expense:CostCentre__1` = '750' AND TYPE = 'expense:expenseReport' order by cm_created desc", 2);
// TODO: Search-1478: Uncomment when fixed
// testSqlQuery("select * from alfresco where TYPE = 'expense:expenseReport' order by `expense:Recorded_At` desc", 5);
// TODO: Search-1478: Uncomment when Fixed
// testSqlQuery("select * from alfresco where TYPE = 'expense:expenseReport' order by expense_Recorded_At desc", 5);
// TODO: Search-1478: Uncomment when Fixed
// testSqlQuery("select expense_Recorded_At_year, sum(expense_amount) from alfresco"
// + " where TYPE = 'expense:expenseReport' "
// + " group by expense_Recorded_At_year"
// + " order by expense_Recorded_At desc", 5);
}
/** Try adding a double space at each location throughout a wildcard query. */
@Test(priority = 21, groups = { TestGroup.INSIGHT_11 })
public void testWildcardQueryContainingExtraSpaces()
{
String baseQuery = "select * from alfresco where `expense:Location` = 'london'";
int wordCount = baseQuery.split(" ").length;
for (int i = 1; i < wordCount; i++)
{
// Replace the ith space with a double space.
String query = baseQuery.replaceFirst("(([^ ]+ ){" + i + "})", "$1 ");
// Check the query still executes correctly.
testSqlQuery(query, 2);
}
}
/** Check that using different whitespace characters doesn't break the query. */
@Test(priority = 22, groups = { TestGroup.INSIGHT_11 })
public void testWildcardQueryContainingDifferentWhitespace()
{
List<String> whitespacesSequences = asList("\n\r", "\n", "\r", "\t", "\f");
whitespacesSequences.forEach(whitespaces -> {
StringBuilder chars = new StringBuilder();
for (int howManyWhiteSpaceChars = 1; howManyWhiteSpaceChars < 3; howManyWhiteSpaceChars++)
{
chars.append(whitespaces);
String query = "select * from alfresco where `expense:id` in (10, 30, 0)".replace(" ", chars);
testSqlQuery(query, 2);
}
});
}
}

View File

@@ -1,682 +0,0 @@
/*
* Copyright 2018 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.service.search.e2e.insightEngine.sql;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.json.Json;
import javax.json.JsonObject;
import org.alfresco.dataprep.SiteService.Visibility;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.rest.search.SearchSqlRequest;
import org.alfresco.service.search.e2e.AbstractSearchServiceE2E;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.data.DataContent;
import org.alfresco.utility.data.DataSite;
import org.alfresco.utility.data.RandomData;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
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.alfresco.utility.report.Bug;
import org.alfresco.utility.report.log.Step;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.hamcrest.Matchers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Purpose of this TestClass is to test that the TimeSeries Aggregation works with/out Nulls and when values are not available
*
* @author meenal bhave
*/
public class TimeSeriesAggrTest extends AbstractSearchServiceE2E
{
@Autowired
protected DataSite dataSite;
@Autowired
protected DataContent dataContent;
protected SiteModel testSite;
private UserModel testExpenseUser1, testExpenseAdmin;
private FolderModel testFolderUser1, testFolderAdmin;
private FileModel expense1, expense2, expense3, expense4;
private Long uniqueRef;
/**
* sql query to retrieve aggregated results based on Virtual Time Dimension _day
*/
private static final String VIRTUAL_TIME_DIMENSION_DAY = ""
+ "select "
+ "finance_CreatedAt_day, "
+ "count(*) as ExpensesCount, "
+ "sum(finance_amount) as TotalExpenses, avg(finance_amount) as AvgExpenses, "
+ "min(finance_amount) as MinExpenses, max(finance_amount) as MaxExpenses "
+ "from alfresco "
+ "group by finance_CreatedAt_day";
/**
* sql query to retrieve aggregated results based on Virtual Time Dimension _month
*/
private static final String VIRTUAL_TIME_DIMENSION_MONTH = ""
+ "select "
+ "finance_CreatedAt_month, "
+ "count(*) as ExpensesCount, "
+ "sum(finance_amount) as TotalExpenses, avg(finance_amount) as AvgExpenses, "
+ "min(finance_amount) as MinExpenses, max(finance_amount) as MaxExpenses "
+ "from alfresco "
+ "group by finance_CreatedAt_month";
/**
* sql query to retrieve aggregated results based on Virtual Time Dimension _year
* Includes order by desc: order by virtual time dimension _year
*/
private static final String VIRTUAL_TIME_DIMENSION_YEAR = ""
+ "select "
+ "finance_CreatedAt_year, "
+ "count(*) as ExpensesCount, "
+ "sum(finance_amount) as TotalExpenses, avg(finance_amount) as AvgExpenses, "
+ "min(finance_amount) as MinExpenses, max(finance_amount) as MaxExpenses "
+ "from alfresco "
+ "group by finance_CreatedAt_Year "
+ "order by finance_CreatedAt_YEAR desc";
/**
* String that adds having clause based on min amount to the query
*/
private static final String HAVING_MIN_AMOUNT = " having min(finance_amount) > 0";
/**
* String that adds having clause based on count to the query
*/
private static final String HAVING_COUNT = " having count(*) >= 1";
/**
* String that adds order by desc clause to the query
*/
private static final String ORDER_BY_DESC = " order by finance_CreatedAt_month desc";
/** The current date. */
private static final LocalDateTime nowDate = LocalDateTime.now();
/** LocalDateTime that represents date 1 month ago */
private static final LocalDateTime dateLastMonth = nowDate.minusMonths(1);
/** The day after one month ago. */
private static final LocalDateTime lastMonthPlusOneDay = dateLastMonth.plusDays(1);
@BeforeClass(alwaysRun = true)
public void setupEnvironment() throws Exception
{
serverHealth.assertServerIsOnline();
// Create test users
testExpenseUser1 = dataUser.createRandomTestUser();
testExpenseAdmin = dataUser.createRandomTestUser();
// Create private test site as testExpenseUser1 and add testExpenseAdmin
testSite = new SiteModel(RandomData.getRandomName("SiteFinance1"));
testSite.setVisibility(Visibility.PRIVATE);
testSite = dataSite.usingUser(testExpenseUser1).createSite(testSite);
dataUser.addUserToSite(testExpenseAdmin, testSite, UserRole.SiteContributor);
// Create test folders for users
testFolderUser1 = dataContent.usingSite(testSite).usingUser(testExpenseUser1).createFolder();
testFolderAdmin = dataContent.usingSite(testSite).usingUser(testExpenseAdmin).createFolder();
// Set Node Permissions for testFolder2, to deny access to testExpenseUser1
JsonObject userPermission = Json
.createObjectBuilder()
.add("permissions",
Json.createObjectBuilder()
.add("isInheritanceEnabled", false)
.add("locallySet",
Json.createObjectBuilder()
.add("authorityId", testExpenseUser1.getUsername())
.add("name", "SiteManager")
.add("accessStatus", "DENIED")
)).build();
String putBody = userPermission.toString();
restClient.authenticateUser(testExpenseAdmin).withCoreAPI().usingNode(testFolderAdmin).updateNode(putBody);
uniqueRef = System.currentTimeMillis();
createTestData();
}
private void createTestData() throws Exception
{
// testExpenseUser1 has 2 expenses, testExpenseAdmin has 2 expense, userAdmin can see all expenses
// Expense1 for testExpenseUser1 dated today: Amount 100
expense1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
expense1.setName("ex-"+ expense1.getName());
Map<String, Object> properties = new HashMap<>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:finance:Expense");
properties.put(PropertyIds.NAME, expense1.getName());
properties.put("finance:No", uniqueRef);
properties.put("finance:Emp", testExpenseUser1.getUsername());
properties.put("finance:amount", 100);
properties.put("finance:CreatedAt", Date.from(nowDate.toInstant(ZoneOffset.UTC)));
properties.put("finance:Location", "Reading");
cmisApi.authenticateUser(testExpenseUser1).usingSite(testSite).usingResource(testFolderUser1)
.createFile(expense1, properties, VersioningState.MAJOR).assertThat().existsInRepo();
// Expense2 for testExpenseUser1 dated <today - 1 month>: Amount 50
expense2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
expense2.setName("ex-"+ expense2.getName());
properties = new HashMap<>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:finance:Expense");
properties.put(PropertyIds.NAME, expense2.getName());
properties.put("finance:No", uniqueRef+1);
properties.put("finance:Emp", testExpenseUser1.getUsername());
properties.put("finance:amount", 50);
properties.put("finance:CreatedAt", Date.from(dateLastMonth.toInstant(ZoneOffset.UTC)));
properties.put("finance:Location", "London");
cmisApi.authenticateUser(testExpenseUser1).usingSite(testSite).usingResource(testFolderUser1)
.createFile(expense2, properties, VersioningState.MAJOR).assertThat().existsInRepo();
// Expense1 for testExpenseAdmin dated <today - 1 month>: Amount 400
expense3 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
expense3.setName("ex-"+ expense3.getName());
properties = new HashMap<>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:finance:Expense");
properties.put(PropertyIds.NAME, expense3.getName());
properties.put("finance:No", uniqueRef+3);
properties.put("finance:Emp", testExpenseAdmin.getUsername());
properties.put("finance:amount", 400);
properties.put("finance:CreatedAt", Date.from(dateLastMonth.toInstant(ZoneOffset.UTC)));
properties.put("finance:Location", "London");
cmisApi.authenticateUser(testExpenseAdmin).usingSite(testSite).usingResource(testFolderAdmin)
.createFile(expense3, properties, VersioningState.MAJOR).assertThat().existsInRepo();
// Expense2 for testExpenseAdmin dated <today - 1 month>: Amount Not specified / Null
expense4 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
expense4.setName("ex-"+ expense4.getName());
properties = new HashMap<>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "D:finance:Expense");
properties.put(PropertyIds.NAME, expense4.getName());
properties.put("finance:No", uniqueRef+4);
properties.put("finance:Emp", testExpenseAdmin.getUsername());
properties.put("finance:CreatedAt", Date.from(lastMonthPlusOneDay.toInstant(ZoneOffset.UTC)));
properties.put("finance:Location", "Maidenhead");
cmisApi.authenticateUser(testExpenseAdmin).usingSite(testSite).usingResource(testFolderAdmin)
.createFile(expense4, properties, VersioningState.MAJOR).assertThat().existsInRepo();
// Wait for the content to be indexed
waitForIndexing(expense4.getName(), true);
}
/**
* Test that Virtual time series aggregation works for _day
* Format appears as yyyy
* Data shows results for [Current full day - 1 month] as default
* Values are correctly aggregated for _year dimension
* Order is correct
*/
@Test(priority = 1, groups = { TestGroup.INSIGHT_10 })
public void testBasicTimeSeriesAggrDay() throws Exception
{
// Select Data for TimeSeriesAggr: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(VIRTUAL_TIME_DIMENSION_DAY);
sqlRequest.setFormat("json");
RestResponse response =
restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Check that response includes the details for expense dated <today - 1 month>
int noOfDays = nowDate.getDayOfYear() - dateLastMonth.getDayOfYear();
response.assertThat().body("list.pagination.count", Matchers.equalTo(noOfDays + 1));
// Execute in solr format
sqlRequest.setFormat("solr");
response = restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("result-set.docs", Matchers.notNullValue());
// Check the results are in ascending order of date, starting with <today - 1 month>
restClient.onResponse().assertThat().body("result-set.docs[0].finance_CreatedAt_day", Matchers
.equalTo(dateLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
// last date available in the results set is today
restClient.onResponse().assertThat().body("result-set.docs[" + noOfDays + "].finance_CreatedAt_day", Matchers
.equalTo(nowDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
}
/**
* Test that Virtual time series aggregation works for _day
* Format appears as yyyy
* Data shows results for [Current full day - 1 month] as default
* Values are correctly aggregated for _year dimension
* Order is correct
*/
@Test(priority = 2, groups = { TestGroup.INSIGHT_10 })
public void testBasicTimeSeriesAggrDayWithHavingClause() throws Exception
{
// Select Data for TimeSeriesAggr: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(VIRTUAL_TIME_DIMENSION_DAY + HAVING_MIN_AMOUNT);
sqlRequest.setFormat("json");
RestResponse response =
restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Check Count
response.assertThat().body("list.pagination.count", Matchers.equalTo(2));
// Execute in solr format
sqlRequest.setFormat("solr");
response = restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("result-set.docs", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].finance_CreatedAt_day", Matchers
.equalTo(dateLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[0].ExpensesCount", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("result-set.docs[0].MinExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].MaxExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].TotalExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].AvgExpenses", Matchers.equalTo(50));
// Check that response includes the details for expense dated <today>
restClient.onResponse().assertThat().body("result-set.docs[1].finance_CreatedAt_day", Matchers
.equalTo(nowDate.minusMonths(0).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[1].ExpensesCount", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("result-set.docs[1].MinExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[1].MaxExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[1].TotalExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[1].AvgExpenses", Matchers.equalTo(100));
}
/**
* Test that Virtual time series aggregation works for _month
* Format appears as yyyy-mm
* Data shows results for [Current month - 24 months] as default
* Values are correctly aggregated for _month dimension
* Order is correct
*/
@Test(priority = 3, groups = { TestGroup.INSIGHT_10 })
public void testBasicTimeSeriesAggrMonth() throws Exception
{
// Select Data for TimeSeriesAggr: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(VIRTUAL_TIME_DIMENSION_MONTH + ORDER_BY_DESC);
sqlRequest.setFormat("json");
RestResponse response =
restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Check Count for Month Aggregation is 25: Current month minus 24 months
response.assertThat().body("list.pagination.count", Matchers.equalTo(25));
// Execute in solr format
sqlRequest.setFormat("solr");
response = restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("result-set.docs", Matchers.notNullValue());
// Check that response includes the details for expense dated <today>: Order By desc
restClient.onResponse().assertThat().body("result-set.docs[0].finance_CreatedAt_month", Matchers
.equalTo(nowDate.minusMonths(0).format(DateTimeFormatter.ofPattern("yyyy-MM"))));
restClient.onResponse().assertThat().body("result-set.docs[0].ExpensesCount", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("result-set.docs[0].MinExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[0].MaxExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[0].TotalExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[0].AvgExpenses", Matchers.equalTo(100));
// Check that response includes the details for expense dated <today - 1 month>
restClient.onResponse().assertThat().body("result-set.docs[1].finance_CreatedAt_month", Matchers
.equalTo(dateLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM"))));
restClient.onResponse().assertThat().body("result-set.docs[1].ExpensesCount", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("result-set.docs[1].MinExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[1].MaxExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[1].TotalExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[1].AvgExpenses", Matchers.equalTo(50));
}
/**
* Test that Virtual time series aggregation works for _year
* Format appears as yyyy
* Data shows results for [Current year - 5 years] as default
* Values are correctly aggregated for _year dimension
* Order is correct
*/
@Test(priority = 4, groups = { TestGroup.INSIGHT_10 })
public void testBasicTimeSeriesAggrYear() throws Exception
{
// Select Data for TimeSeriesAggr: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(VIRTUAL_TIME_DIMENSION_YEAR);
sqlRequest.setFormat("json");
RestResponse response =
restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Check Count for Year Aggregation is 25: Current year minus 5 years
response.assertThat().body("list.pagination.count", Matchers.equalTo(6));
// Execute in solr format
sqlRequest.setFormat("solr");
response = restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("result-set.docs", Matchers.notNullValue());
// Check that response includes the details for expense dated <today>: Order By desc
restClient.onResponse().assertThat().body("result-set.docs[0].finance_CreatedAt_year", Matchers
.equalTo(nowDate.format(DateTimeFormatter.ofPattern("yyyy"))));
restClient.onResponse().assertThat().body("result-set.docs[0].ExpensesCount", Matchers.equalTo(2));
restClient.onResponse().assertThat().body("result-set.docs[0].MinExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].MaxExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[0].TotalExpenses", Matchers.equalTo(150));
restClient.onResponse().assertThat().body("result-set.docs[0].AvgExpenses", Matchers.equalTo(75));
// Check that response includes the details for expense dated <today - 1 year>
restClient.onResponse().assertThat().body("result-set.docs[1].finance_CreatedAt_year", Matchers
.equalTo(nowDate.minusYears(1).format(DateTimeFormatter.ofPattern("yyyy"))));
restClient.onResponse().assertThat().body("result-set.docs[1].ExpensesCount", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].MinExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].MaxExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].TotalExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].AvgExpenses", Matchers.equalTo(0));
}
/**
* Test that Aggregation Values appear as 0 when not available for a time dimension
*/
@Test(priority = 5, groups = { TestGroup.INSIGHT_10 })
public void testNoValuesAggregateAsZero() throws Exception
{
// Select Data for TimeSeriesAggr: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(VIRTUAL_TIME_DIMENSION_DAY);
sqlRequest.setFormat("json");
RestResponse response =
restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Check Count
response.assertThat().body("list.pagination.count", Matchers.greaterThanOrEqualTo(28));
// Execute in solr format
sqlRequest.setFormat("solr");
response = restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("result-set.docs", Matchers.notNullValue());
// Check that response includes the details for expense dated <today - 1 month>
restClient.onResponse().assertThat().body("result-set.docs[0].finance_CreatedAt_day", Matchers
.equalTo(dateLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[0].ExpensesCount", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("result-set.docs[0].MinExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].MaxExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].TotalExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].AvgExpenses", Matchers.equalTo(50));
// Check that response includes expense dated <today - 1 month + 1 day>: Aggregations = 0, when ! specified
restClient.onResponse().assertThat().body("result-set.docs[1].finance_CreatedAt_day", Matchers
.equalTo(dateLastMonth.plusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[1].ExpensesCount", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].MinExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].MaxExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].TotalExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].AvgExpenses", Matchers.equalTo(0));
}
/**
* Test that Aggregation Values appear as 0 when null for any time dimension
*/
@Test(priority = 6, groups = { TestGroup.INSIGHT_10 })
public void testNullValuesAggregateAsZero() throws Exception
{
// Select Data for TimeSeriesAggr: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(VIRTUAL_TIME_DIMENSION_DAY);
sqlRequest.setFormat("json");
RestResponse response =
restClient.authenticateUser(testExpenseAdmin).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
// Check Count
response.assertThat().body("list.pagination.count", Matchers.greaterThanOrEqualTo(29));
// Execute in solr format
sqlRequest.setFormat("solr");
response = restClient.authenticateUser(testExpenseUser1).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("result-set.docs", Matchers.notNullValue());
// Check that response includes the details for expense dated <today - 1 month>
restClient.onResponse().assertThat().body("result-set.docs[0].finance_CreatedAt_day", Matchers
.equalTo(dateLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[0].ExpensesCount", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("result-set.docs[0].MinExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].MaxExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].TotalExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].AvgExpenses", Matchers.equalTo(50));
// Check that response includes expense dated <today - 1 month + 1 day>: Aggregations = 0, when ! specified
restClient.onResponse().assertThat().body("result-set.docs[1].finance_CreatedAt_day", Matchers
.equalTo(dateLastMonth.plusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[1].ExpensesCount", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].MinExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].MaxExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].TotalExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].AvgExpenses", Matchers.equalTo(0));
}
/**
* Test that aggregation produces correct results in-spite of changing null to zeroes
*/
@Test(priority = 7, groups = { TestGroup.INSIGHT_10 })
public void testAggregationsInclNulls() throws Exception
{
// This test only works when the four documents are split 3 last month/1 this month.
if (lastMonthPlusOneDay.getMonth().equals(nowDate.getMonth()))
{
Step.STEP("Skipping testAggregationsInclNulls as it fails near the end of months.");
return;
}
// Select Data for TimeSeriesAggr: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(VIRTUAL_TIME_DIMENSION_MONTH + HAVING_COUNT);
sqlRequest.setFormat("solr");
// User2 can see aggr results for All 4 Content
RestResponse response =
restClient.authenticateUser(testExpenseAdmin).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("result-set.docs", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].finance_CreatedAt_month", Matchers
.equalTo(dateLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM"))));
restClient.onResponse().assertThat().body("result-set.docs[0].ExpensesCount", Matchers.equalTo(3));
restClient.onResponse().assertThat().body("result-set.docs[0].MinExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].MaxExpenses", Matchers.equalTo(400));
restClient.onResponse().assertThat().body("result-set.docs[0].TotalExpenses", Matchers.equalTo(450));
restClient.onResponse().assertThat().body("result-set.docs[0].AvgExpenses", Matchers.equalTo(225));
restClient.onResponse().assertThat().body("result-set.docs[1].finance_CreatedAt_month", Matchers
.equalTo(nowDate.format(DateTimeFormatter.ofPattern("yyyy-MM"))));
restClient.onResponse().assertThat().body("result-set.docs[1].ExpensesCount", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("result-set.docs[1].MinExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[1].MaxExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[1].TotalExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[1].AvgExpenses", Matchers.equalTo(100));
}
/**
* Test that aggregation produces correct results for admin, aggregating data from different users
* Aggregated Values appear as 0 when actual values include a mix of null and non null values
* Results don't show 0 entries: when having clause filters them out
*/
@Bug(id = "Search-927", status=Bug.Status.OPENED)
@Test(priority = 8, groups = { TestGroup.INSIGHT_10 })
public void testAggregationsForOtherUser() throws Exception
{
String timeSeriesSqlDayAdmin = ""
+ "select "
+ "finance_CreatedAt_day, "
+ "count(*) as ExpensesCount, "
+ "sum(finance_amount) as TotalExpenses, avg(finance_amount) as AvgExpenses, "
+ "min(finance_amount) as MinExpenses, max(finance_amount) as MaxExpenses "
+ "from alfresco "
+ "where SITE = '" + testSite.getId() + "'"
+ "group by finance_CreatedAt_day";
// Select Data for TimeSeriesAggr: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(timeSeriesSqlDayAdmin + HAVING_COUNT);
sqlRequest.setFormat("solr");
// admin can see aggregation results for All 4 Content added to the Site
RestResponse response =
restClient.authenticateUser(dataUser.getAdminUser()).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("result-set.docs", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].finance_CreatedAt_day", Matchers
.equalTo(dateLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[0].ExpensesCount", Matchers.equalTo(2));
restClient.onResponse().assertThat().body("result-set.docs[0].MinExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[0].MaxExpenses", Matchers.equalTo(400));
restClient.onResponse().assertThat().body("result-set.docs[0].TotalExpenses", Matchers.equalTo(450));
restClient.onResponse().assertThat().body("result-set.docs[0].AvgExpenses", Matchers.equalTo(225));
restClient.onResponse().assertThat().body("result-set.docs[1].finance_CreatedAt_day", Matchers
.equalTo(lastMonthPlusOneDay.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[1].ExpensesCount", Matchers.equalTo(1));
// TODO: Search-927: NaN: Uncomment the following steps when Search-927 is resolved
// restClient.onResponse().assertThat().body("result-set.docs[1].MinExpenses", Matchers.equalTo(0));
// restClient.onResponse().assertThat().body("result-set.docs[1].MaxExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].TotalExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].AvgExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[2].finance_CreatedAt_day", Matchers
.equalTo(nowDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[2].ExpensesCount", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("result-set.docs[2].MinExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[2].MaxExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[2].TotalExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[2].AvgExpenses", Matchers.equalTo(100));
}
/**
* Test that aggregation produces correct results for admin, aggregating data from different users
* Aggregated Values appear as 0 when actual values include a mix of null and non nul values
* Results show 0 entries: when having clause does not filter them out
* Order by desc shows the same results as above query in a desc order
*/
@Bug(id = "Search-927", status=Bug.Status.OPENED)
@Test(priority = 9, groups = { TestGroup.INSIGHT_10 })
public void testAggregationsForOtherUserOrderByDesc() throws Exception
{
String timeSeriesSqlDayAdmin = ""
+ "select "
+ "finance_CreatedAt_day, "
+ "count(*) as ExpensesCount, "
+ "sum(finance_amount) as TotalExpenses, avg(finance_amount) as AvgExpenses, "
+ "min(finance_amount) as MinExpenses, max(finance_amount) as MaxExpenses "
+ "from alfresco "
+ "where SITE = '" + testSite.getId() + "'"
+ "group by finance_CreatedAt_day "
+ "having count(*) >= 1 "
+ "order by finance_CreatedAt_day desc";
// Select Data for TimeSeriesAggr: json format
SearchSqlRequest sqlRequest = new SearchSqlRequest();
sqlRequest.setSql(timeSeriesSqlDayAdmin);
sqlRequest.setFormat("solr");
// admin can see aggregation results for All 4 Content added to the Site
RestResponse response =
restClient.authenticateUser(dataUser.getAdminUser()).withSearchSqlAPI().searchSql(sqlRequest);
restClient.assertStatusCodeIs(HttpStatus.OK);
response.assertThat().body("result-set.docs", Matchers.notNullValue());
restClient.onResponse().assertThat().body("result-set.docs[0].finance_CreatedAt_day", Matchers
.equalTo(nowDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[0].ExpensesCount", Matchers.equalTo(1));
restClient.onResponse().assertThat().body("result-set.docs[0].MinExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[0].MaxExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[0].TotalExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[0].AvgExpenses", Matchers.equalTo(100));
restClient.onResponse().assertThat().body("result-set.docs[1].finance_CreatedAt_day", Matchers
.equalTo(lastMonthPlusOneDay.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[1].ExpensesCount", Matchers.equalTo(1));
// TODO: Search-927: NaN: Uncomment the following steps when Search-927 is resolved
// restClient.onResponse().assertThat().body("result-set.docs[1].MinExpenses", Matchers.equalTo(0));
// restClient.onResponse().assertThat().body("result-set.docs[1].MaxExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].TotalExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[1].AvgExpenses", Matchers.equalTo(0));
restClient.onResponse().assertThat().body("result-set.docs[2].finance_CreatedAt_day", Matchers
.equalTo(dateLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
restClient.onResponse().assertThat().body("result-set.docs[2].ExpensesCount", Matchers.equalTo(2));
restClient.onResponse().assertThat().body("result-set.docs[2].MinExpenses", Matchers.equalTo(50));
restClient.onResponse().assertThat().body("result-set.docs[2].MaxExpenses", Matchers.equalTo(400));
restClient.onResponse().assertThat().body("result-set.docs[2].TotalExpenses", Matchers.equalTo(450));
restClient.onResponse().assertThat().body("result-set.docs[2].AvgExpenses", Matchers.equalTo(225));
}
}

View File

@@ -5,7 +5,7 @@
* agreement is prohibited.
*/
package org.alfresco.service.search.e2e;
package org.alfresco.test.search.functional;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createRecordCategoryChildModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createRecordCategoryModel;
@@ -33,7 +33,7 @@ import org.testng.annotations.BeforeClass;
*
* @author Cristina Diaconu
*/
public class AbstractRMSearchServiceE2E extends AbstractSearchServiceE2E
public abstract class AbstractRMSearchServiceE2E extends AbstractSearchServiceE2E
{
protected static final String FILE_PLAN_ALIAS = "-filePlan-";
protected static final String RECORD_TYPE = "rma:record";

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.e2e;
package org.alfresco.test.search.functional;
/*
* Copyright 2019 Alfresco Software, Ltd. All rights reserved.

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import org.alfresco.dataprep.SiteService.Visibility;
import org.alfresco.rest.core.RestResponse;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import java.util.ArrayList;
import java.util.List;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import org.alfresco.rest.model.RestErrorModel;
import org.alfresco.rest.search.FacetInterval;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import java.util.ArrayList;
import java.util.List;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import org.alfresco.rest.search.SearchNodeModel;
import org.alfresco.rest.search.SearchResponse;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import java.util.Collections;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import java.util.ArrayList;
import java.util.List;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import org.alfresco.rest.model.RestRequestSpellcheckModel;
import org.alfresco.rest.search.RestRequestQueryModel;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;

View File

@@ -5,13 +5,13 @@
* agreement is prohibited.
*/
package org.alfresco.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.rest.search.SearchResponse;
import org.alfresco.service.search.e2e.AbstractSearchServiceE2E;
import org.alfresco.test.search.functional.AbstractSearchServiceE2E;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.data.DataContent;
import org.alfresco.utility.data.DataSite;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;

View File

@@ -16,7 +16,7 @@
* 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.service.search.e2e.searchservices;
package org.alfresco.test.search.functional.searchServices;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.cmis;
package org.alfresco.test.search.functional.searchServices.cmis;
import org.alfresco.cmis.CmisProperties;
import org.alfresco.cmis.CmisWrapper;
@@ -23,7 +23,7 @@ import org.testng.annotations.BeforeSuite;
@ContextConfiguration("classpath:alfresco-search-e2e-context.xml")
@Component
@Scope(value = "prototype")
public abstract class CmisTest extends AbstractTestNGSpringContextTests
public abstract class AbstractCmisTest extends AbstractTestNGSpringContextTests
{
private static Logger LOG = LogFactory.getLogger();

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.cmis;
package org.alfresco.test.search.functional.searchServices.cmis;
import org.alfresco.utility.Utility;
import org.alfresco.utility.data.provider.XMLDataConfig;
@@ -13,7 +13,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class SolrSearchByAspectTests extends CmisTest
public class SolrSearchByAspectTests extends AbstractCmisTest
{
/** Logger for the class. */
private static Logger LOGGER = LoggerFactory.getLogger(SolrSearchByAspectTests.class);

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.cmis;
package org.alfresco.test.search.functional.searchServices.cmis;
import org.alfresco.utility.Utility;
import org.alfresco.utility.data.provider.XMLDataConfig;
@@ -13,7 +13,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class SolrSearchByIdTests extends CmisTest
public class SolrSearchByIdTests extends AbstractCmisTest
{
/** Logger for the class. */
private static Logger LOGGER = LoggerFactory.getLogger(SolrSearchByIdTests.class);

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.cmis;
package org.alfresco.test.search.functional.searchServices.cmis;
import org.alfresco.utility.Utility;
import org.alfresco.utility.data.provider.XMLDataConfig;
@@ -12,7 +12,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class SolrSearchByPathTests extends CmisTest
public class SolrSearchByPathTests extends AbstractCmisTest
{
/** Logger for the class. */
private static Logger LOGGER = LoggerFactory.getLogger(SolrSearchByPathTests.class);

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.cmis;
package org.alfresco.test.search.functional.searchServices.cmis;
import org.alfresco.utility.Utility;
import org.alfresco.utility.data.provider.XMLDataConfig;
@@ -13,7 +13,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class SolrSearchByPropertyTests extends CmisTest
public class SolrSearchByPropertyTests extends AbstractCmisTest
{
/** Logger for the class. */
private static Logger LOGGER = LoggerFactory.getLogger(SolrSearchByPropertyTests.class);

View File

@@ -1,8 +1,7 @@
package org.alfresco.service.search.cmis;
package org.alfresco.test.search.functional.searchServices.cmis;
import org.alfresco.utility.Utility;
import org.alfresco.utility.data.provider.XMLDataConfig;
import org.alfresco.utility.data.provider.XMLTestData;
import org.alfresco.utility.data.provider.XMLTestDataProvider;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
@@ -15,7 +14,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class SolrSearchInFolderTests extends CmisTest
public class SolrSearchInFolderTests extends AbstractCmisTest
{
private UserModel testUser;
private SiteModel testSite;

View File

@@ -1,8 +1,7 @@
package org.alfresco.service.search.cmis;
package org.alfresco.test.search.functional.searchServices.cmis;
import org.alfresco.utility.Utility;
import org.alfresco.utility.data.provider.XMLDataConfig;
import org.alfresco.utility.data.provider.XMLTestData;
import org.alfresco.utility.data.provider.XMLTestDataProvider;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FileType;
@@ -15,7 +14,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class SolrSearchInTreeTests extends CmisTest
public class SolrSearchInTreeTests extends AbstractCmisTest
{
private UserModel testUser;
private SiteModel testSite;

View File

@@ -1,8 +1,8 @@
package org.alfresco.service.search.cmis;
package org.alfresco.test.search.functional.searchServices.cmis;
import org.testng.annotations.Test;
public class SorlSearchSimpleQueryTests extends CmisTest
public class SorlSearchSimpleQueryTests extends AbstractCmisTest
{
@Test
public void simpleQueryOnFolderDesc() throws Exception

View File

@@ -5,11 +5,11 @@
* agreement is prohibited.
*/
package org.alfresco.service.search.e2e.rm.searchServices;
package org.alfresco.test.search.functional.searchServices.rm;
import org.alfresco.rest.search.RestRequestQueryModel;
import org.alfresco.rest.search.SearchResponse;
import org.alfresco.service.search.e2e.AbstractRMSearchServiceE2E;
import org.alfresco.test.search.functional.AbstractRMSearchServiceE2E;
import org.alfresco.utility.model.TestGroup;
import org.springframework.http.HttpStatus;
import org.testng.Assert;

View File

@@ -12,7 +12,7 @@
* 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.service.search.e2e.searchservices.solr;
package org.alfresco.test.search.functional.searchServices.solr;
import java.net.URLEncoder;
@@ -20,7 +20,7 @@ import javax.json.JsonArrayBuilder;
import org.alfresco.rest.core.JsonBodyGenerator;
import org.alfresco.rest.model.RestTextResponse;
import org.alfresco.service.search.e2e.searchservices.AbstractSearchTest;
import org.alfresco.test.search.functional.searchServices.AbstractSearchTest;
import org.alfresco.utility.model.TestGroup;
import org.hamcrest.Matchers;
import org.springframework.http.HttpStatus;

View File

@@ -4,12 +4,12 @@
* pursuant to a written agreement and any use of this program without such an
* agreement is prohibited.
*/
package org.alfresco.service.search.e2e.searchservices.tracker;
package org.alfresco.test.search.functional.searchServices.tracker;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.search.e2e.AbstractSearchServiceE2E;
import org.alfresco.test.search.functional.AbstractSearchServiceE2E;
import org.alfresco.utility.data.DataContent;
import org.alfresco.utility.model.ContentModel;
import org.alfresco.utility.model.FileModel;

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.backup;
package org.alfresco.test.search.nonFunctional.backup;
import java.io.File;
import java.nio.file.Paths;
@@ -28,8 +28,8 @@ import com.jayway.restassured.RestAssured;
@Configuration
@ContextConfiguration("classpath:alfresco-search-e2e-context.xml")
public abstract class AbstractBackupTest extends AbstractTestNGSpringContextTests {
public abstract class AbstractBackupTest extends AbstractTestNGSpringContextTests
{
protected SiteModel testSite = new SiteModel("siteForBackupTesting");
protected FolderModel folder = new FolderModel("folderBackedUp");
protected FileModel file = new FileModel("fileBackedUp.txt", FileType.TEXT_PLAIN, "uber important file");

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.backup;
package org.alfresco.test.search.nonFunctional.backup;
import org.testng.annotations.Test;
@@ -9,18 +9,17 @@ import org.testng.annotations.Test;
* @author Paul Brodner
*
*/
public class SearchServiceOnBackupTests extends AbstractBackupTest {
public class SearchServiceOnBackupTests extends AbstractBackupTest
{
@Test
public void deleteBackupFolder() throws Exception {
/**
/*
* Site: siteForBackupTesting
* > documentLibrary
* | siteForBackupTesting
* |- fileBackedUp.txt
*/
cmisWrapper.authenticateUser(dataSite.getAdminUser())
.usingSite(testSite).setLastContentModel(folder);
cmisWrapper.deleteFolderTree().and().assertThat().doesNotExistInRepo();

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.backup;
package org.alfresco.test.search.nonFunctional.backup;
import org.testng.annotations.Test;
@@ -9,9 +9,8 @@ import org.testng.annotations.Test;
* @author Paul Brodner
*
*/
public class SearchServicePostBackupTests extends AbstractBackupTest {
public class SearchServicePostBackupTests extends AbstractBackupTest
{
@Test
public void testIFBackupDataExist() throws Exception {
cmisWrapper.authenticateUser(dataSite.getAdminUser())

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.backup;
package org.alfresco.test.search.nonFunctional.backup;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
@@ -14,8 +14,8 @@ import org.testng.annotations.Test;
* @author Paul Brodner
*
*/
public class SearchServicePreBackupTests extends AbstractBackupTest {
public class SearchServicePreBackupTests extends AbstractBackupTest
{
/**
* {"responseHeader":{"status":0,"QTime":1},"exception":"org.apache.solr.common.SolrException:org.apache.solr.common.SolrException:
* Directory does not exist:

View File

@@ -5,7 +5,7 @@
* agreement is prohibited.
*/
package org.alfresco.service.search.unit;
package org.alfresco.test.search.nonFunctional.sanity;
import java.sql.ResultSet;
import java.util.HashMap;
@@ -15,7 +15,7 @@ import org.alfresco.dataprep.SiteService.Visibility;
import org.alfresco.rest.core.RestResponse;
import org.alfresco.rest.search.SearchSqlJDBCRequest;
import org.alfresco.rest.search.SearchSqlRequest;
import org.alfresco.service.search.e2e.AbstractSearchServiceE2E;
import org.alfresco.test.search.functional.AbstractSearchServiceE2E;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.data.DataContent;
import org.alfresco.utility.data.DataSite;

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.upgrade;
package org.alfresco.test.search.nonFunctional.upgrade;
import org.alfresco.utility.LogFactory;
import org.alfresco.utility.Utility;

View File

@@ -1,4 +1,4 @@
package org.alfresco.service.search.upgrade;
package org.alfresco.test.search.nonFunctional.upgrade;
import org.alfresco.cmis.CmisWrapper;
import org.alfresco.utility.data.DataContent;

View File

@@ -9,34 +9,34 @@
<test name="SearchFaceted">
<classes>
<class name="org.alfresco.service.search.e2e.searchservices.FacetIntervalSearchTest"/>
<class name="org.alfresco.service.search.e2e.searchservices.FacetRangeSearchTest"/>
<class name="org.alfresco.service.search.e2e.searchservices.PivotFacetedSearchTest"/>
<class name="org.alfresco.service.search.e2e.searchservices.FacetedSearchTest"/>
<class name="org.alfresco.service.search.e2e.searchservices.FacetFieldsSearchTest"/>
<class name="org.alfresco.test.search.functional.searchServices.FacetIntervalSearchTest"/>
<class name="org.alfresco.test.search.functional.searchServices.FacetRangeSearchTest"/>
<class name="org.alfresco.test.search.functional.searchServices.PivotFacetedSearchTest"/>
<class name="org.alfresco.test.search.functional.searchServices.FacetedSearchTest"/>
<class name="org.alfresco.test.search.functional.searchServices.FacetFieldsSearchTest"/>
</classes>
</test>
<test name="SearchFeatures">
<classes>
<class name="org.alfresco.service.search.e2e.searchservices.FingerPrintTest"/>
<class name="org.alfresco.service.search.e2e.searchservices.SearchAPATHTest"/>
<class name="org.alfresco.service.search.e2e.searchservices.SearchHighLightTest"/>
<class name="org.alfresco.service.search.e2e.searchservices.SearchSpellCheckTest"/>
<class name="org.alfresco.service.search.e2e.searchservices.SearchTest"/>
<class name="org.alfresco.service.search.e2e.searchservices.StatsSearchTest"/>
<class name="org.alfresco.test.search.functional.searchServices.FingerPrintTest"/>
<class name="org.alfresco.test.search.functional.searchServices.SearchAPATHTest"/>
<class name="org.alfresco.test.search.functional.searchServices.SearchHighLightTest"/>
<class name="org.alfresco.test.search.functional.searchServices.SearchSpellCheckTest"/>
<class name="org.alfresco.test.search.functional.searchServices.SearchTest"/>
<class name="org.alfresco.test.search.functional.searchServices.StatsSearchTest"/>
</classes>
</test>
<test name="SearchPrivateAPIs">
<classes>
<class name="org.alfresco.service.search.e2e.searchservices.ShardInfoTest"/>
<class name="org.alfresco.test.search.functional.searchServices.ShardInfoTest"/>
</classes>
</test>
<test name="SolrAPIs">
<classes>
<class name="org.alfresco.service.search.e2e.searchservices.solr.SearchSolrAPITest" />
<class name="org.alfresco.test.search.functional.searchServices.solr.SearchSolrAPITest" />
</classes>
</test>
@@ -49,7 +49,7 @@
</run>
</groups>
<classes>
<class name="org.alfresco.service.search.unit.SetupTest" />
<class name="org.alfresco.test.search.nonFunctional.sanity.SetupTest" />
</classes>
</test>
@@ -63,8 +63,9 @@
</run>
</groups>
<packages>
<package name="org.alfresco.service.search.e2e.searchservices" />
<package name="org.alfresco.service.search.e2e.searchservices.tracker" />
<package name="org.alfresco.test.search.functional.searchServices" />
<package name="org.alfresco.test.search.functional.searchServices.solr" />
<package name="org.alfresco.test.search.functional.searchServices.tracker" />
</packages>
<classes>
</classes>

View File

@@ -1,17 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="org.alfresco" />
<import resource="classpath:dataprep-context.xml" />
<import resource="classpath*:alfresco-tester-context.xml" />
</beans>

View File

@@ -2,20 +2,14 @@
<suite name="CMISSearchSuite" verbose="6" preserve-order="true">
<listeners>
<listener class-name="org.alfresco.utility.report.HtmlReportListener"></listener>
<listeners>
<listener class-name="org.alfresco.utility.report.log.LogsListener"/>
<listener class-name="org.alfresco.utility.report.HtmlReportListener"/>
</listeners>
<test name="Search">
<classes>
<class name="org.alfresco.service.search.cmis.SolrSearchByAspectTests" />
<class name="org.alfresco.service.search.cmis.SolrSearchByIdTests" />
<class name="org.alfresco.service.search.cmis.SolrSearchByPathTests" />
<class name="org.alfresco.service.search.cmis.SolrSearchByPropertyTests" />
<class name="org.alfresco.service.search.cmis.SolrSearchInFolderTests" />
<class name="org.alfresco.service.search.cmis.SolrSearchInTreeTests" />
<class name="org.alfresco.service.search.cmis.SorlSearchSimpleQueryTests" />
</classes>
<packages>
<package name="org.alfresco.test.search.functional.searchServices.cmis" />
</packages>
</test>
</suite>

View File

@@ -4,7 +4,7 @@
<classes>
<!-- execute this before backup -->
<class
name="org.alfresco.service.search.backup.SearchServiceOnBackupTests" />
name="org.alfresco.test.search.nonFunctional.backup.SearchServiceOnBackupTests" />
</classes>
</test>
</suite>

View File

@@ -4,7 +4,7 @@
<classes>
<!-- execute this after backup -->
<class
name="org.alfresco.service.search.backup.SearchServicePostBackupTests" />
name="org.alfresco.test.search.nonFunctional.backup.SearchServicePostBackupTests" />
</classes>
</test>
</suite>

View File

@@ -6,7 +6,7 @@
<!-- this class depends on data produce and validated by search-pre-upgrade-suite.xml.
Execute it after upgrading product to new version -->
<class
name="org.alfresco.service.search.upgrade.SearchServiceUpgradeTests">
name="org.alfresco.test.search.nonFunctional.upgrade.SearchServiceUpgradeTests">
<methods>
<include name="checkDataIsSearchable" />
</methods>

View File

@@ -4,7 +4,7 @@
<classes>
<!-- execute this before backup -->
<class
name="org.alfresco.service.search.backup.SearchServicePreBackupTests" />
name="org.alfresco.test.search.nonFunctional.backup.SearchServicePreBackupTests" />
</classes>
</test>
</suite>

View File

@@ -4,7 +4,7 @@
<classes>
<!-- execute this before upgrade -->
<class
name="org.alfresco.service.search.upgrade.SearchServiceUpgradeTests">
name="org.alfresco.test.search.nonFunctional.upgrade.SearchServiceUpgradeTests">
<methods>
<include name="prepareData" />
<include name="checkDataIsSearchable" />