+ * No data - roots is null -- NONSENSICAL + * No data - roots is empty + * + * name + * no name + * + * displayRank + * no displayRank + * + * no child classes + * child classes + * + * child class has name + * child class has no name + * + * child class has shortDef + * child class has no shortDef + * + * G1 no name, displayRank, no classes + * G2 name, no displayRank, classes + * G2C1 no name, no shortDef + * G2C2 name, shortdef + * + * Try once with no data + * Try with all data + *+ */ + +public class ListClassGroupsControllerTest extends ListControllerTestBase { + private static final String LINK_FORMAT_GROUP = "%s"; + private static final String LINK_FORMAT_CLASS = "%s"; + private static final String GROUP1 = "http://ont1/group1"; + private static final String GROUP2 = "http://ont1/group2"; + private static final String CLASS1 = "http://ont1/class1"; + private static final String CLASS2 = "http://ont1/class2"; + private static final String CLASS2_NAME = "The Second Class"; + private static final String CLASS2_SHORT_DEF = "A Marvelous Class"; + private static final int GROUP1_RANK = 5; + private static final String GROUP2_NAME = "The Second Group"; + + private static final JsonNode JSON_EMPTY_RESPONSE = arrayOf(); + + private static final JsonNode JSON_FULL_RESPONSE = arrayOf( + groupListNode(LINK_FORMAT_GROUP, GROUP1, "(unnamed group)", + "" + GROUP1_RANK), + groupListNode(LINK_FORMAT_GROUP, GROUP2, GROUP2_NAME, "", + groupMemberNode("", "", "", ""), + groupMemberNode(LINK_FORMAT_CLASS, CLASS2, CLASS2_NAME, + CLASS2_SHORT_DEF))); + + private ListClassGroupsController controller; + private HttpServletRequestStub req; + private ModelAccessFactoryStub modelsFactory; + private WebappDaoFactoryStub wadf; + private VClassGroupDaoStub vcgDao; + + @Before + public void setup() { + controller = new ListClassGroupsController(); + + req = new HttpServletRequestStub(); + + vcgDao = new VClassGroupDaoStub(); + + wadf = new WebappDaoFactoryStub(); + wadf.setVClassGroupDao(vcgDao); + + modelsFactory = new ModelAccessFactoryStub(); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL); + } + + // ---------------------------------------------------------------------- + // The tests + // ---------------------------------------------------------------------- + + @Test + public void noData() throws Exception { + assertMatchingJson(controller, req, JSON_EMPTY_RESPONSE); + } + + @Test + public void basicJsonTest() throws Exception { + populate(); + + /* + * The controller attempts to handle the case of a class with no name, + * but instead it returns invalid json. + */ + String rawResponse = getJsonFromController(controller, req); + String kluged = rawResponse.replace("[\"\"", "[ {\"name\": \"\""); + assertKlugedJson(JSON_FULL_RESPONSE, kluged); + + // assertMatchingJson(controller, req, JSON_FULL_RESPONSE); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void populate() { + vcgDao.setGroups(vClassGroup(GROUP1, null, GROUP1_RANK), + vClassGroup(GROUP2, GROUP2_NAME, -1, vclass(CLASS1, null, null), + vclass(CLASS2, CLASS2_NAME, CLASS2_SHORT_DEF))); + + } + + private VClassGroup vClassGroup(String uri, String name, int rank, + VClass... vClasses) { + VClassGroup group = new VClassGroup(uri, name, rank); + for (VClass vClass : vClasses) { + group.add(vClass); + } + return group; + } + + private VClass vclass(String uri, String name, String shortDef) { + VClass vc = new VClass(uri); + vc.setName(name); + vc.setShortDef(shortDef); + return vc; + } + +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListControllerTestBase.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListControllerTestBase.java new file mode 100644 index 000000000..b17571957 --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListControllerTestBase.java @@ -0,0 +1,185 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +import javax.servlet.http.HttpServletRequest; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; + +/** + * Some useful methods for assembling JSON structures that will match the test + * results. + * + * Also, some methods for running the tests, with and without kluging the + * results. + */ +public class ListControllerTestBase extends AbstractTestClass { + protected static ObjectMapper mapper = new ObjectMapper(); + + /** + * Create a JSON array from nodes. + */ + protected static ArrayNode arrayOf(JsonNode... nodes) { + ArrayNode array = mapper.createArrayNode(); + for (JsonNode node : nodes) { + array.add(node); + } + return array; + } + + /** + * Show a DataProperty or an ObjectProperty in a list. + */ + protected static ObjectNode propertyListNode(String path, String uri, + String name, String internalName, String domainVClass, + String rangeVClass, String group) { + String nameString = String.format("%s", path, + urlEncode(uri), name); + ObjectNode propNode = mapper.createObjectNode().put("name", nameString); + propNode.putObject("data").put("internalName", internalName) + .put("domainVClass", domainVClass) + .put("rangeVClass", rangeVClass).put("group", group); + return propNode; + } + + /** + * Show a DataProperty or an ObjectProperty in a hierarchy. + */ + protected static ObjectNode propertyHierarchyNode(String path, String uri, + String name, String internalName, String domainVClass, + String rangeVClass, String group, ObjectNode... children) { + ObjectNode propNode = propertyListNode(path, uri, name, internalName, + domainVClass, rangeVClass, group); + propNode.set("children", arrayOf(children)); + return propNode; + } + + /** + * Show a VClass in a list. + */ + protected static ObjectNode degenerateVclassListNode(String name, + String shortDef, String classGroup, String ontology) { + ObjectNode vcNode = mapper.createObjectNode().put("name", name); + vcNode.putObject("data").put("shortDef", shortDef) + .put("classGroup", classGroup).put("ontology", ontology); + return vcNode; + } + + /** + * Show a VClass in a list. + */ + protected static ObjectNode vclassListNode(String path, String uri, + String name, String shortDef, String classGroup, String ontology) { + String nameString = String.format("%s", path, + urlEncode(uri), name); + ObjectNode vcNode = mapper.createObjectNode().put("name", nameString); + vcNode.putObject("data").put("shortDef", shortDef) + .put("classGroup", classGroup).put("ontology", ontology); + return vcNode; + } + + /** + * Show a VClass in a hierarchy. + */ + protected static ObjectNode vclassHierarchyNode(String path, String uri, + String name, String shortDef, String classGroup, String ontology, + ObjectNode... children) { + ObjectNode vcNode = vclassListNode(path, uri, name, shortDef, + classGroup, ontology); + vcNode.set("children", arrayOf(children)); + return vcNode; + } + + /** + * Show a ClassGroup or PropertyGroup in a list. + */ + protected static ObjectNode groupListNode(String linkFormat, String uri, + String name, String displayRank, ObjectNode... children) { + String nameString = String.format(linkFormat, urlEncode(uri), name); + ObjectNode gNode = mapper.createObjectNode().put("name", nameString); + gNode.putObject("data").put("displayRank", displayRank); + gNode.set("children", arrayOf(children)); + return gNode; + } + + /** + * Show a Class or Property as part of a Group. + */ + protected static ObjectNode groupMemberNode(String linkFormat, String uri, + String name, String shortDef, ObjectNode... children) { + String nameString = String.format(linkFormat, urlEncode(uri), name); + ObjectNode memberNode = mapper.createObjectNode().put("name", + nameString); + memberNode.putObject("data").put("shortDef", shortDef); + memberNode.set("children", arrayOf(children)); + return memberNode; + } + + /** + * Based on the fact that each of these controllers returns a + * TemplateResponseValues object with a "jsonTree" in the body map. + * + * That jsonTree would be an standard JSON array, except that it is missing + * the enclosing brackets, so we need to add them before comparing to the + * expected value. + * + * Add the brackets, read the strings, and compare. + */ + protected static void assertMatchingJson(FreemarkerHttpServlet controller, + HttpServletRequest req, JsonNode expected) throws Exception { + String jsonString = getJsonFromController(controller, req); + JsonNode actual = mapper.readTree("[" + jsonString + "]"); + assertEquals(expected, actual); + } + + /** + * Some of the controllers have edge cases that produce invalid JSON, even + * when wrapped in enclosing brackets. For those cases, call this method, + * massage the result to form valid JSON, and call assertKlugedJson(). + */ + protected static String getJsonFromController( + FreemarkerHttpServlet controller, HttpServletRequest req) + throws Exception { + ResponseValues rv = controller.processRequest(new VitroRequest(req)); + assertTrue(rv instanceof TemplateResponseValues); + TemplateResponseValues trv = (TemplateResponseValues) rv; + + Object o = trv.getMap().get("jsonTree"); + assertTrue(o instanceof String); + String jsonString = (String) o; + return jsonString; + } + + /** + * If it was necessary to manipulate the response from the controller, this + * is how to test it. + */ + protected void assertKlugedJson(JsonNode expected, + String klugedActualString) throws Exception { + JsonNode actual = mapper.readTree("[" + klugedActualString + "]"); + assertEquals(expected, actual); + } + + private static String urlEncode(String uri) { + try { + return URLEncoder.encode(uri, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return uri; + } + } +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListDatatypePropertiesControllerTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListDatatypePropertiesControllerTest.java new file mode 100644 index 000000000..30bd1ccde --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListDatatypePropertiesControllerTest.java @@ -0,0 +1,255 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption.LANGUAGE_NEUTRAL; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.PolicyOption.POLICY_NEUTRAL; + +import java.text.Collator; + +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; + +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; +import edu.cornell.mannlib.vitro.webapp.beans.Datatype; +import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.DatatypeDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; +import stubs.javax.servlet.http.HttpServletRequestStub; + +/** + * Not a well-formed set of unit tests. But it's a pretty good exercise of the + * different possibilities in the output stage. + * + * Test plan: + * + *
+ * No data - roots is null -- NONSENSICAL + * No data - roots is empty + * + * Ontology is not specified + * Ontology is specified and matches + * Ontology is specified and does not match + * DataProperty does not match Ontology, but has child properties that do. + * + * Name from picklistName + * Name from getName + * Name from getUri + * Name no URL? -- NONSENSICAL + * + * InternalName from picklistName + * InternalName missing. + * + * Domain class no class URI + * Domain class no class for URI + * Domain class get picklistName from Language Aware DAO + * Domain class use picklistName from Language Neutral DAO + * + * Range no range URI + * Range no datatype for URI + * Range datatype has no name + * Range has a name + * + * Group no group URI + * Group no group for URI + * Group no name + * Group has a name + * + * DP1 Ont1, no name, no picklistName, no domainClass, no RangeClass, no GroupURI + * DP2 Ont2, name, no picklistName, no domain class for URI, no range datatype for URI, no group for GroupURI + * DP3 Ont1, picklistname, domainclass no picklistname, range datatype with no name, group has no name + * DP4 Ont1, picklistname, domainclass w/picklistname, range datatype with name, group with name + * + * Try once with no data + * Try with all data and no ontology specified + * Try with all data and Ont1, Ont2, Ont3 + *+ */ +public class ListDatatypePropertiesControllerTest + extends ListControllerTestBase { + private static final String PATH = "datapropEdit"; + private static final String ONT1 = "http://ont1/"; + private static final String ONT2 = "http://ont2/"; + private static final String ONT3 = "http://ont3/"; + private static final String DP1 = ONT1 + "first"; + private static final String DP2 = ONT2 + "second"; + private static final String DP3 = ONT1 + "third"; + private static final String DP4 = ONT1 + "fourth"; + private static final String DP2_NAME = "TWO"; + private static final String DP3_NAME = "THREE"; + private static final String DP4_NAME = "FOUR"; + private static final String DP3_PICK_NAME = "The third one"; + private static final String DP4_PICK_NAME = "The fourth one"; + private static final String DOMAIN_NONE = "http://domain/noSuchDomain"; + private static final String DOMAIN_NO_NAME = "http://domain/domainWithNoName"; + private static final String DOMAIN_W_NAME = "http://domain/namedDomain"; + private static final String NAME_DOMAIN = "An excellent domain"; + private static final String RANGE_NONE = "http://domain/noSuchRange"; + private static final String RANGE_NO_NAME = "http://domain/rangeWithNoName"; + private static final String RANGE_W_NAME = "http://domain/namedRange"; + private static final String NAME_RANGE = "Home on the range"; + private static final String GROUP_NONE = "http://domain/noSuchGroup"; + private static final String GROUP_NO_NAME = "http://domain/groupWithNoName"; + private static final String GROUP_W_NAME = "http://domain/namedGroup"; + private static final String NAME_GROUP = "The Groupsters"; + + private static final ArrayNode NO_DATA_RESPONSE = arrayOf( + mapper.createObjectNode().put("name", "No data properties found")); + + private static final JsonNode RESPONSE_UNFILTERED = arrayOf( + propertyListNode(PATH, DP1, "first", "first", "", "", + "unspecified"), + propertyListNode(PATH, DP2, "second", "second", "", RANGE_NONE, + "unknown group"), + propertyListNode(PATH, DP4, DP4_PICK_NAME, DP4_PICK_NAME, + NAME_DOMAIN, NAME_RANGE, NAME_GROUP), + propertyListNode(PATH, DP3, DP3_PICK_NAME, DP3_PICK_NAME, + "domainWithNoName", "", "")); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT1 = arrayOf( + propertyListNode(PATH, DP1, "first", "first", "", "", + "unspecified"), + propertyListNode(PATH, DP4, DP4_PICK_NAME, DP4_PICK_NAME, + NAME_DOMAIN, NAME_RANGE, NAME_GROUP), + propertyListNode(PATH, DP3, DP3_PICK_NAME, DP3_PICK_NAME, + "domainWithNoName", "", "")); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT2 = arrayOf( + propertyListNode(PATH, DP2, "second", "second", "", RANGE_NONE, + "unknown group")); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT3 = arrayOf( + mapper.createObjectNode().put("name", "No data properties found")); + + private ListDatatypePropertiesController controller; + private HttpServletRequestStub req; + private ModelAccessFactoryStub modelsFactory; + private WebappDaoFactoryStub wadf; + private DataPropertyDaoStub dpdao; + private DatatypeDaoStub dtdao; + private VClassDaoStub vcdao; + private PropertyGroupDaoStub pgdao; + + @Before + public void setup() { + controller = new ListDatatypePropertiesController(); + + req = new HttpServletRequestStub(); + new VitroRequest(req).setCollator(Collator.getInstance()); + + dpdao = new DataPropertyDaoStub(); + dtdao = new DatatypeDaoStub(); + vcdao = new VClassDaoStub(); + pgdao = new PropertyGroupDaoStub(); + + wadf = new WebappDaoFactoryStub(); + wadf.setDataPropertyDao(dpdao); + wadf.setDatatypeDao(dtdao); + wadf.setVClassDao(vcdao); + wadf.setPropertyGroupDao(pgdao); + + modelsFactory = new ModelAccessFactoryStub(); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL); + modelsFactory.get(req).setWebappDaoFactory(wadf, LANGUAGE_NEUTRAL, + POLICY_NEUTRAL); + } + + // ---------------------------------------------------------------------- + // The tests + // ---------------------------------------------------------------------- + + @Test + public void noDataProperties() throws Exception { + assertMatchingJson(controller, req, NO_DATA_RESPONSE); + } + + @Test + public void unfiltered() throws Exception { + populate(); + assertMatchingJson(controller, req, RESPONSE_UNFILTERED); + } + + @Test + public void filteredByOnt1() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT1); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT1); + } + + @Test + public void filteredByOnt2() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT2); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT2); + } + + @Test + public void filteredByOnt3() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT3); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT3); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void populate() { + vcdao.setVClass(vclass(DOMAIN_NO_NAME, null)); + vcdao.setVClass(vclass(DOMAIN_W_NAME, NAME_DOMAIN)); + dtdao.addDatatype(datatype(RANGE_NO_NAME, null)); + dtdao.addDatatype(datatype(RANGE_W_NAME, NAME_RANGE)); + pgdao.addPropertyGroup(propertyGroup(GROUP_NO_NAME, null)); + pgdao.addPropertyGroup(propertyGroup(GROUP_W_NAME, NAME_GROUP)); + dpdao.addDataProperty(dataProperty(DP1, null, null, null, null, null)); + dpdao.addDataProperty(dataProperty(DP2, DP2_NAME, null, DOMAIN_NONE, + RANGE_NONE, GROUP_NONE)); + dpdao.addDataProperty(dataProperty(DP3, DP3_NAME, DP3_PICK_NAME, + DOMAIN_NO_NAME, RANGE_NO_NAME, GROUP_NO_NAME)); + dpdao.addDataProperty(dataProperty(DP4, DP4_NAME, DP4_PICK_NAME, + DOMAIN_W_NAME, RANGE_W_NAME, GROUP_W_NAME)); + } + + private DataProperty dataProperty(String uri, String name, + String pickListName, String domainClassUri, String rangeDatatypeUri, + String groupUri) { + DataProperty dp = new DataProperty(); + dp.setURI(uri); + dp.setName(name); + dp.setPickListName(pickListName); + dp.setDomainClassURI(domainClassUri); + dp.setRangeDatatypeURI(rangeDatatypeUri); + dp.setGroupURI(groupUri); + return dp; + } + + private Datatype datatype(String uri, String name) { + Datatype dt = new Datatype(); + dt.setUri(uri); + dt.setName(name); + return dt; + } + + private VClass vclass(String uri, String pickListName) { + VClass vc = new VClass(); + vc.setURI(uri); + vc.setPickListName(pickListName); + return vc; + } + + private PropertyGroup propertyGroup(String uri, String name) { + PropertyGroup pg = new PropertyGroup(); + pg.setURI(uri); + pg.setName(name); + return pg; + } +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyGroupsControllerTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyGroupsControllerTest.java new file mode 100644 index 000000000..6e6bb3310 --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyGroupsControllerTest.java @@ -0,0 +1,170 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.PolicyOption.POLICY_NEUTRAL; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.Property; +import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; +import stubs.javax.servlet.http.HttpServletRequestStub; + +/** + * Not a well-formed set of unit tests. But it's a pretty good exercise of the + * different possibilities in the output stage. + * + * Test plan: + * + *
+ * No data - roots is null -- NONSENSICAL + * No data - roots is empty + * + * name + * no name - (unnamed group) + * + * display rank + * no display rank + * + * no child properties + * child property is data property + * child properti is object property + * + * child data property has no name + * child data property has name + * child object property has no domainPublic + * child object property has domainPublic + * + * G1 no name, displayRank, no classes + * G2 name, no displayRank, classes + * G2DP1 no name, no shortDef + * G2DP2 name, shortdef + * G2OP1 no domainPublic, no shortDef + * G2OP2 domainPublic, shortdef + * + * Try once with no data + * Try with all data + *+ */ + +public class ListPropertyGroupsControllerTest extends ListControllerTestBase { + private static final String LINK_FORMAT_GROUP = "%s"; + private static final String LINK_FORMAT_DATA_PROPERTY = "%s"; + private static final String LINK_FORMAT_OBJECT_PROPERTY = "%s"; + private static final String GROUP1 = "http://ont1/group1"; + private static final String GROUP2 = "http://ont1/group2"; + private static final String DP1 = "http://ont1/dp1"; + private static final String DP2 = "http://ont1/dp2"; + private static final String OP1 = "http://ont1/op1"; + private static final String OP2 = "http://ont1/op2"; + private static final String DP2_NAME = "A second data property"; + private static final String OP2_DOMAIN_PUBLIC = "The second domain"; + private static final int GROUP1_RANK = 5; + private static final String GROUP2_NAME = "The Second Group"; + + private static final JsonNode JSON_EMPTY_RESPONSE = arrayOf(); + + private static final JsonNode JSON_FULL_RESPONSE = arrayOf( + groupListNode(LINK_FORMAT_GROUP, GROUP2, GROUP2_NAME, "", + groupMemberNode(LINK_FORMAT_DATA_PROPERTY, DP1, null, ""), + groupMemberNode(LINK_FORMAT_DATA_PROPERTY, DP2, DP2_NAME, + ""), + groupMemberNode(LINK_FORMAT_OBJECT_PROPERTY, OP1, null, ""), + groupMemberNode(LINK_FORMAT_OBJECT_PROPERTY, OP2, + OP2_DOMAIN_PUBLIC, "")), + groupListNode(LINK_FORMAT_GROUP, GROUP1, "(unnamed group)", + "" + GROUP1_RANK)); + + private ListPropertyGroupsController controller; + private HttpServletRequestStub req; + private ModelAccessFactoryStub modelsFactory; + private WebappDaoFactoryStub wadf; + private PropertyGroupDaoStub pgdao; + + @Before + public void setup() { + controller = new ListPropertyGroupsController(); + + req = new HttpServletRequestStub(); + + pgdao = new PropertyGroupDaoStub(); + + wadf = new WebappDaoFactoryStub(); + wadf.setPropertyGroupDao(pgdao); + + modelsFactory = new ModelAccessFactoryStub(); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL); + } + + // ---------------------------------------------------------------------- + // The tests + // ---------------------------------------------------------------------- + + @Test + public void noData() throws Exception { + assertMatchingJson(controller, req, JSON_EMPTY_RESPONSE); + } + + @Test + public void basicJsonTest() throws Exception { + populate(); + + // /* + // * The controller attempts to handle the case of a class with no name, + // * but instead it returns invalid json. + // */ + // String rawResponse = getJsonFromController(controller, req); + // String kluged = rawResponse.replace("[\"\"", "[ {\"name\": \"\""); + // assertKlugedJson(JSON_FULL_RESPONSE, kluged); + + assertMatchingJson(controller, req, JSON_FULL_RESPONSE); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void populate() { + pgdao.addPropertyGroup(propertyGroup(GROUP1, "", GROUP1_RANK)); + pgdao.addPropertyGroup( + propertyGroup(GROUP2, GROUP2_NAME, -1, dataProperty(DP1, null), + dataProperty(DP2, DP2_NAME), objectProperty(OP1, null), + objectProperty(OP2, OP2_DOMAIN_PUBLIC))); + } + + private PropertyGroup propertyGroup(String uri, String name, + int displayRank, Property... properties) { + PropertyGroup pg = new PropertyGroup(); + pg.setURI(uri); + pg.setName(name); + pg.setDisplayRank(displayRank); + pg.setPropertyList(new ArrayList<>(Arrays.asList(properties))); + return pg; + } + + private ObjectProperty objectProperty(String uri, String name) { + ObjectProperty op = new ObjectProperty(); + op.setURI(uri); + op.setDomainPublic(name); + return op; + } + + private DataProperty dataProperty(String uri, String name) { + DataProperty dp = new DataProperty(); + dp.setURI(uri); + dp.setName(name); + return dp; + } + +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyWebappsControllerTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyWebappsControllerTest.java new file mode 100644 index 000000000..773616d5b --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyWebappsControllerTest.java @@ -0,0 +1,253 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption.LANGUAGE_NEUTRAL; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.PolicyOption.POLICY_NEUTRAL; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.Property; +import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.OntologyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; +import stubs.javax.servlet.http.HttpServletRequestStub; + +/** + * Not a well-formed set of unit tests. But it's a pretty good exercise of the + * different possibilities in the output stage. + * + * Test plan: + * + *
+ * No data - roots is null -- NONSENSICAL + * No data - roots is empty + * + * Ontology is not specified + * Ontology is specified and matches + * Ontology is specified and does not match + * DataProperty does not match Ontology, but has child properties that do. + * + * Name from picklistName + * Name from getUri + * Name no URL? -- NONSENSICAL + * + * InternalName from localNameWithPrefix + * InternalName from localName + * InternalName from URI + * + * Domain class no class URI + * Domain class no class for URI + * Domain class use picklistName + * + * Range class no class URI + * Range class no class for URI + * Range class use picklistName + * + * Group no group URI + * Group no group for URI + * Group no name + * Group has a name + * + * OP1 Ont1, no picklistName, no localNameWithPrefix, no domainClass, no rangeClass, no GroupURI + * OP2 Ont2, picklistName, no localNameWithPrefix, no domain class for URI, no range class for URI, no group for GroupURI + * OP3 Ont1, picklistName, localNameWithPrefix, domainclass no picklistname, range class no picklistname, group has no name + * OP4 Ont1, picklistName, localNameWithPrefix, domainclass w/picklistname, range class w/picklistname, group with name + * + * Try once with no data + * Try with all data and no ontology specified + * Try with all data and Ont1, Ont2, Ont3 + *+ */ +public class ListPropertyWebappsControllerTest extends ListControllerTestBase { + private static final String PATH = "./propertyEdit"; + private static final String ONT1 = "http://ont1/"; + private static final String ONT2 = "http://ont2/"; + private static final String ONT3 = "http://ont3/"; + private static final String OP1 = ONT1 + "first"; + private static final String OP2 = ONT2 + "second"; + private static final String OP3 = ONT1 + "third"; + private static final String OP4 = ONT1 + "fourth"; + private static final String OP2_PICK_NAME = "The second one"; + private static final String OP3_PICK_NAME = "The third one"; + private static final String OP4_PICK_NAME = "The fourth one"; + private static final String OP3_LOCALNAME_W_PREFIX = "ontology1:third"; + private static final String OP4_LOCALNAME_W_PREFIX = "ontology1:fourth"; + private static final String DOMAIN_NONE = "http://domain/noSuchDomain"; + private static final String DOMAIN_NO_NAME = "http://domain/domainWithNoName"; + private static final String DOMAIN_W_NAME = "http://domain/namedDomain"; + private static final String NAME_DOMAIN = "An excellent domain"; + private static final String RANGE_NONE = "http://domain/noSuchRange"; + private static final String RANGE_NO_NAME = "http://domain/rangeWithNoName"; + private static final String RANGE_W_NAME = "http://domain/namedRange"; + private static final String NAME_RANGE = "Home on the range"; + private static final String GROUP_NONE = "http://domain/noSuchGroup"; + private static final String GROUP_NO_NAME = "http://domain/groupWithNoName"; + private static final String GROUP_W_NAME = "http://domain/namedGroup"; + private static final String NAME_GROUP = "The Groupsters"; + + private static final JsonNode NO_DATA_RESPONSE = arrayOf(mapper + .createObjectNode().put("name", "No object properties found")); + + private static final JsonNode RESPONSE_UNFILTERED = arrayOf( + propertyListNode(PATH, OP1, "first", "first", "", "", + "unspecified"), + propertyListNode(PATH, OP4, OP4_PICK_NAME, OP4_LOCALNAME_W_PREFIX, + NAME_DOMAIN, NAME_RANGE, NAME_GROUP), + propertyListNode(PATH, OP2, OP2_PICK_NAME, "second", "", "", + "unknown group"), + propertyListNode(PATH, OP3, OP3_PICK_NAME, OP3_LOCALNAME_W_PREFIX, + "domainWithNoName", "rangeWithNoName", "")); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT1 = arrayOf( + propertyListNode(PATH, OP1, "first", "first", "", "", + "unspecified"), + propertyListNode(PATH, OP4, OP4_PICK_NAME, OP4_LOCALNAME_W_PREFIX, + NAME_DOMAIN, NAME_RANGE, NAME_GROUP), + propertyListNode(PATH, OP3, OP3_PICK_NAME, OP3_LOCALNAME_W_PREFIX, + "domainWithNoName", "rangeWithNoName", "")); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT2 = arrayOf( + propertyListNode(PATH, OP2, OP2_PICK_NAME, "second", "", "", + "unknown group")); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT3 = arrayOf(mapper + .createObjectNode().put("name", "No object properties found")); + + private ListPropertyWebappsController controller; + private HttpServletRequestStub req; + private ModelAccessFactoryStub modelsFactory; + private WebappDaoFactoryStub wadf; + private ObjectPropertyDaoStub opdao; + private OntologyDaoStub odao; + private PropertyGroupDaoStub pgdao; + private VClassDaoStub vcdao; + + @Before + public void setup() { + controller = new ListPropertyWebappsController(); + + req = new HttpServletRequestStub(); + new VitroRequest(req).setCollator(Collator.getInstance()); + + opdao = new ObjectPropertyDaoStub(); + odao = new OntologyDaoStub(); + pgdao = new PropertyGroupDaoStub(); + vcdao = new VClassDaoStub(); + + wadf = new WebappDaoFactoryStub(); + wadf.setObjectPropertyDao(opdao); + wadf.setOntologyDao(odao); + wadf.setPropertyGroupDao(pgdao); + wadf.setVClassDao(vcdao); + + modelsFactory = new ModelAccessFactoryStub(); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL, + LANGUAGE_NEUTRAL); + } + + // ---------------------------------------------------------------------- + // The tests + // ---------------------------------------------------------------------- + + @Test + public void noDataProperties() throws Exception { + assertMatchingJson(controller, req, NO_DATA_RESPONSE); + } + + @Test + public void unfiltered() throws Exception { + populate(); + assertMatchingJson(controller, req, RESPONSE_UNFILTERED); + } + + @Test + public void filteredByOnt1() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT1); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT1); + } + + @Test + public void filteredByOnt2() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT2); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT2); + } + + @Test + public void filteredByOnt3() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT3); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT3); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void populate() { + vcdao.setVClass(vclass(DOMAIN_NO_NAME, null)); + vcdao.setVClass(vclass(DOMAIN_W_NAME, NAME_DOMAIN)); + vcdao.setVClass(vclass(RANGE_NO_NAME, null)); + vcdao.setVClass(vclass(RANGE_W_NAME, NAME_RANGE)); + pgdao.addPropertyGroup(propertyGroup(GROUP_NO_NAME, null, 5)); + pgdao.addPropertyGroup(propertyGroup(GROUP_W_NAME, NAME_GROUP, 3)); + opdao.addObjectProperty( + objectProperty(OP1, null, null, null, null, null)); + opdao.addObjectProperty(objectProperty(OP2, OP2_PICK_NAME, null, + DOMAIN_NONE, RANGE_NONE, GROUP_NONE)); + opdao.addObjectProperty( + objectProperty(OP3, OP3_PICK_NAME, OP3_LOCALNAME_W_PREFIX, + DOMAIN_NO_NAME, RANGE_NO_NAME, GROUP_NO_NAME)); + opdao.addObjectProperty( + objectProperty(OP4, OP4_PICK_NAME, OP4_LOCALNAME_W_PREFIX, + DOMAIN_W_NAME, RANGE_W_NAME, GROUP_W_NAME)); + } + + private PropertyGroup propertyGroup(String uri, String name, + int displayRank, Property... properties) { + PropertyGroup pg = new PropertyGroup(); + pg.setURI(uri); + pg.setName(name); + pg.setDisplayRank(displayRank); + pg.setPropertyList(new ArrayList<>(Arrays.asList(properties))); + return pg; + } + + private ObjectProperty objectProperty(String uri, String name, + String localNameWithPrefix, String domainVClass, String rangeVClass, + String propertyGroup) { + ObjectProperty op = new ObjectProperty(); + op.setURI(uri); + op.setPickListName(name); + op.setLocalNameWithPrefix(localNameWithPrefix); + op.setRangeVClassURI(rangeVClass); + op.setDomainVClassURI(domainVClass); + op.setGroupURI(propertyGroup); + return op; + } + + private VClass vclass(String uri, String name) { + VClass vc = new VClass(); + vc.setURI(uri); + vc.setPickListName(name); + return vc; + } + +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListVClassWebappsControllerTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListVClassWebappsControllerTest.java new file mode 100644 index 000000000..6df219b9f --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListVClassWebappsControllerTest.java @@ -0,0 +1,233 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.PolicyOption.POLICY_NEUTRAL; + +import java.text.Collator; + +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +import edu.cornell.mannlib.vitro.webapp.beans.Ontology; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.OntologyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; +import stubs.javax.servlet.http.HttpServletRequestStub; + +/** + * Not a well-formed set of unit tests. But it's a pretty good exercise of the + * different possibilities in the output stage. + * + * Test plan: + * + *
+ * + * Ontology is not specified + * Ontology is specified and matches + * Ontology is specified and does not match + * + * classes = empty + * classes = null -- UNREALISTIC + * + * no pickListName + * pickListName + * + * shortDef + * no shortDef + * + * no group uri + * no group for uri + * no name for group + * group with name + * + * ontology not found + * ontology no name + * ontology with name + * + * VC1 - Ont1, no pickListName, no shortDef, no GroupURI, no matching Ontology + * VC2 - Ont2, pickListName, shortDef, no group for GroupURI, ontology has no name + * VC3 - Ont2, pickListName, shortDef, group has no name, ontology with name + * VC4 - Ont1, pickListName, shortDef, group with name, no matching Ontology + * + * Try once with no data + * Try with all data and no ontology specified + * Try with all data and Ont1, Ont2, Ont3 + * Sorted by picklist + *+ */ + +public class ListVClassWebappsControllerTest extends ListControllerTestBase { + private static final String PATH = "./vclassEdit"; + private static final String ONT1 = "http://ont1/"; + private static final String ONT2 = "http://ont2/"; + private static final String ONT3 = "http://ont3/"; + private static final String ONT2_NAME = "Fabulous Ontology"; + private static final String VC1 = ONT1 + "vc1"; + private static final String VC2 = ONT2 + "vc2"; + private static final String VC3 = ONT2 + "vc3"; + private static final String VC4 = ONT1 + "vc4"; + private static final String VC2_NAME = "Carol"; + private static final String VC3_NAME = "Ted"; + private static final String VC4_NAME = "ALice"; + private static final String VC2_SHORT_DEF = "Short Carol"; + private static final String VC3_SHORT_DEF = "Tiny Ted"; + private static final String VC4_SHORT_DEF = "Wee ALice"; + private static final String GROUP_NONE = "http://domain/noSuchGroup"; + private static final String GROUP_NO_NAME = "http://domain/groupWithNoName"; + private static final String GROUP_W_NAME = "http://domain/namedGroup"; + private static final String NAME_GROUP = "The Groupsters"; + + private static final JsonNode JSON_EMPTY_RESPONSE = arrayOf(); + + private static final JsonNode RESPONSE_UNFILTERED = arrayOf( + vclassListNode(PATH, VC4, VC4_NAME, VC4_SHORT_DEF, NAME_GROUP, + ONT1), + vclassListNode(PATH, VC2, VC2_NAME, VC2_SHORT_DEF, "", ONT2_NAME), + vclassListNode(PATH, VC3, VC3_NAME, VC3_SHORT_DEF, "", ONT2_NAME), + degenerateVclassListNode("", "", "", ONT1) // VC1 + ); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT1 = arrayOf( + vclassListNode(PATH, VC4, VC4_NAME, VC4_SHORT_DEF, NAME_GROUP, + ONT1), + degenerateVclassListNode("", "", "", ONT1) // VC1 + ); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT2 = arrayOf( + vclassListNode(PATH, VC2, VC2_NAME, VC2_SHORT_DEF, "", ONT2_NAME), + vclassListNode(PATH, VC3, VC3_NAME, VC3_SHORT_DEF, "", ONT2_NAME)); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT3 = arrayOf(); + + private ListVClassWebappsController controller; + private HttpServletRequestStub req; + private ModelAccessFactoryStub modelsFactory; + private WebappDaoFactoryStub wadf; + private OntologyDaoStub odao; + private VClassDaoStub vcdao; + private VClassGroupDaoStub vcgdao; + + @Before + public void setup() { + controller = new ListVClassWebappsController(); + + req = new HttpServletRequestStub(); + new VitroRequest(req).setCollator(Collator.getInstance()); + + odao = new OntologyDaoStub(); + vcdao = new VClassDaoStub(); + vcgdao = new VClassGroupDaoStub(); + + wadf = new WebappDaoFactoryStub(); + wadf.setOntologyDao(odao); + wadf.setVClassDao(vcdao); + wadf.setVClassGroupDao(vcgdao); + + modelsFactory = new ModelAccessFactoryStub(); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL); + // modelsFactory.get(req).setWebappDaoFactory(wadf, LANGUAGE_NEUTRAL, + // POLICY_NEUTRAL); + } + + // ---------------------------------------------------------------------- + // The tests + // ---------------------------------------------------------------------- + + @Test + public void noData() throws Exception { + assertMatchingJson(controller, req, JSON_EMPTY_RESPONSE); + } + + @Test + public void unfiltered() throws Exception { + populate(); + + // No name produces invalid JSON so we kluge it for easy comparison + String rawResponse = getJsonFromController(controller, req); + String kluged = rawResponse.replace("\"\"\"", "\"\",\""); + assertKlugedJson(RESPONSE_UNFILTERED, kluged); + } + + @Test + public void filteredByOnt1() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT1); + // No name produces invalid JSON so we kluge it for easy comparison + // Filtered out classes leave their commas behind, so remove them + String rawResponse = getJsonFromController(controller, req); + String kluged = rawResponse.replace("\"\"\"", "\"\",\"") + .replace(", , ,", ","); + assertKlugedJson(RESPONSE_FILTERED_BY_ONT1, kluged); + } + + @Test + public void filteredByOnt2() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT2); + // Filtered out classes leave their commas behind, so remove them + String rawResponse = getJsonFromController(controller, req); + String kluged = rawResponse.replaceAll(", $", " "); + assertKlugedJson(RESPONSE_FILTERED_BY_ONT2, kluged); + } + + @Test + public void filteredByOnt3() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT3); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT3); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void populate() { + odao.insertNewOntology(ontology(ONT2, ONT2_NAME)); + odao.insertNewOntology(ontology(ONT3, null)); + vcgdao.setGroups(vclassGroup(GROUP_NO_NAME, null)); + vcgdao.setGroups(vclassGroup(GROUP_W_NAME, NAME_GROUP)); + vcdao.setVClass(vclass(VC1, null, null, null)); + vcdao.setVClass(vclass(VC2, VC2_NAME, VC2_SHORT_DEF, GROUP_NONE)); + vcdao.setVClass(vclass(VC3, VC3_NAME, VC3_SHORT_DEF, GROUP_NO_NAME)); + vcdao.setVClass(vclass(VC4, VC4_NAME, VC4_SHORT_DEF, GROUP_W_NAME)); + } + + private VClass vclass(String uri, String name, String shortDef, + String groupURI) { + VClass vc = new VClass(); + vc.setURI(uri); + if (name != null) { + vc.setName(name); + vc.setPickListName(name); + } + if (shortDef != null) { + vc.setShortDef(shortDef); + } + if (groupURI != null) { + vc.setGroupURI(groupURI); + } + return vc; + } + + private VClassGroup vclassGroup(String uri, String name) { + VClassGroup vcg = new VClassGroup(); + vcg.setURI(uri); + vcg.setPublicName(name); + return vcg; + } + + private Ontology ontology(String uri, String name) { + Ontology o = new Ontology(); + o.setURI(uri); + o.setName(name); + return o; + } +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowClassHierarchyControllerTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowClassHierarchyControllerTest.java new file mode 100644 index 000000000..d64362f67 --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowClassHierarchyControllerTest.java @@ -0,0 +1,229 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ASSERTIONS_ONLY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.POLICY_NEUTRAL; + +import java.text.Collator; + +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; + +import edu.cornell.mannlib.vitro.webapp.beans.Ontology; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.OntologyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; +import stubs.javax.servlet.http.HttpServletRequestStub; + +/** + * Not a well-formed set of unit tests. But it's a pretty good exercise of the + * different possibilities in the output stage. + * + * Test plan: + * + *
+ * No data - roots is null -- NONSENSICAL + * No data - roots is empty + * + * Ontology is not specified + * Ontology is specified and matches + * Ontology is specified and does not match + * VClass does not match Ontology, but has child properties that do. + * + * pickListName + * no pickListName + * + * shortDef + * no shortDef + * + * Group no group URI + * Group no group for URI + * Group no name + * Group has a name + * + * No ontology for namespace + * Ontology but no name + * Ontology with name + * + * DP_1A Ont1, no pickListName, no shortDef, no GroupURI, no matching Ontology + * DP_1B Ont2, pickListName, shortDef, no group for GroupURI, ontology has no name + * DP_1B2A Ont3, pickListName, shortDef, group has no name, ontology with name + * DP_1B2B Ont1, pickListName, shortDef, group with name, no matching Ontology + * + * Try once with no data + * Try with all data and no ontology specified + * Try with all data and Ont1, Ont2, Ont3 + *+ */ +public class ShowClassHierarchyControllerTest extends ListControllerTestBase { + private static final String PATH = "vclassEdit"; + private static final String ONT1 = "http://ont1/"; + private static final String ONT2 = "http://ont2/"; + private static final String ONT3 = "http://ont3/"; + private static final String ONT3_NAME = "Fabulous Ontology"; + private static final String URI_GREATAUNT = ONT1 + "greatAunt"; + private static final String URI_GRANDMOTHER = ONT2 + "grandmother"; + private static final String URI_AUNT = ONT3 + "aunt"; + private static final String URI_MOTHER = ONT1 + "mother"; + private static final String NAME_GRANDMOTHER = "GrandMother"; + private static final String NAME_AUNT = "Aunt"; + private static final String NAME_MOTHER = "Mother"; + private static final String SHORT_DEF_GRANDMOTHER = "My GrandMother"; + private static final String SHORT_DEF_AUNT = "My Aunt"; + private static final String SHORT_DEF_MOTHER = "My Mother"; + private static final String GROUP_NONE = "http://domain/noSuchGroup"; + private static final String GROUP_NO_NAME = "http://domain/groupWithNoName"; + private static final String GROUP_W_NAME = "http://domain/namedGroup"; + private static final String NAME_GROUP = "The Groupsters"; + + private static final ArrayNode JSON_EMPTY_RESPONSE = arrayOf( + vclassHierarchyNode(PATH, + "http://www.w3.org/1999/02/22-rdf-syntax-ns#Resource", + "Resource", "", "", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#")); + + private static final JsonNode RESPONSE_UNFILTERED = arrayOf( + vclassHierarchyNode(PATH,URI_GRANDMOTHER, NAME_GRANDMOTHER, + SHORT_DEF_GRANDMOTHER, "", ONT2, + vclassHierarchyNode(PATH,URI_AUNT, NAME_AUNT, SHORT_DEF_AUNT, "", + ONT3_NAME), + vclassHierarchyNode(PATH,URI_MOTHER, NAME_MOTHER, + SHORT_DEF_MOTHER, NAME_GROUP, ONT1)), + vclassHierarchyNode(PATH,URI_GREATAUNT, "greatAunt", "", "", ONT1)); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT1 = arrayOf( + vclassHierarchyNode(PATH,URI_GREATAUNT, "greatAunt", "", "", ONT1)); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT2 = arrayOf( + vclassHierarchyNode(PATH,URI_GRANDMOTHER, NAME_GRANDMOTHER, + SHORT_DEF_GRANDMOTHER, "", ONT2)); + + private static final JsonNode RESPONSE_FILTERED_BY_ONT3 = arrayOf(); + + private ShowClassHierarchyController controller; + + private HttpServletRequestStub req; + private ModelAccessFactoryStub modelsFactory; + + private OntologyDaoStub ontdao; + private VClassDaoStub vcdao; + private VClassGroupDaoStub vcgdao; + private WebappDaoFactoryStub wadf; + + @Before + public void setup() { + controller = new ShowClassHierarchyController(); + + req = new HttpServletRequestStub(); + new VitroRequest(req).setCollator(Collator.getInstance()); + + ontdao = new OntologyDaoStub(); + + vcdao = new VClassDaoStub(); + + vcgdao = new VClassGroupDaoStub(); + + wadf = new WebappDaoFactoryStub(); + wadf.setOntologyDao(ontdao); + wadf.setVClassDao(vcdao); + wadf.setVClassGroupDao(vcgdao); + + modelsFactory = new ModelAccessFactoryStub(); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL, + ASSERTIONS_ONLY); + } + + // ---------------------------------------------------------------------- + // The tests + // ---------------------------------------------------------------------- + + @Test + public void noData() throws Exception { + assertMatchingJson(controller, req, JSON_EMPTY_RESPONSE); + } + + @Test + public void unfiltered() throws Exception { + populate(); + assertMatchingJson(controller, req, RESPONSE_UNFILTERED); + } + + @Test + public void filteredByOnt1() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT1); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT1); + } + + @Test + public void filteredByOnt2() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT2); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT2); + } + + @Test + public void filteredByOnt3() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT3); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT3); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void populate() { + ontdao.insertNewOntology(ontology(ONT2, null)); + ontdao.insertNewOntology(ontology(ONT3, ONT3_NAME)); + vcgdao.setGroups(vclassGroup(GROUP_NO_NAME, null)); + vcgdao.setGroups(vclassGroup(GROUP_W_NAME, NAME_GROUP)); + vcdao.setVClass(vclass(URI_GREATAUNT, null, null, null)); + vcdao.setVClass(vclass(URI_GRANDMOTHER, NAME_GRANDMOTHER, GROUP_NONE, + SHORT_DEF_GRANDMOTHER)); + vcdao.setVClass( + vclass(URI_AUNT, NAME_AUNT, GROUP_NO_NAME, SHORT_DEF_AUNT), + URI_GRANDMOTHER); + vcdao.setVClass( + vclass(URI_MOTHER, NAME_MOTHER, GROUP_W_NAME, SHORT_DEF_MOTHER), + URI_GRANDMOTHER); + } + + private VClass vclass(String uri, String name, String groupUri, + String shortDef) { + VClass vc = new VClass(); + vc.setURI(uri); + vc.setPickListName(name); + vc.setShortDef(shortDef); + vc.setGroupURI(groupUri); + VClassGroup group = vcgdao.getGroupByURI(groupUri); + if (group != null) { + group.add(vc); + } + return vc; + } + + private Ontology ontology(String uri, String name) { + Ontology o = new Ontology(); + o.setURI(uri); + o.setName(name); + return o; + } + + private VClassGroup vclassGroup(String uri, String name) { + VClassGroup vcg = new VClassGroup(); + vcg.setURI(uri); + vcg.setPublicName(name); + return vcg; + } +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowDataPropertyHierarchyControllerTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowDataPropertyHierarchyControllerTest.java new file mode 100644 index 000000000..af7bb0eee --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowDataPropertyHierarchyControllerTest.java @@ -0,0 +1,286 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ASSERTIONS_ONLY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LANGUAGE_NEUTRAL; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.POLICY_NEUTRAL; + +import java.text.Collator; + +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.databind.node.ArrayNode; + +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; +import edu.cornell.mannlib.vitro.webapp.beans.Datatype; +import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.DatatypeDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; +import stubs.javax.servlet.http.HttpServletRequestStub; + +/** + * Not a well-formed set of unit tests. But it's a pretty good exercise of the + * different possibilities in the output stage. + * + * Test plan: + * + *
+ * No data - roots is null -- NONSENSICAL + * No data - roots is empty + * + * Ontology is not specified + * Ontology is specified and matches + * Ontology is specified and does not match + * DataProperty does not match Ontology, but has child properties that do. + * + * Name from picklistName + * Name from getName + * Name from getUri + * Name no URL? -- NONSENSICAL + * + * InternalName from picklistName + * InternalName missing. + * + * Domain class no class URI + * Domain class no class for URI + * Domain class get picklistName from Language Aware DAO + * Domain class use picklistName from Language Neutral DAO + * + * Range no range URI + * Range no datatype for URI + * Range datatype has no name + * Range has a name + * + * Group no group URI + * Group no group for URI + * Group no name + * Group has a name + * + * Children no children + * Children sorted by picklist + * + * DP_1A Ont1, no name, no picklistName, no domainClass, no RangeClass, no GroupURI + * DP_1B Ont2, name, no picklistName, no domain class for URI, no range datatype for URI, no group for GroupURI + * DP_1B2A Ont1, picklistname, domainclass no picklistname, range datatype with no name, group has no name + * DP_1B2B Ont1, picklistname(less than 1B2A), domainclass w/picklistname, range datatype with name, group with name + * + * Try once with no data + * Try with all data and no ontology specified + * Try with all data and Ont1, Ont2, Ont3 + *+ */ +public class ShowDataPropertyHierarchyControllerTest + extends ListControllerTestBase { + private static final String PATH = "datapropEdit"; + private static final String ONT1 = "http://ont1/"; + private static final String ONT2 = "http://ont2/"; + private static final String ONT3 = "http://ont3/"; + private static final String URI_GREATAUNT = ONT1 + "greatAunt"; + private static final String URI_GRANDMOTHER = ONT2 + "grandmother"; + private static final String URI_AUNT = ONT1 + "aunt"; + private static final String URI_MOTHER = ONT1 + "mother"; + private static final String URI_DAUGHTER = ONT2 + "daughter"; + private static final String NAME_GRANDMOTHER = "GrandMother"; + private static final String NAME_AUNT = "Aunt"; + private static final String NAME_MOTHER = "Mother"; + private static final String NAME_DAUGHTER = "Me"; + private static final String PICK_NAME_AUNT = "Old Aunt Agnes"; + private static final String PICK_NAME_MOTHER = "My Mother"; + private static final String DOMAIN_NONE = "http://domain/noSuchDomain"; + private static final String DOMAIN_NO_NAME = "http://domain/domainWithNoName"; + private static final String DOMAIN_W_NAME = "http://domain/namedDomain"; + private static final String NAME_DOMAIN = "An excellent domain"; + private static final String RANGE_NONE = "http://domain/noSuchRange"; + private static final String RANGE_NO_NAME = "http://domain/rangeWithNoName"; + private static final String RANGE_W_NAME = "http://domain/namedRange"; + private static final String NAME_RANGE = "Home on the range"; + private static final String GROUP_NONE = "http://domain/noSuchGroup"; + private static final String GROUP_NO_NAME = "http://domain/groupWithNoName"; + private static final String GROUP_W_NAME = "http://domain/namedGroup"; + private static final String NAME_GROUP = "The Groupsters"; + + private static final ArrayNode NO_DATA_RESPONSE = arrayOf( // + propertyHierarchyNode(PATH, "nullfake", "ullfake", "ullfake", "", + "", "unspecified")); + + private static final ArrayNode RESPONSE_UNFILTERED = arrayOf( + propertyHierarchyNode(PATH, URI_GRANDMOTHER, "grandmother", + "grandmother", "", "http://domain/noSuchRange", + "unknown group", + propertyHierarchyNode(PATH, URI_MOTHER, PICK_NAME_MOTHER, + "My Mother", "namedDomain", "Home on the range", + "The Groupsters", + propertyHierarchyNode(PATH, URI_DAUGHTER, + "daughter", "daughter", "", "", + "unspecified")), + propertyHierarchyNode(PATH, URI_AUNT, PICK_NAME_AUNT, + "Old Aunt Agnes", "domainWithNoName", "", "")), + propertyHierarchyNode(PATH, URI_GREATAUNT, "greatAunt", "greatAunt", + "", "", "unspecified")); + + private static final ArrayNode RESPONSE_FILTERED_BY_ONT1 = arrayOf( + propertyHierarchyNode(PATH, URI_GREATAUNT, "greatAunt", "greatAunt", + "", "", "unspecified")); + + private static final ArrayNode RESPONSE_FILTERED_BY_ONT2 = arrayOf( + propertyHierarchyNode(PATH, URI_GRANDMOTHER, "grandmother", + "grandmother", "", "http://domain/noSuchRange", + "unknown group", propertyHierarchyNode(PATH, URI_DAUGHTER, + "daughter", "daughter", "", "", "unspecified"))); + + private static final ArrayNode RESPONSE_FILTERED_BY_ONT3 = arrayOf(); + + private ShowDataPropertyHierarchyController controller; + private HttpServletRequestStub req; + private ModelAccessFactoryStub modelsFactory; + private WebappDaoFactoryStub wadf; + private DatatypeDaoStub ddao; + private DataPropertyDaoStub dpdao; + private PropertyGroupDaoStub pgdao; + private VClassDaoStub vcdao; + + @Before + public void setup() { + controller = new ShowDataPropertyHierarchyController(); + + req = new HttpServletRequestStub(); + new VitroRequest(req).setCollator(Collator.getInstance()); + + ddao = new DatatypeDaoStub(); + + dpdao = new DataPropertyDaoStub(); + + pgdao = new PropertyGroupDaoStub(); + + vcdao = new VClassDaoStub(); + + wadf = new WebappDaoFactoryStub(); + wadf.setDatatypeDao(ddao); + wadf.setDataPropertyDao(dpdao); + wadf.setPropertyGroupDao(pgdao); + wadf.setVClassDao(vcdao); + + modelsFactory = new ModelAccessFactoryStub(); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL, + ASSERTIONS_ONLY); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL, + LANGUAGE_NEUTRAL); + } + + // ---------------------------------------------------------------------- + // The tests + // ---------------------------------------------------------------------- + + @Test + public void noDataTest() throws Exception { + // The NO DATA response is not valid JSON unless we kluge it. + String rawResponse = getJsonFromController(controller, req); + String kluged = rawResponse + "]}"; + assertKlugedJson(NO_DATA_RESPONSE, kluged); + + // assertMatchingJson(controller, req, NO_DATA_RESPONSE); + } + + @Test + public void unfiltered() throws Exception { + populate(); + assertMatchingJson(controller, req, RESPONSE_UNFILTERED); + } + + @Test + public void filteredByOnt1() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT1); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT1); + } + + @Test + public void filteredByOnt2() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT2); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT2); + } + + @Test + public void filteredByOnt3() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT3); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT3); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void populate() { + vcdao.setVClass(vclass(DOMAIN_NO_NAME, null)); + vcdao.setVClass(vclass(DOMAIN_W_NAME, NAME_DOMAIN)); + ddao.addDatatype(datatype(RANGE_NO_NAME, null)); + ddao.addDatatype(datatype(RANGE_W_NAME, NAME_RANGE)); + pgdao.addPropertyGroup(propertyGroup(GROUP_NO_NAME, null)); + pgdao.addPropertyGroup(propertyGroup(GROUP_W_NAME, NAME_GROUP)); + dpdao.addDataProperty( + dataProperty(URI_GREATAUNT, null, null, null, null, null)); + dpdao.addDataProperty(dataProperty(URI_GRANDMOTHER, NAME_GRANDMOTHER, + null, DOMAIN_NONE, RANGE_NONE, GROUP_NONE)); + dpdao.addDataProperty( + dataProperty(URI_AUNT, NAME_AUNT, PICK_NAME_AUNT, + DOMAIN_NO_NAME, RANGE_NO_NAME, GROUP_NO_NAME), + URI_GRANDMOTHER); + dpdao.addDataProperty( + dataProperty(URI_MOTHER, NAME_MOTHER, PICK_NAME_MOTHER, + DOMAIN_W_NAME, RANGE_W_NAME, GROUP_W_NAME), + URI_GRANDMOTHER); + dpdao.addDataProperty(dataProperty(URI_DAUGHTER, NAME_DAUGHTER, null, + null, null, null), URI_MOTHER); + } + + private DataProperty dataProperty(String uri, String name, + String pickListName, String domainClassUri, String rangeDatatypeUri, + String groupUri) { + DataProperty dp = new DataProperty(); + dp.setURI(uri); + dp.setName(name); + dp.setPickListName(pickListName); + dp.setDomainClassURI(domainClassUri); + dp.setRangeDatatypeURI(rangeDatatypeUri); + dp.setGroupURI(groupUri); + return dp; + } + + private Datatype datatype(String uri, String name) { + Datatype d = new Datatype(); + d.setUri(uri); + d.setName(name); + return d; + } + + private PropertyGroup propertyGroup(String uri, String name) { + PropertyGroup pg = new PropertyGroup(); + pg.setURI(uri); + pg.setName(name); + return pg; + } + + private VClass vclass(String uri) { + VClass vc = new VClass(); + vc.setURI(uri); + return vc; + } + + private VClass vclass(String uri, String name) { + VClass vc = vclass(uri); + vc.setName(name); + return vc; + } + +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowObjectPropertyHierarchyControllerTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowObjectPropertyHierarchyControllerTest.java new file mode 100644 index 000000000..c5acb6871 --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowObjectPropertyHierarchyControllerTest.java @@ -0,0 +1,292 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.freemarker; + +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ASSERTIONS_ONLY; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LANGUAGE_NEUTRAL; +import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.POLICY_NEUTRAL; + +import java.text.Collator; + +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.databind.node.ArrayNode; + +import edu.cornell.mannlib.vitro.webapp.beans.Datatype; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.DatatypeDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.VClassDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub; +import stubs.javax.servlet.http.HttpServletRequestStub; + +/** + * Not a well-formed set of unit tests. But it's a pretty good exercise of the + * different possibilities in the output stage. + * + * Test plan: + * + *
+ * No data - roots is null -- NONSENSICAL + * No data - roots is empty + * + * Ontology is not specified + * Ontology is specified and matches + * Ontology is specified and does not match + * ObjectProperty does not match Ontology, but has child properties that do. + * + * Name from picklistName + * Name from getLocalName + * Name no URL? -- NONSENSICAL + * + * InternalName from localNameWithPrefix + * InternalName from localName + * + * Domain class no class URI + * Domain class no class for URI + * Domain class get picklistName from Language Aware DAO + * Domain class use picklistName from Language Neutral DAO + * + * Range class no class URI + * Range class no class for URI + * Range class get picklistName from Language Aware DAO + * Range class use picklistName from Language Neutral DAO + * + * Group no group URI + * Group no group for URI + * Group no name + * Group has a name + * + * Children no children + * Children sorted by picklist + * + * DP_1A Ont1, no name, no localnamewithprefix, no picklistName, no domainClass, no RangeClass, no GroupURI + * DP_1B Ont2, name, no localnamewithprefix, no picklistName, no domain class for URI, no range clqss for URI, no group for GroupURI + * DP_1B2A Ont1, name, localnamewithprefix, picklistname, domainclass no picklistname, range class with no picklistname, group has no name + * DP_1B2B Ont1, name, localnamewithprefix, picklistname(less than 1B2A), domain class w/picklistname, range class w/picklistname, group with name + * + * Try once with no data + * Try with all data and no ontology specified + * Try with all data and Ont1, Ont2, Ont3 + *+ */ +public class ShowObjectPropertyHierarchyControllerTest + extends ListControllerTestBase { + private static final String PATH = "propertyEdit"; + private static final String ONT1 = "http://ont1/"; + private static final String ONT2 = "http://ont2/"; + private static final String ONT3 = "http://ont3/"; + private static final String URI_GREATAUNT = ONT1 + "greatAunt"; + private static final String URI_GRANDMOTHER = ONT2 + "grandmother"; + private static final String URI_AUNT = ONT1 + "aunt"; + private static final String URI_MOTHER = ONT1 + "mother"; + private static final String URI_DAUGHTER = ONT2 + "daughter"; + private static final String NAME_GRANDMOTHER = "GrandMother"; + private static final String NAME_AUNT = "Aunt"; + private static final String NAME_MOTHER = "Mother"; + private static final String NAME_DAUGHTER = "Me"; + private static final String LOCAL_NAME_WITH_PREFIX_AUNT = "family:aunt"; + private static final String LOCAL_NAME_WITH_PREFIX_MOTHER = "family:mother"; + private static final String DOMAIN_NONE = "http://domain/noSuchDomain"; + private static final String DOMAIN_NO_NAME = "http://domain/domainWithNoName"; + private static final String DOMAIN_W_NAME = "http://domain/namedDomain"; + private static final String NAME_DOMAIN = "An excellent domain"; + private static final String RANGE_NONE = "http://domain/noSuchRange"; + private static final String RANGE_NO_NAME = "http://domain/rangeWithNoName"; + private static final String RANGE_W_NAME = "http://domain/namedRange"; + private static final String NAME_RANGE = "Home on the range"; + private static final String GROUP_NONE = "http://domain/noSuchGroup"; + private static final String GROUP_NO_NAME = "http://domain/groupWithNoName"; + private static final String GROUP_W_NAME = "http://domain/namedGroup"; + private static final String NAME_GROUP = "The Groupsters"; + + private static final ArrayNode NO_DATA_RESPONSE = arrayOf( // + propertyHierarchyNode(PATH, "nullfake", "ullfake", "ullfake", "", + "", "unspecified")); + + private static final ArrayNode RESPONSE_UNFILTERED = arrayOf( + propertyHierarchyNode(PATH, URI_GRANDMOTHER, NAME_GRANDMOTHER, + "grandmother", "", "", "unknown group", + propertyHierarchyNode(PATH, URI_AUNT, NAME_AUNT, + "family:aunt", "domainWithNoName", "", ""), + propertyHierarchyNode(PATH, URI_MOTHER, NAME_MOTHER, + "family:mother", "namedDomain", "", + "The Groupsters", + propertyHierarchyNode(PATH, URI_DAUGHTER, + NAME_DAUGHTER, "daughter", "", "", + "unspecified"))), + propertyHierarchyNode(PATH, URI_GREATAUNT, "greatAunt", "greatAunt", + "", "", "unspecified")); + + private static final ArrayNode RESPONSE_FILTERED_BY_ONT1 = arrayOf( + propertyHierarchyNode(PATH, URI_GREATAUNT, "greatAunt", "greatAunt", + "", "", "unspecified")); + + private static final ArrayNode RESPONSE_FILTERED_BY_ONT2 = arrayOf( + propertyHierarchyNode(PATH, URI_GRANDMOTHER, NAME_GRANDMOTHER, + "grandmother", "", "", "unknown group", + propertyHierarchyNode(PATH, URI_DAUGHTER, NAME_DAUGHTER, + "daughter", "", "", "unspecified"))); + + private static final ArrayNode RESPONSE_FILTERED_BY_ONT3 = arrayOf(); + + private ShowObjectPropertyHierarchyController controller; + private HttpServletRequestStub req; + private ModelAccessFactoryStub modelsFactory; + private WebappDaoFactoryStub wadf; + private DatatypeDaoStub ddao; + private ObjectPropertyDaoStub opdao; + private PropertyGroupDaoStub pgdao; + private VClassDaoStub vcdao; + + @Before + public void setup() { + controller = new ShowObjectPropertyHierarchyController(); + + req = new HttpServletRequestStub(); + new VitroRequest(req).setCollator(Collator.getInstance()); + + ddao = new DatatypeDaoStub(); + + opdao = new ObjectPropertyDaoStub(); + + pgdao = new PropertyGroupDaoStub(); + + vcdao = new VClassDaoStub(); + + wadf = new WebappDaoFactoryStub(); + wadf.setDatatypeDao(ddao); + wadf.setObjectPropertyDao(opdao); + wadf.setPropertyGroupDao(pgdao); + wadf.setVClassDao(vcdao); + + modelsFactory = new ModelAccessFactoryStub(); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL, + ASSERTIONS_ONLY); + modelsFactory.get(req).setWebappDaoFactory(wadf, POLICY_NEUTRAL, + LANGUAGE_NEUTRAL); + } + + // ---------------------------------------------------------------------- + // The tests + // ---------------------------------------------------------------------- + + @Test + public void noDataTest() throws Exception { + // The NO DATA response is not valid JSON unless we kluge it. + String rawResponse = getJsonFromController(controller, req); + String kluged = rawResponse + "]}"; + assertKlugedJson(NO_DATA_RESPONSE, kluged); + + // assertMatchingJson(controller, req, NO_DATA_RESPONSE); + } + + @Test + public void unfiltered() throws Exception { + populate(); + assertMatchingJson(controller, req, RESPONSE_UNFILTERED); + } + + @Test + public void filteredByOnt1() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT1); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT1); + } + + @Test + public void filteredByOnt2() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT2); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT2); + } + + @Test + public void filteredByOnt3() throws Exception { + populate(); + req.addParameter("ontologyUri", ONT3); + assertMatchingJson(controller, req, RESPONSE_FILTERED_BY_ONT3); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void populate() { + vcdao.setVClass(vclass(DOMAIN_NO_NAME, null)); + vcdao.setVClass(vclass(DOMAIN_W_NAME, NAME_DOMAIN)); + ddao.addDatatype(datatype(RANGE_NO_NAME, null)); + ddao.addDatatype(datatype(RANGE_W_NAME, NAME_RANGE)); + pgdao.addPropertyGroup(propertyGroup(GROUP_NO_NAME, null)); + pgdao.addPropertyGroup(propertyGroup(GROUP_W_NAME, NAME_GROUP)); + opdao.addObjectProperty( + objectProperty(URI_GREATAUNT, null, null, null, null, null)); + opdao.addObjectProperty(objectProperty(URI_GRANDMOTHER, + NAME_GRANDMOTHER, null, DOMAIN_NONE, RANGE_NONE, GROUP_NONE)); + opdao.addObjectProperty( + objectProperty(URI_AUNT, NAME_AUNT, LOCAL_NAME_WITH_PREFIX_AUNT, + DOMAIN_NO_NAME, RANGE_NO_NAME, GROUP_NO_NAME), + URI_GRANDMOTHER); + opdao.addObjectProperty(objectProperty(URI_MOTHER, NAME_MOTHER, + LOCAL_NAME_WITH_PREFIX_MOTHER, DOMAIN_W_NAME, RANGE_W_NAME, + GROUP_W_NAME), URI_GRANDMOTHER); + opdao.addObjectProperty(objectProperty(URI_DAUGHTER, NAME_DAUGHTER, + null, null, null, null), URI_MOTHER); + } + + private ObjectProperty objectProperty(String uri, String name, + String localNameWithPrefix, String domainClassUri, + String rangeDatatypeUri, String groupUri) { + ObjectProperty op = new ObjectProperty(); + op.setURI(uri); + op.setPickListName(name); + op.setLocalNameWithPrefix(localNameWithPrefix); + op.setDomainVClassURI(domainClassUri); + op.setDomainPublic(getLocalName(domainClassUri)); + op.setRangeVClassURI(rangeDatatypeUri); + op.setGroupURI(groupUri); + return op; + } + + private Datatype datatype(String uri, String name) { + Datatype d = new Datatype(); + d.setUri(uri); + d.setName(name); + return d; + } + + private PropertyGroup propertyGroup(String uri, String name) { + PropertyGroup pg = new PropertyGroup(); + pg.setURI(uri); + pg.setName(name); + return pg; + } + + private VClass vclass(String uri) { + VClass vc = new VClass(); + vc.setURI(uri); + return vc; + } + + private VClass vclass(String uri, String name) { + VClass vc = vclass(uri); + vc.setName(name); + return vc; + } + + private String getLocalName(String uri) { + if (uri == null) { + return null; + } + int delimiter = Math.max(uri.lastIndexOf('#'), uri.lastIndexOf('/')); + return uri.substring(delimiter + 1); + } + +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java index 625f0e598..505930e85 100644 --- a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java @@ -196,7 +196,7 @@ public class JsonServletTest extends AbstractTestClass { setLoggerLevel(JsonServlet.class, Level.FATAL); setLoggerLevel(ModelAccess.class, Level.ERROR); String vclassId = "http://myVclass"; - vcDao.setVClass(vclassId, new VClass(vclassId)); + vcDao.setVClass(new VClass(vclassId)); req.addParameter(GET_SEARCH_INDIVIDUALS_BY_VCLASS, "true"); req.addParameter(VCLASS_ID, vclassId); diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/utils/json/JacksonUtilsTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/utils/json/JacksonUtilsTest.java new file mode 100644 index 000000000..6fda141a8 --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/utils/json/JacksonUtilsTest.java @@ -0,0 +1,73 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils.json; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; + +/** + * quotes,\, \r, \n, \b, \f, \t and other control characters. + * + * + */ +public class JacksonUtilsTest extends AbstractTestClass { + + // ---------------------------------------------------------------------- + // Tests for quote() + // quotes,\, \r, \n, \b, \f, \t and other control characters. + // Originally written as direct comparisons to the net.sf.json version. + // ---------------------------------------------------------------------- + + @Test + public void quoteNull() { + assertJacksonQuoted(null, ""); + // assertNetSfJsonQuoted(null, ""); + } + + @Test + public void quoteQuote() { + assertJacksonQuoted("\"", "\\\""); + // assertNetSfJsonQuoted("\"", "\\\""); + } + + @Test + public void quoteBackslash() { + assertJacksonQuoted("\\", "\\\\"); + // assertNetSfJsonQuoted("\\", "\\\\"); + } + + @Test + public void quoteReturn() { + assertJacksonQuoted("\r", "\\r"); + // assertNetSfJsonQuoted("\r", "\\r"); + } + + @Test + public void quoteUnicode() { + assertJacksonQuoted("\u0007", "\\u0007"); + // assertNetSfJsonQuoted("\u0007", "\\u0007"); + } + + @Test + public void quoteAssorted() { + assertJacksonQuoted("\n\b\f\t", "\\n\\b\\f\\t"); + // assertNetSfJsonQuoted("\n\b\f\t", "\\n\\b\\f\\t"); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void assertJacksonQuoted(String raw, String expected) { + String actual = JacksonUtils.quote(raw); + assertEquals("\"" + expected + "\"", actual); + } + + // private void assertNetSfJsonQuoted(String raw, String expected) { + // String actual = net.sf.json.util.JSONUtils.quote(raw); + // assertEquals("\"" + expected + "\"", actual); + // } +} diff --git a/api/src/test/java/stubs/edu/cornell/mannlib/vitro/webapp/dao/DataPropertyDaoStub.java b/api/src/test/java/stubs/edu/cornell/mannlib/vitro/webapp/dao/DataPropertyDaoStub.java index 1268c3be7..29eaebc08 100644 --- a/api/src/test/java/stubs/edu/cornell/mannlib/vitro/webapp/dao/DataPropertyDaoStub.java +++ b/api/src/test/java/stubs/edu/cornell/mannlib/vitro/webapp/dao/DataPropertyDaoStub.java @@ -2,12 +2,15 @@ package stubs.edu.cornell.mannlib.vitro.webapp.dao; -import java.util.ArrayList; +import static java.util.stream.Collectors.toList; + import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import com.google.common.base.Objects; + import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Property; @@ -25,47 +28,86 @@ public class DataPropertyDaoStub implements DataPropertyDao { // ---------------------------------------------------------------------- // Stub infrastructure // ---------------------------------------------------------------------- - - private final Map
+ <#if copyright??> + ©${copyright.year?c} <#if copyright.url??> ${copyright.text} <#else> - ${copyright.text} - #if> -
${i18n().vitro_description}
${i18n().with_vitro}
- +