package lux.solr;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XdmNode;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryRequestBase;
import org.apache.solr.response.SolrQueryResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ResponseWriterTest extends BaseSolrTest {
private LuxResponseWriter responseWriter;
private StringWriter writer;
@Before
public void init() {
responseWriter = new LuxResponseWriter();
writer = new StringWriter();
}
@After
public void exit() {
//core.close();
}
@Test
public void testEmptyResponse () throws Exception {
// no error and no results; blank result? should be throw an exception?
assertEquals ("", writeResponse((String) null));
}
// return a single string with the default content type (text/html)
@Test
public void testStringResponse () throws Exception {
String result = writeResponse ((String) null, "xs:string", "Hello, World");
assertEquals ("Hello, World", result);
assertEquals ("text/html; charset=UTF-8", responseWriter.getContentType(makeRequest(), new SolrQueryResponse()));
}
// return a single string with the text/xml content type
@Test
public void testXmlStringResponse () throws Exception {
String result = writeResponse ("text/xml", "xs:string", "Hello, World");
assertEquals ("<results>Hello, World</results>", result);
}
// return a single xml result with the text/xml content type
@Test
public void testXmlResponse () throws Exception {
Processor processor = new Processor(false);
XdmNode doc = processor.newDocumentBuilder().build(new StreamSource (new StringReader ("<test>Hello, World</test>")));
String result = writeResponse ("text/xml", "element", doc);
assertEquals ("<test>Hello, World</test>\n", result);
// and with xsl
writer = new StringWriter();
result = writeResponse (makeRequest("lux.contentType", "text/xml", "lux.xml-xsl-stylesheet", "transform.xsl"), "element", doc);
assertEquals ("<?xml-stylesheet type='text/xsl' href='transform.xsl' ?>\n<test>Hello, World</test>\n", result);
}
// return multiple xml results
@Test
public void testMultipleXmlResults() throws Exception {
XdmNode doc = buildDocument("<test>Hello, World</test>");
String result = writeResponse ("text/xml", "element", doc, "element", doc);
assertEquals ("<results><test>Hello, World</test>\n" +
"<test>Hello, World</test>\n" +
"</results>", result);
}
// if an ordinary error was caught, we report it using a SolrException so that
// Solr can produce a 400 response
@Test
public void testErrorResponse() throws Exception {
SolrQueryRequest request = makeRequest();
SolrQueryResponse response = new SolrQueryResponse();
response.add("xpath-error", "error #1");
response.add("xpath-error", "error #2");
try {
responseWriter.write(writer, request, response);
fail ("no exception thrown");
} catch (SolrException e) {
assertEquals ("error #1\nerror #2\n", e.getMessage());
}
}
// if an internal, fatal error of some kind occurred, we generate an html response
@Test
public void testExceptionResponse() throws Exception {
SolrQueryRequest request = makeRequest();
SolrQueryResponse response = new SolrQueryResponse();
NamedList<String> errors = new NamedList<String> ();
// This seems to be how Solr reports errors internally?
errors.add("msg", "An error occurred");
response.add("error", errors);
response.setException(new Exception (""));
responseWriter.write(writer, request, response);
assertEquals ("<html><head><title>Error</title></head><body><h1>Error</h1><code>An error occurred</code></body></html>", writer.getBuffer().toString());
}
private String writeResponse (SolrQueryRequest request, Object ... params) throws IOException {
SolrQueryResponse response = new SolrQueryResponse();
NamedList<Object> results = new NamedList<Object> ();
for (int i = 0; i < params.length; i += 2) {
results.add((String) params[i], params[i+1]);
}
response.add("xpath-results", results);
responseWriter.write(writer, request, response);
return writer.getBuffer().toString();
}
private String writeResponse (String contentType, Object ... params) throws IOException {
SolrQueryRequest request;
if (contentType != null) {
request = makeRequest ("lux.contentType", contentType);
} else {
request = makeRequest ();
}
return writeResponse (request, params);
}
private SolrQueryRequest makeRequest(String ... params) {
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < params.length; i+=2) {
map.put(params[i], params[i+1]);
}
SolrParams solrParams = new MapSolrParams(map);
return new SimpleSolrQuery(solrCore, solrParams);
}
private XdmNode buildDocument (String xml) throws SaxonApiException {
Processor processor = new Processor(false);
return processor.newDocumentBuilder().build(new StreamSource (new StringReader (xml)));
}
private static class SimpleSolrQuery extends SolrQueryRequestBase {
SimpleSolrQuery (SolrCore core, SolrParams params) {
super (core, params);
}
}
}