diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java
new file mode 100644
index 000000000..827e3c7ae
--- /dev/null
+++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java
@@ -0,0 +1,246 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+
+package edu.cornell.mannlib.vitro.webapp.controller.json;
+
+import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+import static javax.servlet.http.HttpServletResponse.SC_OK;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+import org.apache.log4j.Level;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassDaoStub;
+import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
+import stubs.javax.servlet.ServletConfigStub;
+import stubs.javax.servlet.ServletContextStub;
+import stubs.javax.servlet.http.HttpServletRequestStub;
+import stubs.javax.servlet.http.HttpServletResponseStub;
+import stubs.javax.servlet.http.HttpSessionStub;
+import stubs.org.apache.solr.client.solrj.SolrServerStub;
+import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
+import edu.cornell.mannlib.vitro.webapp.beans.VClass;
+import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
+
+/**
+ * TODO
+ */
+public class JsonServletTest extends AbstractTestClass {
+ private static final String GET_SOLR_INDIVIDUALS_BY_VCLASS = "getSolrIndividualsByVClass";
+
+ private static final String GET_VCLASSES_FOR_VCLASS_GROUP = "getVClassesForVClassGroup";
+
+ private static final String VCLASS_ID = "vclassId";
+
+ /**
+ * Test plan
+ *
+ *
+ *
+ * GetEntitiesByVClass, GetEntitiesByVClassContinuation
+ * from ents_edit.js
+ * ents_edit_head.jsp
+ * (there is an ents_edit.jsp, invoked from EntityEditController, which does not seem to invoke ents_edit.js)
+ *
+ * GetSolrIndividualsByVClass
+ * Mock out SolrServer (from SolrSetup) and IndividualDao
+ * invoked by BrowseDataGetter.java
+ * home page
+ * invoked by ClassGroupPageData.java
+ * >>>> Bring up "People" tab.
+ * invoked by BrowseWidget.java
+ *
+ * GetSolrIndividualsByVClasses
+ * Mock out SolrServer (from SolrSetup) and IndividualDao
+ * invoked by IndividualsForClassesDataGetter.java
+ * ProcessIndividualsForClasses
+ * extended in vivo by ProcessInternalClasses
+ * SelectDataGetterUtils.java
+ * SelectDataGetterUtils
+ * MenuManagementEdit.java
+ * MenuManagementController.java
+ * extended in vivo by InternalClassesDataGetter, also invoked by SelectDataGetterUtils
+ *
+ * GetDataForPage
+ * Mock out PageDao
+ *
+ */
+
+ private JsonServlet servlet;
+ private ServletConfigStub config;
+ private ServletContextStub ctx;
+ private HttpSessionStub session;
+ private HttpServletRequestStub req;
+ private HttpServletResponseStub resp;
+
+ private WebappDaoFactoryStub wadf;
+ private VClassDaoStub vcDao;
+
+ private SolrServerStub solr;
+
+ @Before
+ public void setup() throws ServletException {
+ ctx = new ServletContextStub();
+
+ session = new HttpSessionStub();
+ session.setServletContext(ctx);
+
+ config = new ServletConfigStub();
+ config.setServletContext(ctx);
+
+ servlet = new JsonServlet();
+ servlet.init(config);
+
+ req = new HttpServletRequestStub();
+ req.setMethod("GET");
+ req.setSession(session);
+
+ resp = new HttpServletResponseStub();
+
+ wadf = new WebappDaoFactoryStub();
+ req.setAttribute("webappDaoFactory", wadf);
+ ctx.setAttribute("webappDaoFactory", wadf);
+
+ vcDao = new VClassDaoStub();
+ wadf.setVClassDao(vcDao);
+
+ solr = new SolrServerStub();
+ ctx.setAttribute(SolrSetup.SOLR_SERVER, solr);
+ }
+
+ @Test
+ public void noRecognizedRequestParameters() throws ServletException,
+ IOException {
+ servlet.service(req, resp);
+ assertEquals("empty response", "", resp.getOutput());
+ assertEquals("status=ok", SC_OK, resp.getStatus());
+ }
+
+ @Test
+ public void vclassesNoClassgroup() throws ServletException, IOException {
+ req.addParameter(GET_VCLASSES_FOR_VCLASS_GROUP, "true");
+ servlet.service(req, resp);
+ assertEquals("empty response", "", resp.getOutput());
+ assertEquals("status=failure", SC_INTERNAL_SERVER_ERROR,
+ resp.getStatus());
+ }
+
+ /**
+ * TODO Modify VClassGroupCache so it can be stubbed out. JsonServlet asks
+ * VClassGroupCache for the current instance, and VClassGroupCache is a
+ * concrete class instead of an interface, so we can't replace the instance
+ * with one we like better. Furthermore, VClassGroupCache has a private
+ * constructor, so we can't change its behavior at all.
+ *
+ * Also test: success but no VClasses found, success with one VClass,
+ * success with multiple VClasses. In each case, confirm proper status,
+ * character encoding, and content type on the response.
+ */
+ @Ignore
+ @Test
+ public void vclassesClassgroupNotRecognized() throws ServletException,
+ IOException {
+ req.addParameter(GET_VCLASSES_FOR_VCLASS_GROUP, "true");
+ req.addParameter("classgroupUri", "http://bogusUri");
+ servlet.service(req, resp);
+ assertEquals("empty response", "", resp.getOutput());
+ assertEquals("status=failure", SC_INTERNAL_SERVER_ERROR,
+ resp.getStatus());
+ }
+
+ @Test
+ public void individualsByClassNoVClass() throws ServletException,
+ IOException {
+ setLoggerLevel(JsonServlet.class, Level.FATAL);
+ req.addParameter(GET_SOLR_INDIVIDUALS_BY_VCLASS, "true");
+ servlet.service(req, resp);
+ assertFailureWithErrorMessage("java.lang.Exception: "
+ + "parameter vclassId URI parameter expected ");
+ }
+
+ @Test
+ public void individualsByClassUnrecognizedVClass() throws ServletException,
+ IOException {
+ setLoggerLevel(JsonServlet.class, Level.FATAL);
+ String vclassId = "http://bogusVclass";
+ req.addParameter(GET_SOLR_INDIVIDUALS_BY_VCLASS, "true");
+ req.addParameter(VCLASS_ID, vclassId);
+
+ servlet.service(req, resp);
+ assertFailureWithErrorMessage("java.lang.Exception: " + "Class "
+ + vclassId + " not found");
+ }
+
+ /**
+ * TODO test successful responses. This will require figuring out how to
+ * stub SolrServer. It's an abstract class, so we just need to figure out
+ * what sort of NamedList is required as a response to a request.
+ */
+ @Test
+ public void individualsByClassNoIndividuals() throws ServletException,
+ IOException {
+ setLoggerLevel(JsonServlet.class, Level.FATAL);
+ String vclassId = "http://myVclass";
+ vcDao.setVClass(vclassId, new VClass(vclassId));
+ req.addParameter(GET_SOLR_INDIVIDUALS_BY_VCLASS, "true");
+ req.addParameter(VCLASS_ID, vclassId);
+
+ servlet.service(req, resp);
+ assertSuccessWithIndividuals(vclassId, 0);
+ }
+
+ // ----------------------------------------------------------------------
+ // Helper methods
+ // ----------------------------------------------------------------------
+
+ /**
+ * The response should be a JSONObject that contained this error-message,
+ * and the status should be set to INTERNAL_SERVER_ERROR.
+ */
+ private void assertFailureWithErrorMessage(String expected) {
+ try {
+ JSONObject result = new JSONObject(resp.getOutput());
+ assertEquals("errorMessage", expected,
+ getFieldValue(result, "errorMessage"));
+ assertEquals("status", SC_INTERNAL_SERVER_ERROR, resp.getStatus());
+ } catch (JSONException e) {
+ fail(e.toString());
+ }
+ }
+
+ private void assertSuccessWithIndividuals(String vclassId, int count) {
+ try {
+ JSONObject actual = new JSONObject(resp.getOutput());
+ assertEquals("errorMessage", "",
+ getFieldValue(actual, "errorMessage"));
+ assertEquals("count", count, getFieldValue(actual, "totalCount"));
+
+ JSONObject vclassObj = (JSONObject) getFieldValue(actual, "vclass");
+ assertEquals("vclass name", vclassId.split("://")[1], getFieldValue(vclassObj, "name"));
+ assertEquals("vclass uri", vclassId, getFieldValue(vclassObj, "URI"));
+
+ assertEquals("status", SC_OK, resp.getStatus());
+ } catch (JSONException e) {
+ fail(e.toString());
+ }
+ }
+
+ private Object getFieldValue(JSONObject json, String fieldName) {
+ try {
+ assertEquals("find " + fieldName, true, json.has(fieldName));
+ return json.get(fieldName);
+ } catch (JSONException e) {
+ fail(e.toString());
+ return -1;
+ }
+ }
+
+}
diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/VClassDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/VClassDaoStub.java
new file mode 100644
index 000000000..3c912c72e
--- /dev/null
+++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/VClassDaoStub.java
@@ -0,0 +1,264 @@
+package stubs.edu.cornell.mannlib.vitro.webapp.dao;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
+import edu.cornell.mannlib.vitro.webapp.beans.VClass;
+import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
+import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
+import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
+
+public class VClassDaoStub implements VClassDao {
+// ----------------------------------------------------------------------
+// Stub infrastructure
+// ----------------------------------------------------------------------
+
+ private final Map vclassesByUri = new HashMap();
+
+ public void setVClass(String uri, VClass vclass) {
+ vclassesByUri.put(uri, vclass);
+ }
+
+// ----------------------------------------------------------------------
+// Stub methods
+// ----------------------------------------------------------------------
+
+ @Override
+ public VClass getVClassByURI(String URI) {
+ return vclassesByUri.get(URI);
+ }
+
+// ----------------------------------------------------------------------
+// Un-implemented methods
+// ----------------------------------------------------------------------
+
+
+ @Override
+ public List getRootClasses() {
+ throw new RuntimeException(
+ "VClassDaoStub.getRootClasses() not implemented.");
+ }
+
+ @Override
+ public List getOntologyRootClasses(String ontologyURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.getOntologyRootClasses() not implemented.");
+ }
+
+ @Override
+ public List getAllVclasses() {
+ throw new RuntimeException(
+ "VClassDaoStub.getAllVclasses() not implemented.");
+ }
+
+ @Override
+ public List getDisjointWithClassURIs(String vclassURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.getDisjointWithClassURIs() not implemented.");
+ }
+
+ @Override
+ public void addSuperclass(VClass subclass, VClass superclass) {
+ throw new RuntimeException(
+ "VClassDaoStub.addSuperclass() not implemented.");
+ }
+
+ @Override
+ public void addSuperclass(String classURI, String superclassURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.addSuperclass() not implemented.");
+ }
+
+ @Override
+ public void removeSuperclass(VClass vclass, VClass superclass) {
+ throw new RuntimeException(
+ "VClassDaoStub.removeSuperclass() not implemented.");
+ }
+
+ @Override
+ public void removeSuperclass(String classURI, String superclassURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.removeSuperclass() not implemented.");
+ }
+
+ @Override
+ public void addSubclass(VClass vclass, VClass subclass) {
+ throw new RuntimeException(
+ "VClassDaoStub.addSubclass() not implemented.");
+ }
+
+ @Override
+ public void addSubclass(String classURI, String subclassURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.addSubclass() not implemented.");
+ }
+
+ @Override
+ public void removeSubclass(VClass vclass, VClass subclass) {
+ throw new RuntimeException(
+ "VClassDaoStub.removeSubclass() not implemented.");
+ }
+
+ @Override
+ public void removeSubclass(String classURI, String subclassURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.removeSubclass() not implemented.");
+ }
+
+ @Override
+ public void addDisjointWithClass(String classURI, String disjointCLassURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.addDisjointWithClass() not implemented.");
+ }
+
+ @Override
+ public void removeDisjointWithClass(String classURI, String disjointClassURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.removeDisjointWithClass() not implemented.");
+ }
+
+ @Override
+ public List getEquivalentClassURIs(String classURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.getEquivalentClassURIs() not implemented.");
+ }
+
+ @Override
+ public void addEquivalentClass(String classURI, String equivalentClassURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.addEquivalentClass() not implemented.");
+ }
+
+ @Override
+ public void removeEquivalentClass(String classURI, String equivalentClassURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.removeEquivalentClass() not implemented.");
+ }
+
+ @Override
+ public List getSubClassURIs(String classURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.getSubClassURIs() not implemented.");
+ }
+
+ @Override
+ public List getAllSubClassURIs(String classURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.getAllSubClassURIs() not implemented.");
+ }
+
+ @Override
+ public List getSuperClassURIs(String classURI, boolean direct) {
+ throw new RuntimeException(
+ "VClassDaoStub.getSuperClassURIs() not implemented.");
+ }
+
+ @Override
+ public List getAllSuperClassURIs(String classURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.getAllSuperClassURIs() not implemented.");
+ }
+
+ @Override
+ public void insertNewVClass(VClass cls) throws InsertException {
+ throw new RuntimeException(
+ "VClassDaoStub.insertNewVClass() not implemented.");
+ }
+
+ @Override
+ public void updateVClass(VClass cls) {
+ throw new RuntimeException(
+ "VClassDaoStub.updateVClass() not implemented.");
+ }
+
+ @Override
+ public void deleteVClass(String URI) {
+ throw new RuntimeException(
+ "VClassDaoStub.deleteVClass() not implemented.");
+ }
+
+ @Override
+ public void deleteVClass(VClass cls) {
+ throw new RuntimeException(
+ "VClassDaoStub.deleteVClass() not implemented.");
+ }
+
+ @Override
+ public List getVClassesForProperty(String propertyURI,
+ boolean domainSide) {
+ throw new RuntimeException(
+ "VClassDaoStub.getVClassesForProperty() not implemented.");
+ }
+
+ @Override
+ public List getVClassesForProperty(String vclassURI,
+ String propertyURI) {
+ throw new RuntimeException(
+ "VClassDaoStub.getVClassesForProperty() not implemented.");
+ }
+
+ @Override
+ public void addVClassesToGroup(VClassGroup group) {
+ throw new RuntimeException(
+ "VClassDaoStub.addVClassesToGroup() not implemented.");
+ }
+
+ @Override
+ public void insertNewClasses2Classes(Classes2Classes c2c) {
+ throw new RuntimeException(
+ "VClassDaoStub.insertNewClasses2Classes() not implemented.");
+ }
+
+ @Override
+ public void deleteClasses2Classes(Classes2Classes c2c) {
+ throw new RuntimeException(
+ "VClassDaoStub.deleteClasses2Classes() not implemented.");
+ }
+
+ @Override
+ public void addVClassesToGroup(VClassGroup group,
+ boolean includeUninstantiatedClasses) {
+ throw new RuntimeException(
+ "VClassDaoStub.addVClassesToGroup() not implemented.");
+ }
+
+ @Override
+ public void addVClassesToGroup(VClassGroup group,
+ boolean includeUninstantiatedClasses, boolean getIndividualCount) {
+ throw new RuntimeException(
+ "VClassDaoStub.addVClassesToGroup() not implemented.");
+ }
+
+ @Override
+ public void addVClassesToGroups(List groups) {
+ throw new RuntimeException(
+ "VClassDaoStub.addVClassesToGroups() not implemented.");
+ }
+
+ @Override
+ public boolean isSubClassOf(VClass vc1, VClass vc2) {
+ throw new RuntimeException(
+ "VClassDaoStub.isSubClassOf() not implemented.");
+ }
+
+ @Override
+ public boolean isSubClassOf(String vclassURI1, String vclassURI2) {
+ throw new RuntimeException(
+ "VClassDaoStub.isSubClassOf() not implemented.");
+ }
+
+ @Override
+ public VClass getTopConcept() {
+ throw new RuntimeException(
+ "VClassDaoStub.getTopConcept() not implemented.");
+ }
+
+ @Override
+ public VClass getBottomConcept() {
+ throw new RuntimeException(
+ "VClassDaoStub.getBottomConcept() not implemented.");
+ }
+
+}
diff --git a/webapp/test/stubs/javax/servlet/http/HttpServletResponseStub.java b/webapp/test/stubs/javax/servlet/http/HttpServletResponseStub.java
index df479c890..7a35e8d16 100644
--- a/webapp/test/stubs/javax/servlet/http/HttpServletResponseStub.java
+++ b/webapp/test/stubs/javax/servlet/http/HttpServletResponseStub.java
@@ -10,6 +10,8 @@ import java.io.StringWriter;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
@@ -29,6 +31,7 @@ public class HttpServletResponseStub implements HttpServletResponse {
private String errorMessage;
private Map headers = new HashMap();
private String contentType;
+ private String charset = "";
private ByteArrayOutputStream outputStream;
private StringWriter outputWriter;
@@ -129,9 +132,19 @@ public class HttpServletResponseStub implements HttpServletResponse {
return headers.containsKey(name);
}
+ /**
+ * Calling setContentType("this/type;charset=UTF-8") is the same as calling
+ * setContentType("this/type;charset=UTF-8"); setCharacterEncoding("UTF-8")
+ */
@Override
public void setContentType(String contentType) {
this.contentType = contentType;
+
+ Pattern p = Pattern.compile(";\\scharset=([^;]+)");
+ Matcher m = p.matcher(contentType);
+ if (m.find()) {
+ this.charset = m.group(1);
+ }
}
@Override
@@ -139,6 +152,16 @@ public class HttpServletResponseStub implements HttpServletResponse {
return contentType;
}
+ @Override
+ public void setCharacterEncoding(String charset) {
+ this.charset = charset;
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ return charset;
+ }
+
// ----------------------------------------------------------------------
// Un-implemented methods
// ----------------------------------------------------------------------
@@ -155,12 +178,6 @@ public class HttpServletResponseStub implements HttpServletResponse {
"HttpServletResponseStub.getBufferSize() not implemented.");
}
- @Override
- public String getCharacterEncoding() {
- throw new RuntimeException(
- "HttpServletResponseStub.getCharacterEncoding() not implemented.");
- }
-
@Override
public Locale getLocale() {
throw new RuntimeException(
@@ -191,12 +208,6 @@ public class HttpServletResponseStub implements HttpServletResponse {
"HttpServletResponseStub.setBufferSize() not implemented.");
}
- @Override
- public void setCharacterEncoding(String arg0) {
- throw new RuntimeException(
- "HttpServletResponseStub.setCharacterEncoding() not implemented.");
- }
-
@Override
public void setContentLength(int arg0) {
throw new RuntimeException(
diff --git a/webapp/test/stubs/org/apache/solr/client/solrj/SolrServerStub.java b/webapp/test/stubs/org/apache/solr/client/solrj/SolrServerStub.java
new file mode 100644
index 000000000..4fd1df48b
--- /dev/null
+++ b/webapp/test/stubs/org/apache/solr/client/solrj/SolrServerStub.java
@@ -0,0 +1,46 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+
+package stubs.org.apache.solr.client.solrj;
+
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.common.util.NamedList;
+
+/**
+ * TODO
+ */
+public class SolrServerStub extends SolrServer {
+ private static final Log log = LogFactory.getLog(SolrServerStub.class);
+
+ // ----------------------------------------------------------------------
+ // Stub infrastructure
+ // ----------------------------------------------------------------------
+
+ // ----------------------------------------------------------------------
+ // Stub methods
+ // ----------------------------------------------------------------------
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.solr.client.solrj.SolrServer#request(org.apache.solr.client
+ * .solrj.SolrRequest)
+ */
+ @Override
+ public NamedList