blob: e1b642f4c437fd92d547f0ceec1c16b5aeaf714a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.client.solrj.request.json;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import org.apache.solr.SolrTestCase;
import org.apache.solr.client.solrj.request.RequestWriter;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.MapWriter;
import org.junit.Test;
import static org.hamcrest.core.StringContains.containsString;
/**
* Unit tests for {@link JsonQueryRequest}
*/
public class JsonQueryRequestUnitTest extends SolrTestCase {
private static final boolean LEAVE_WHITESPACE = false;
@Test
public void testRejectsNullQueryString() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().setQuery((String)null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testRejectsNullQueryMap() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().setQuery((Map<String, Object>)null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testRejectsNullQueryMapWriter() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().setQuery((MapWriter)null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testWritesProvidedQueryStringToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().setQuery("text:solr");
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"query\":\"text:solr\""));
}
@Test
public void testWritesProvidedQueryMapToJsonCorrectly() {
final Map<String, Object> queryMap = new HashMap<>();
final Map<String, Object> paramsMap = new HashMap<>();
queryMap.put("lucene", paramsMap);
paramsMap.put("df", "text");
paramsMap.put("q", "*:*");
final JsonQueryRequest request = new JsonQueryRequest().setQuery(queryMap);
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"query\":{\"lucene\":{\"q\":\"*:*\",\"df\":\"text\"}}"));
}
@Test
public void testWritesProvidedQueryMapWriterToJsonCorrectly() {
final MapWriter queryWriter = new MapWriter() {
@Override
public void writeMap(EntryWriter ew) throws IOException {
ew.put("lucene", (MapWriter) ew1 -> {
ew1.put("q", "*:*");
ew1.put("df", "text");
});
}
};
final JsonQueryRequest request = new JsonQueryRequest().setQuery(queryWriter);
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"query\":{\"lucene\":{\"q\":\"*:*\",\"df\":\"text\"}}"));
}
@Test
public void testRejectsInvalidFacetName() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().withFacet(null, new HashMap<>());
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().withStatFacet(null, "avg(price)");
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testRejectsInvalidFacetMap() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().withFacet("anyFacetName", (Map<String, Object>)null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testRejectsNullFacetMapWriter() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().withFacet("anyFacetName", (MapWriter)null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testRejectsInvalidStatFacetString() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().withStatFacet("anyFacetName", (String)null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testWritesProvidedFacetMapToJsonCorrectly() {
final Map<String, Object> categoryFacetMap = new HashMap<>();
categoryFacetMap.put("type", "terms");
categoryFacetMap.put("field", "category");
final JsonQueryRequest request = new JsonQueryRequest().withFacet("top_categories", categoryFacetMap);
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"facet\":{\"top_categories\":{\"field\":\"category\",\"type\":\"terms\"}}"));
}
@Test
public void testWritesProvidedFacetMapWriterToJsonCorrectly() {
final MapWriter facetWriter = new MapWriter() {
@Override
public void writeMap(EntryWriter ew) throws IOException {
ew.put("type", "terms");
ew.put("field", "category");
}
};
final JsonQueryRequest request = new JsonQueryRequest().withFacet("top_categories", facetWriter);
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"facet\":{\"top_categories\":{\"type\":\"terms\",\"field\":\"category\"}}"));
}
@Test
public void testWritesProvidedStatFacetToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().withStatFacet("avg_price", "avg(price)");
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"facet\":{\"avg_price\":\"avg(price)\"}"));
}
@Test
public void testWritesMultipleFacetMapsToJsonCorrectly() {
final Map<String, Object> facetMap1 = new HashMap<>();
facetMap1.put("type", "terms");
facetMap1.put("field", "a");
final Map<String, Object> facetMap2 = new HashMap<>();
facetMap2.put("type", "terms");
facetMap2.put("field", "b");
final JsonQueryRequest request = new JsonQueryRequest();
request.withFacet("facet1", facetMap1);
request.withFacet("facet2", facetMap2);
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"facet\":{\"facet2\":{\"field\":\"b\",\"type\":\"terms\"},\"facet1\":{\"field\":\"a\",\"type\":\"terms\"}}"));
}
@Test
public void testRejectsInvalidLimit() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().setLimit(-1);
});
assertThat(thrown.getMessage(),containsString("must be non-negative"));
}
@Test
public void testWritesProvidedLimitToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().setLimit(5);
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"limit\":5"));
}
@Test
public void testRejectsInvalidOffset() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().setOffset(-1);
});
assertThat(thrown.getMessage(),containsString("must be non-negative"));
}
@Test
public void testWritesProvidedOffsetToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().setOffset(5);
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"offset\":5"));
}
@Test
public void testRejectsInvalidSort() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().setSort(null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testWritesProvidedSortToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().setSort("price asc");
final String requestBody = writeRequestToJson(request, LEAVE_WHITESPACE);
assertThat(requestBody, containsString("\"sort\":\"price asc"));
}
@Test
public void testRejectsInvalidFilterString() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().withFilter((String)null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testRejectsInvalidFilterMap() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().withFilter((Map<String,Object>)null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testWritesProvidedFilterToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().withFilter("text:solr");
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"filter\":[\"text:solr\"]"));
}
@Test
public void testWritesMultipleProvidedFiltersToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().withFilter("text:solr").withFilter("text:lucene");
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"filter\":[\"text:solr\",\"text:lucene\"]"));
}
@Test
public void testRejectsInvalidFieldsIterable() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().returnFields((Iterable<String>)null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testWritesProvidedFieldsToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().returnFields("price");
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"fields\":[\"price\"]"));
}
@Test
public void testWritesMultipleProvidedFieldsToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().returnFields("price", "name");
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"fields\":[\"price\",\"name\"]"));
}
@Test
public void testRejectsInvalidMiscParamName() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().withParam(null, "any-value");
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testRejectsInvalidMiscParamValue() {
Throwable thrown = expectThrows(IllegalArgumentException.class, () -> {
new JsonQueryRequest().withParam("any-name", null);
});
assertThat(thrown.getMessage(),containsString("must be non-null"));
}
@Test
public void testWritesMiscParamsToJsonCorrectly() {
final JsonQueryRequest request = new JsonQueryRequest().withParam("fq", "inStock:true");
final String requestBody = writeRequestToJson(request);
assertThat(requestBody, containsString("\"params\":{\"fq\":\"inStock:true\"}"));
}
private String writeRequestToJson(JsonQueryRequest request, boolean trimWhitespace) {
final RequestWriter.ContentWriter writer = request.getContentWriter(ClientUtils.TEXT_JSON);
final ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
writer.write(os);
final String rawJsonString = new String(os.toByteArray(), StandardCharsets.UTF_8);
// Trimming whitespace makes our assertions in these tests more stable (independent of JSON formatting) so we do
// it by default. But we leave the option open in case the JSON fields have spaces.
if (trimWhitespace) {
return rawJsonString.replaceAll("\n", "").replaceAll(" ","");
} else {
return rawJsonString;
}
} catch (IOException e) {
/* Unreachable in practice, since we're not doing any I/O here */
throw new RuntimeException(e);
}
}
private String writeRequestToJson(JsonQueryRequest request) {
return writeRequestToJson(request, true);
}
}