diff --git a/e2e-test/java/org/alfresco/rest/search/AbstractSearchTest.java b/e2e-test/java/org/alfresco/rest/search/AbstractSearchTest.java index 594105873..2bb43effc 100644 --- a/e2e-test/java/org/alfresco/rest/search/AbstractSearchTest.java +++ b/e2e-test/java/org/alfresco/rest/search/AbstractSearchTest.java @@ -111,4 +111,13 @@ public class AbstractSearchTest extends RestTest { return restClient.authenticateUser(dataUser.getAdminUser()).withSearchAPI().search(query); } + + protected SearchRequest carsQuery() + { + SearchRequest query = new SearchRequest(); + RestRequestQueryModel queryReq = new RestRequestQueryModel(); + queryReq.setQuery("cars"); + query.setQuery(queryReq); + return query; + } } diff --git a/e2e-test/java/org/alfresco/rest/search/FacetIntervalSearchTest.java b/e2e-test/java/org/alfresco/rest/search/FacetIntervalSearchTest.java index 5b66fbcb2..c32908fd0 100644 --- a/e2e-test/java/org/alfresco/rest/search/FacetIntervalSearchTest.java +++ b/e2e-test/java/org/alfresco/rest/search/FacetIntervalSearchTest.java @@ -95,21 +95,22 @@ public class FacetIntervalSearchTest extends AbstractSearchTest SearchResponse response = query(query); response.assertThat().entriesListIsNotEmpty(); - response.getContext().assertThat().field("facetIntervals").isNotEmpty(); - RestResultBucketsModel resultBucketsModel = response.getContext().getFacetIntervals().get(0); + response.getContext().assertThat().field("facets").isNotEmpty(); + RestGenericFacetResponseModel facetResponseModel = response.getContext().getFacets().get(0); - FacetFieldBucket bucket = resultBucketsModel.getBuckets().get(0); - Assert.assertEquals(resultBucketsModel.getBuckets().size(), 2); + RestGenericBucketModel bucket = facetResponseModel.getBuckets().get(0); + Assert.assertEquals(facetResponseModel.getBuckets().size(), 2); bucket.assertThat().field("label").is("aUser"); - bucket.assertThat().field("count").isGreaterThan(1); bucket.assertThat().field("filterQuery").is("creator:[a,user]"); + bucket.getMetrics().get(0).assertThat().field("type").is("count"); + bucket.getMetrics().get(0).assertThat().field("value").contains("{count="); - bucket = resultBucketsModel.getBuckets().get(1); + bucket = facetResponseModel.getBuckets().get(1); bucket.assertThat().field("label").is("theRest"); - bucket.assertThat().field("count").isLessThan(1); bucket.assertThat().field("filterQuery").is("creator:(user,z]"); - + bucket.getMetrics().get(0).assertThat().field("type").is("count"); + bucket.getMetrics().get(0).assertThat().field("value").is("{count=0}"); } @Test(groups = { TestGroup.REST_API, TestGroup.SEARCH, TestGroup.ASS_1 }) @@ -137,31 +138,25 @@ public class FacetIntervalSearchTest extends AbstractSearchTest SearchResponse response = query(query); response.assertThat().entriesListIsNotEmpty(); - response.getContext().assertThat().field("facetIntervals").isNotEmpty(); - RestResultBucketsModel resultBucketsModel = response.getContext().getFacetIntervals().get(0); + response.getContext().assertThat().field("facets").isNotEmpty(); + RestGenericFacetResponseModel facetResponseModel = response.getContext().getFacets().get(0); - resultBucketsModel.assertThat().field("label").is("modified"); - FacetFieldBucket bucket = resultBucketsModel.getBuckets().get(0); - Assert.assertEquals(resultBucketsModel.getBuckets().size(), 2); + facetResponseModel.assertThat().field("label").is("modified"); + RestGenericBucketModel bucket = facetResponseModel.getBuckets().get(0); + Assert.assertEquals(facetResponseModel.getBuckets().size(), 2); bucket.assertThat().field("label").is("From2016"); - bucket.assertThat().field("count").isGreaterThan(1); bucket.assertThat().field("filterQuery").is("cm:modified:[2016,now]"); + bucket.getMetrics().get(0).assertThat().field("type").is("count"); + bucket.getMetrics().get(0).assertThat().field("value").contains("{count="); - bucket = resultBucketsModel.getBuckets().get(1); + + bucket = facetResponseModel.getBuckets().get(1); bucket.assertThat().field("label").is("Before2016"); - bucket.assertThat().field("count").isLessThan(1); bucket.assertThat().field("filterQuery").is("cm:modified:[*,2016)"); - + bucket.getMetrics().get(0).assertThat().field("type").is("count"); + bucket.getMetrics().get(0).assertThat().field("value").is("{count=0}"); } - private SearchRequest carsQuery() - { - SearchRequest query = new SearchRequest(); - RestRequestQueryModel queryReq = new RestRequestQueryModel(); - queryReq.setQuery("cars"); - query.setQuery(queryReq); - return query; - } } diff --git a/e2e-test/java/org/alfresco/rest/search/FacetedSearchTest.java b/e2e-test/java/org/alfresco/rest/search/FacetedSearchTest.java index 46af12765..ae8a7fcbd 100644 --- a/e2e-test/java/org/alfresco/rest/search/FacetedSearchTest.java +++ b/e2e-test/java/org/alfresco/rest/search/FacetedSearchTest.java @@ -24,6 +24,8 @@ import java.util.List; import org.alfresco.utility.model.TestGroup; import org.alfresco.utility.testrail.ExecutionType; import org.alfresco.utility.testrail.annotation.TestRail; +import org.testng.Assert; +import org.testng.TestException; import org.testng.annotations.Test; /** @@ -67,15 +69,18 @@ public class FacetedSearchTest extends AbstractSearchTest * "facetQueries": [ * { * "count": 61, - * "label": "small" + * "label": "small", + * "filterQuery": "content.size:[o TO 102400]" * }, * { * "count": 0, - * "label": "large" + * "label": "large", + * "filterQuery": "content.size:[o TO 102400]" * }, * { * "count": 0, - * "label": "medium" + * "label": "medium", + * "filterQuery": "content.size:[o TO 102400]" * } * ] * } @@ -88,19 +93,19 @@ public class FacetedSearchTest extends AbstractSearchTest RestRequestQueryModel queryReq = new RestRequestQueryModel(); queryReq.setQuery("cars"); query.setQuery(queryReq); + List facets = new ArrayList(); facets.add(new FacetQuery("content.size:[0 TO 102400]", "small")); facets.add(new FacetQuery("content.size:[102400 TO 1048576]", "medium")); facets.add(new FacetQuery("content.size:[1048576 TO 16777216]", "large")); query.setFacetQueries(facets); - RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel(); - List list = new ArrayList(); - list.add(new FacetFieldQuery("'content.size'")); + List list = new ArrayList<>(); + list.add(new RestRequestFacetFieldModel("'content.size'")); facetFields.setFacets(list); - query.setFacetFields(facetFields); + query.setIncludeRequest(true); SearchResponse response = query(query); response.assertThat().entriesListIsNotEmpty(); @@ -114,6 +119,101 @@ public class FacetedSearchTest extends AbstractSearchTest response.getContext().getFacetQueries().get(2).assertThat().field("label").contains("medium") .and().field("count").isLessThan(1) .and().field("filterQuery").is("content.size:[102400 TO 1048576]"); + //We don't expect to see the FacetFields if group is being used. + Assert.assertNull(response.getContext().getFacetsFields()); + Assert.assertNull(response.getContext().getFacets()); + } + @Test(groups = { TestGroup.REST_API, TestGroup.SEARCH , TestGroup.ASS_1}) + @TestRail(section = {TestGroup.REST_API, TestGroup.SEARCH ,TestGroup.ASS_1 }, executionType = ExecutionType.REGRESSION, + description = "Checks facet queries for the Search api") + /** + * * Perform a group by faceting, below test groups the facet by group name foo. + * { + * "query": { + * "query": "cars", + * "language": "afts" + * }, + * "facetQueries": [ + * {"query": "content.size:[o TO 102400]", "label": "small","group":"foo"}, + * {"query": "content.size:[102400 TO 1048576]", "label": "medium","group":"foo"}, + * {"query": "content.size:[1048576 TO 16777216]", "label": "large","group":"foo"} + * ], + * "facetFields": {"facets": [{"field": "'content.size'"}]} + * } + * + * Expected response + * {"list": { + * "entries": [... All the results], + * "pagination": { + * "maxItems": 100, + * "hasMoreItems": false, + * "totalItems": 61, + * "count": 61, + * "skipCount": 0 + * }, + * "context": { + * "consistency": {"lastTxId": 512}, + * //Added below as part of SEARCH-374 + * "facetsFields": [ + * { "label": "foo", + * "buckets": [ + * { "label": "small", "count": 61, "filterQuery": "content.size:[o TO 102400]"}, + * { "label": "large", "count": 0, "filterQuery": "content.size:[1048576 TO 16777216]"}, + * { "label": "medium", "count": 61, "filterQuery": "content.size:[102400 TO 1048576]"} + * ] + * } + * } + * }} + * + * + * @throws Exception + */ + public void searchFacetGroup() throws Exception + { + SearchRequest query = new SearchRequest(); + RestRequestQueryModel queryReq = new RestRequestQueryModel(); + queryReq.setQuery("cars"); + query.setQuery(queryReq); + + List facets = new ArrayList(); + facets.add(new FacetQuery("content.size:[0 TO 102400]", "small", "foo")); + facets.add(new FacetQuery("content.size:[102400 TO 1048576]", "medium","foo")); + facets.add(new FacetQuery("content.size:[1048576 TO 16777216]", "large","foo")); + query.setFacetQueries(facets); + + RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel(); + List list = new ArrayList<>(); + list.add(new RestRequestFacetFieldModel("'content.size'")); + facetFields.setFacets(list); + + query.setFacetFields(facetFields); + SearchResponse response = query(query); + //We don't expect to see the FacetQueries if group is being used. + Assert.assertTrue(response.getContext().getFacetQueries() == null); + //Validate the facet field structure is correct. + Assert.assertFalse(response.getContext().getFacetsFields().isEmpty()); + Assert.assertEquals(response.getContext().getFacetsFields().get(0).getLabel(), "foo"); + FacetFieldBucket bucket = response.getContext().getFacetsFields().get(0).getBuckets().get(0); + bucket.assertThat().field("label").isNotEmpty(); + bucket.assertThat().field("count").isNotEmpty(); + bucket.assertThat().field("filterQuery").isNotEmpty(); + response.getContext().getFacetsFields().get(0).getBuckets().forEach(action -> { + switch (action.getLabel()) + { + case "small": + Assert.assertEquals(action.getFilterQuery(), "content.size:[0 TO 102400]"); + break; + case "medium": + Assert.assertEquals(action.getFilterQuery(), "content.size:[102400 TO 1048576]"); + break; + case "large": + Assert.assertEquals(action.getFilterQuery(), "content.size:[1048576 TO 16777216]"); + break; + + default: + throw new TestException("Unexpected value returned"); + } + }); } diff --git a/e2e-test/java/org/alfresco/rest/search/PivotFacetedSearchTest.java b/e2e-test/java/org/alfresco/rest/search/PivotFacetedSearchTest.java new file mode 100644 index 000000000..87f3f6e64 --- /dev/null +++ b/e2e-test/java/org/alfresco/rest/search/PivotFacetedSearchTest.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2017 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 . + */ +package org.alfresco.rest.search; + +import org.alfresco.rest.model.RestErrorModel; +import org.alfresco.utility.model.TestGroup; +import org.alfresco.utility.testrail.ExecutionType; +import org.alfresco.utility.testrail.annotation.TestRail; +import org.springframework.http.HttpStatus; +import org.testng.Assert; +import org.testng.TestException; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + * Faceted search test. + * @author Gethin James + * + */ +public class PivotFacetedSearchTest extends AbstractSearchTest +{ + + @Test(groups = { TestGroup.REST_API, TestGroup.SEARCH }) + @TestRail(section = {TestGroup.REST_API, TestGroup.SEARCH }, executionType = ExecutionType.REGRESSION, + description = "Checks errors with pivot using Search api") + public void searchWithPivotingErrors() throws Exception + { + SearchRequest query = carsQuery(); + + RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel(); + List list = new ArrayList<>(); + list.add(new RestRequestFacetFieldModel("'creator'")); + facetFields.setFacets(list); + query.setFacetFields(facetFields); + query.setIncludeRequest(false); + List pivotModelList = new ArrayList<>(); + RestRequestPivotModel pivots = new RestRequestPivotModel(); + pivotModelList.add(pivots); + query.setPivots(pivotModelList); + + SearchResponse response = query(query); + restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST).assertLastError() + .containsSummary(String.format(RestErrorModel.MANDATORY_PARAM, "pivot key")); + + + pivots.setKey("none_like_this"); + response = query(query); + restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST).assertLastError() + .containsSummary("Pivot parameter none_like_this is does not reference a facet Field"); + } + + @Test(groups = { TestGroup.REST_API, TestGroup.SEARCH }) + @TestRail(section = {TestGroup.REST_API, TestGroup.SEARCH }, executionType = ExecutionType.REGRESSION, + description = "Checks with pivot using Search api") + public void searchWithPivoting() throws Exception + { + SearchRequest query = carsQuery(); + + RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel(); + List list = new ArrayList<>(); + list.add(new RestRequestFacetFieldModel("creator")); + facetFields.setFacets(list); + query.setFacetFields(facetFields); + query.setIncludeRequest(false); + + SearchResponse response = query(query); + response.getContext().assertThat().field("facetsFields").isNotNull(); + + List pivotModelList = new ArrayList<>(); + RestRequestPivotModel pivots = new RestRequestPivotModel(); + pivots.setKey("creator"); + pivotModelList.add(pivots); + query.setPivots(pivotModelList); + response = query(query); + + //Pivot key has matched facet field so there is no longer a facet fields response + assertPivotResponse(response, "creator", null); + } + + private void assertPivotResponse(SearchResponse response, String field, String alabel) throws Exception + { + String label = alabel!=null?alabel:field; + response.getContext().assertThat().field("facetsFields").isNull(); + response.getContext().assertThat().field("facets").isNotEmpty(); + RestGenericFacetResponseModel facetResponseModel = response.getContext().getFacets().get(0); + facetResponseModel.assertThat().field("type").is("pivot"); + facetResponseModel.assertThat().field("label").is(label); + RestGenericBucketModel bucket = facetResponseModel.getBuckets().get(0); + bucket.assertThat().field("label").isNotEmpty(); + bucket.assertThat().field("filterQuery").is(field+":"+bucket.getLabel()); + Assert.assertEquals("count", bucket.getMetrics().get(0).getType()); + Assert.assertTrue(bucket.getMetrics().get(0).getValue().toString().contains("{count=")); + } + + @Test(groups = { TestGroup.REST_API, TestGroup.SEARCH }) + @TestRail(section = {TestGroup.REST_API, TestGroup.SEARCH }, executionType = ExecutionType.REGRESSION, + description = "Checks with pivot using Search api and a label as a key") + public void searchWithPivotingUsingLabel() throws Exception + { + SearchRequest query = carsQuery(); + RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel(); + List list = new ArrayList<>(); + RestRequestFacetFieldModel creatorFacetFieldModel = new RestRequestFacetFieldModel("creator"); + creatorFacetFieldModel.setLabel("create"); + list.add(creatorFacetFieldModel); + RestRequestFacetFieldModel restRequestFacetFieldModel = new RestRequestFacetFieldModel("modifier"); + restRequestFacetFieldModel.setLabel("aLabel"); + list.add(restRequestFacetFieldModel); + facetFields.setFacets(list); + query.setFacetFields(facetFields); + query.setIncludeRequest(false); + RestRequestPivotModel pivots = new RestRequestPivotModel(); + pivots.setKey("create"); + RestRequestPivotModel pivotmod = new RestRequestPivotModel(); + pivotmod.setKey("aLabel"); + + List pivotModelList = new ArrayList<>(); + pivotModelList.add(pivots); + pivotModelList.add(pivotmod); + query.setPivots(pivotModelList); + SearchResponse response = query(query); + assertPivotResponse(response, "creator", "create"); + + //Now check the nesting + RestGenericFacetResponseModel facetResponseModel = response.getContext().getFacets().get(0); + RestGenericFacetResponseModel nestedFacet = facetResponseModel.getBuckets().get(0).getFacets().get(0); + RestGenericBucketModel bucket = nestedFacet.getBuckets().get(0); + nestedFacet.assertThat().field("label").isNotEmpty(); + nestedFacet.assertThat().field("label").is("aLabel"); + bucket.assertThat().field("filterQuery").is("modifier:"+bucket.getLabel()); + Assert.assertEquals("count", bucket.getMetrics().get(0).getType()); + Assert.assertTrue(bucket.getMetrics().get(0).getValue().toString().contains("{count=")); + } +} diff --git a/e2e-test/java/org/alfresco/rest/search/SearchAPATHTest.java b/e2e-test/java/org/alfresco/rest/search/SearchAPATHTest.java index 3ed0bbb04..030494997 100644 --- a/e2e-test/java/org/alfresco/rest/search/SearchAPATHTest.java +++ b/e2e-test/java/org/alfresco/rest/search/SearchAPATHTest.java @@ -87,8 +87,8 @@ public class SearchAPATHTest extends AbstractSearchTest searchQuery.setQuery(queryReq); RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel(); - List list = new ArrayList(); - list.add(new FacetFieldQuery("APATH","0")); + List list = new ArrayList<>(); + list.add(new RestRequestFacetFieldModel("APATH","0")); facetFields.setFacets(list); searchQuery.setFacetFields(facetFields); SearchResponse response = query(searchQuery); @@ -107,8 +107,8 @@ public class SearchAPATHTest extends AbstractSearchTest searchQuery.setQuery(queryReq); RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel(); - List list = new ArrayList(); - list.add(new FacetFieldQuery("APATH","1")); + List list = new ArrayList<>(); + list.add(new RestRequestFacetFieldModel("APATH","1")); facetFields.setFacets(list); searchQuery.setFacetFields(facetFields); SearchResponse response = query(searchQuery); @@ -125,8 +125,8 @@ public class SearchAPATHTest extends AbstractSearchTest searchQuery.setQuery(queryReq); RestRequestFacetFieldsModel facetFields = new RestRequestFacetFieldsModel(); - List list = new ArrayList(); - list.add(new FacetFieldQuery("APATH","1/")); + List list = new ArrayList<>(); + list.add(new RestRequestFacetFieldModel("APATH","1/")); facetFields.setFacets(list); searchQuery.setFacetFields(facetFields); @@ -134,7 +134,7 @@ public class SearchAPATHTest extends AbstractSearchTest RestResultBucketsModel fresponse = response.getContext().getFacetsFields().get(0); String path = fresponse.getBuckets().get(0).getLabel().replace("1/", "2/"); list.remove(0); - list.add(new FacetFieldQuery("APATH", path)); + list.add(new RestRequestFacetFieldModel("APATH", path)); facetFields.setFacets(list); searchQuery.setFacetFields(facetFields); @@ -155,7 +155,7 @@ public class SearchAPATHTest extends AbstractSearchTest searchQuery.setQuery(queryReq); facetFields = new RestRequestFacetFieldsModel(); list.remove(0); - list.add(new FacetFieldQuery("APATH",path.replace("2/", "3/"))); + list.add(new RestRequestFacetFieldModel("APATH",path.replace("2/", "3/"))); facetFields.setFacets(list); searchQuery.setFacetFields(facetFields); response = query(searchQuery); diff --git a/e2e-test/java/org/alfresco/rest/search/SearchTest.java b/e2e-test/java/org/alfresco/rest/search/SearchTest.java index 5b989e6c6..58f5a4199 100644 --- a/e2e-test/java/org/alfresco/rest/search/SearchTest.java +++ b/e2e-test/java/org/alfresco/rest/search/SearchTest.java @@ -19,6 +19,8 @@ package org.alfresco.rest.search; import org.alfresco.utility.model.TestGroup; +import org.alfresco.utility.testrail.ExecutionType; +import org.alfresco.utility.testrail.annotation.TestRail; import org.springframework.http.HttpStatus; import org.testng.annotations.Test; @@ -30,7 +32,7 @@ import org.testng.annotations.Test; public class SearchTest extends AbstractSearchTest { @Test(groups={TestGroup.SEARCH, TestGroup.REST_API}) - public void searchCreatedData() throws Exception + public void searchOnIndexedData() throws Exception { SearchResponse nodes = query("fox"); restClient.assertStatusCodeIs(HttpStatus.OK); @@ -58,4 +60,22 @@ public class SearchTest extends AbstractSearchTest restClient.assertStatusCodeIs(HttpStatus.OK); nodes.assertThat().entriesListIsEmpty(); } + + @Test(groups = { TestGroup.REST_API, TestGroup.SEARCH, TestGroup.ASS_1 }) + @TestRail(section = {TestGroup.REST_API, TestGroup.SEARCH, TestGroup.ASS_1 }, executionType = ExecutionType.REGRESSION, + description = "Checks its possible to include the original request in the response") + public void searchWithRequest() throws Exception + { + SearchRequest query = new SearchRequest(); + RestRequestQueryModel queryReq = new RestRequestQueryModel(); + queryReq.setQuery("fox"); + query.setQuery(queryReq); + query.setIncludeRequest(true); + + SearchResponse response = query(query); + restClient.assertStatusCodeIs(HttpStatus.OK); + + response.getContext().assertThat().field("request").isNotEmpty(); + } + }