diff --git a/e2e-test/java/org/alfresco/rest/search/sql/SearchSQLWithQuotedIdentifiers.java b/e2e-test/java/org/alfresco/rest/search/sql/SearchSQLWithQuotedIdentifiers.java index bf88ea9b7..71f472efa 100644 --- a/e2e-test/java/org/alfresco/rest/search/sql/SearchSQLWithQuotedIdentifiers.java +++ b/e2e-test/java/org/alfresco/rest/search/sql/SearchSQLWithQuotedIdentifiers.java @@ -18,17 +18,17 @@ */ package org.alfresco.rest.search.sql; -import org.alfresco.rest.core.RestResponse; +import java.util.UUID; + +import org.alfresco.rest.RestTest; import org.alfresco.rest.search.AbstractSearchTest; import org.alfresco.rest.search.SearchSqlRequest; import org.alfresco.utility.constants.UserRole; import org.alfresco.utility.data.CustomObjectTypeProperties; import org.alfresco.utility.model.*; import org.alfresco.utility.report.Bug; -import org.apache.chemistry.opencmis.commons.PropertyIds; import org.hamcrest.Matchers; import org.springframework.http.HttpStatus; -import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -45,63 +45,181 @@ import org.testng.annotations.Test; */ public class SearchSQLWithQuotedIdentifiers extends AbstractSearchTest { - private final String songName = "Got a match?"; - private final String genre = "Fusion"; + + 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: * + * + * + * @see RestTest#checkServerHealth() * @throws Exception hopefully never, otherwise the test fails. */ @BeforeClass(alwaysRun = true) public void dataPreparation() 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"; + userModel = dataUser.createRandomTestUser(); dataContent.usingAdmin().deployContentModel("models/SEARCH-1063.xml"); - userModel = dataUser.createRandomTestUser(); - dataUser.addUserToSite(userModel, testSite, UserRole.SiteContributor); - final FolderModel testFolder = dataContent.usingSite(testSite).usingUser(userModel).createFolder(); + FolderModel testFolder = dataContent.usingSite(testSite).usingUser(userModel).createFolder(); - file = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "Some text content."); + 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); - final CustomObjectTypeProperties attributes = new CustomObjectTypeProperties(); - attributes.addProperty("1:name", songName); - attributes.addProperty("1:genre", genre); + 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)); - final ContentModel content = + 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(file, "D:1:song", attributes); + .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 testSearchUsingCustomAttributeStartingWithNumber() throws Exception + public void prefixIsComposedByOneNumber() throws Exception { - final SearchSqlRequest sqlRequest = new SearchSqlRequest(); - sqlRequest.setSql("select cm_name, `1_name`, `1_genre` from alfresco where TYPE='1:song'"); - sqlRequest.setFormat("solr"); - sqlRequest.setLocales(new String[] { "en-US" }); - sqlRequest.setIncludeMetadata(false); - - restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest); - restClient.assertStatusCodeIs(HttpStatus.OK); + executeQuery("select cm_name, `1_name`, `1_genre`, `1_co-producer` from alfresco where TYPE='1:song'"); 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)); } - @AfterClass(alwaysRun = true) - public void tearDown() throws Exception + @Test(groups={TestGroup.SEARCH, TestGroup.REST_API, TestGroup.ASS_1}) + @Bug(id = "SEARCH-1063") + public void prefixIsComposedByMultipleNumbers() throws Exception { - dataContent.usingSite(testSite).usingUser(dataUser.getAdminUser()).deleteSite(testSite); + executeQuery("select cm_name, `123_name`, `123_voice_type` from alfresco where TYPE='123:artist'"); + + 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 + { + executeQuery("select cm_name, `1_2_3_name` from alfresco where TYPE='1_2_3:bassist'"); + + 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 + { + executeQuery("select cm_name, `1-2-3_name` from alfresco where TYPE='1-2-3:drummer'"); + + 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 + { + executeQuery("select cm_name, `1-2_3_name` from alfresco where TYPE='1-2_3:saxophonist'"); + + 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)); + } + + /** + * Internal method for executing a SQL Query. + * + * TODO: maybe would be better to move this method (and similar methods) on a SQL supertype layer (e.g. AbstractSqlSearchTest) + * + * @param sql the SQL statement. + */ + private void executeQuery(String sql) throws Exception + { + SearchSqlRequest sqlRequest = new SearchSqlRequest(sql, "solr"); + + restClient.authenticateUser(userModel).withSearchSqlAPI().searchSql(sqlRequest); + restClient.assertStatusCodeIs(HttpStatus.OK); } } \ No newline at end of file diff --git a/e2e-test/resources/models/SEARCH-1063.xml b/e2e-test/resources/models/SEARCH-1063.xml index 97c4f0882..2e647e150 100755 --- a/e2e-test/resources/models/SEARCH-1063.xml +++ b/e2e-test/resources/models/SEARCH-1063.xml @@ -6,7 +6,24 @@ + + + + + @@ -16,7 +33,7 @@ cm:content - name + Name d:text false @@ -26,7 +43,105 @@ - genre + Genre + d:text + false + + true + BOTH + false + + + + Producer + d:text + false + + true + BOTH + false + + + + + + + + + Artist + cm:content + + + Name + d:text + false + + true + BOTH + false + + + + + + Voice Type + d:text + false + + true + BOTH + false + + + + + + + + + Bassist + cm:content + + + Name + d:text + false + + true + BOTH + false + + + + + + + + + Drummer + cm:content + + + Name + d:text + false + + true + BOTH + false + + + + + + + + + Sax + cm:content + + + Name d:text false