NIHVIVO-3542 Refactor IndividualController into 8 classes - focus on cleaning the logic in IndividualRequestAnalyzer - create a unit test for IndividualRequestAnalyzer.

This commit is contained in:
j2blake 2012-01-29 17:23:30 +00:00
parent 5547acc85f
commit fdee610e22
12 changed files with 1680 additions and 5 deletions

View file

@ -0,0 +1,480 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.individual;
import static edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet.N3_MIMETYPE;
import static edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet.RDFXML_MIMETYPE;
import static edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet.TTL_MIMETYPE;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import stubs.edu.cornell.mannlib.vitro.webapp.beans.IndividualStub;
import stubs.javax.servlet.http.HttpServletRequestStub;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.web.ContentType;
/**
* Are we able to figure out what sort of Individual request this is?
*/
public class IndividualRequestAnalyzerTest extends AbstractTestClass {
/**
* Info about the application.
*/
private static final String URL_HOME_PAGE = "http://vivo.mydomain.edu";
private static final String URL_INDIVIDUAL_PAGE = URL_HOME_PAGE
+ "/individual";
private static final String DEFAULT_NAMESPACE = URL_INDIVIDUAL_PAGE + "/";
/**
* Info about the individual that we're testing (mostly).
*/
private static final String ID_INDIVIDUAL_TEST = "testId";
private static final String URI_INDIVIDUAL_TEST = DEFAULT_NAMESPACE
+ ID_INDIVIDUAL_TEST;
private static final String NETID_USER_TEST = "joeUser";
/**
* Info about the file bytestream that appears in one test.
*/
/** The ID of an Individual that represents a FileBytestream object. */
private static final String ID_FILE_BYTESTREAM = "bytesId";
private static final String URI_FILE_BYTESTREAM = DEFAULT_NAMESPACE
+ ID_FILE_BYTESTREAM;
private static final String BYTESTREAM_FILENAME = "imageFilename.jpg";
private static final String URL_BYTESTREAM_ALIAS = URL_HOME_PAGE + "/file/"
+ ID_FILE_BYTESTREAM + "/" + BYTESTREAM_FILENAME;
/**
* Info about an individual that appears in a different namespace.
*/
private static final String SOME_PREFIX = "somePrefix";
private static final String SOME_NAMESPACE = "http://some.namespace/";
private static final String ID_INDIVIDUAL_FOREIGN = "foreignId";
private static final String URI_INDIVIDUAL_FOREIGN = SOME_NAMESPACE
+ ID_INDIVIDUAL_FOREIGN;
private IndividualRequestAnalyzer analyzer;
private MyAnalysisContext analysisContext;
private HttpServletRequestStub req;
private VitroRequest vreq;
private IndividualRequestInfo requestInfo;
private IndividualStub testIndividual;
private IndividualStub bytestreamIndividual;
private IndividualStub foreignIndividual;
@Before
public void setup() {
req = new HttpServletRequestStub();
analysisContext = new MyAnalysisContext(DEFAULT_NAMESPACE);
testIndividual = new IndividualStub(URI_INDIVIDUAL_TEST);
analysisContext.addIndividual(testIndividual);
analysisContext.addProfilePage(NETID_USER_TEST, testIndividual);
bytestreamIndividual = new IndividualStub(URI_FILE_BYTESTREAM);
analysisContext.addIndividual(bytestreamIndividual);
analysisContext.setAliasUrl(URI_FILE_BYTESTREAM, URL_BYTESTREAM_ALIAS);
foreignIndividual = new IndividualStub(URI_INDIVIDUAL_FOREIGN);
analysisContext.addIndividual(foreignIndividual);
analysisContext.setNamespacePrefix(SOME_PREFIX, SOME_NAMESPACE);
}
// ----------------------------------------------------------------------
// Tests - locate by parameter
// ----------------------------------------------------------------------
/** /individual?uri=urlencodedURI */
@Test
public void findIndividualByUriParameter() {
req.setRequestUrl(url(URL_INDIVIDUAL_PAGE));
req.addParameter("uri", URI_INDIVIDUAL_TEST);
analyzeIt();
assertDefaultRequestInfo("find by URI parameter", URI_INDIVIDUAL_TEST);
}
/** /individual?netId=bdc34 */
@Test
public void findIndividualByNetIdParameter() {
req.setRequestUrl(url(URL_INDIVIDUAL_PAGE));
req.addParameter("netId", NETID_USER_TEST);
analyzeIt();
assertDefaultRequestInfo("find by netId parameter", URI_INDIVIDUAL_TEST);
}
/** /individual?netid=bdc34 */
@Test
public void findIndividualByNetidParameter() {
req.setRequestUrl(url(URL_INDIVIDUAL_PAGE));
req.addParameter("netid", NETID_USER_TEST);
analyzeIt();
assertDefaultRequestInfo("find by netid parameter", URI_INDIVIDUAL_TEST);
}
// ----------------------------------------------------------------------
// Tests - miscellaneous
// ----------------------------------------------------------------------
/** /display/localname */
@Test
public void findIndividualByDisplayPath() {
req.setRequestUrl(url(URL_HOME_PAGE + "/display/" + ID_INDIVIDUAL_TEST));
analyzeIt();
assertDefaultRequestInfo("find by display path", URI_INDIVIDUAL_TEST);
}
/** /individual/nsPrefix/localname */
@Test
public void findByPrefixAndLocalname() {
req.setRequestUrl(url(DEFAULT_NAMESPACE + SOME_PREFIX + "/"
+ ID_INDIVIDUAL_FOREIGN));
analyzeIt();
assertDefaultRequestInfo("find by prefix and localname",
URI_INDIVIDUAL_FOREIGN);
}
/** /individual/a/b/c fails. */
@Test
public void unrecognizedPath() {
req.setRequestUrl(url(DEFAULT_NAMESPACE + "this/that/theOther"));
analyzeIt();
assertNoIndividualRequestInfo("unrecognized path");
}
/** /display/localname but no such individual */
@Test
public void findNoSuchIndividualByDisplayPath() {
req.setRequestUrl(url(URL_HOME_PAGE + "/display/" + "bogusID"));
analyzeIt();
assertNoIndividualRequestInfo("unrecognized ID");
}
// ----------------------------------------------------------------------
// Tests - redirect a FileBytestream
// ----------------------------------------------------------------------
@Test
public void redirectAFileBytestreamIndividual() {
req.setRequestUrl(url(URL_HOME_PAGE + "/display/" + ID_FILE_BYTESTREAM));
analyzeIt();
assertBytestreamRedirectInfo("bytestream redirect",
URL_BYTESTREAM_ALIAS);
}
// ----------------------------------------------------------------------
// Tests - redirect from a Linked Data path
// ----------------------------------------------------------------------
/** /individual/localname, accept=RDF redirects to /individual/id/id.rdf */
@Test
public void redirectFromLinkedDataPathAcceptRdf() {
req.setRequestUrl(url(DEFAULT_NAMESPACE + ID_INDIVIDUAL_TEST));
req.setHeader("accept", RDFXML_MIMETYPE);
analyzeIt();
assertRdfRedirectRequestInfo("by linked data path, accept RDF",
redirectUrlForRdfStream(ID_INDIVIDUAL_TEST, ".rdf"));
}
/** /individual/localname, accept=N3 redirects to /individual/id/id.n3 */
@Test
public void redirectFromLinkedDataPathAcceptN3() {
req.setRequestUrl(url(DEFAULT_NAMESPACE + ID_INDIVIDUAL_TEST));
req.setHeader("accept", N3_MIMETYPE);
analyzeIt();
assertRdfRedirectRequestInfo("by linked data path, accept N3",
redirectUrlForRdfStream(ID_INDIVIDUAL_TEST, ".n3"));
}
/** /individual/localname, accept=TTL redirects to /individual/id/id.ttl */
@Test
public void redirectFromLinkedDataPathAcceptTurtle() {
req.setRequestUrl(url(DEFAULT_NAMESPACE + ID_INDIVIDUAL_TEST));
req.setHeader("accept", TTL_MIMETYPE);
analyzeIt();
assertRdfRedirectRequestInfo("by linked data path, accept TTL",
redirectUrlForRdfStream(ID_INDIVIDUAL_TEST, ".ttl"));
}
/** /individual/localname, no accept, redirects to /display/id */
@Test
public void redirectFromLinkedDataPathNoAccept() {
req.setRequestUrl(url(DEFAULT_NAMESPACE + ID_INDIVIDUAL_TEST));
analyzeIt();
assertRdfRedirectRequestInfo("by linked data path with no accept",
"/display/" + ID_INDIVIDUAL_TEST);
}
/**
* If the accept header is set to a recognized value, but not one of the
* onese that we like, treat the same as no accept.
*/
@Test
public void redirectFromLinkedDataPathAcceptStrange() {
req.setRequestUrl(url(DEFAULT_NAMESPACE + ID_INDIVIDUAL_TEST));
req.setHeader("accept", "application/json");
analyzeIt();
assertRdfRedirectRequestInfo(
"by linked data path, accept a strange content type",
"/display/" + ID_INDIVIDUAL_TEST);
}
/**
* If the accept header is set to an unrecognized value, treat the same as
* no accept.
*/
@Test
public void redirectFromLinkedDataPathAcceptGarbage() {
req.setRequestUrl(url(DEFAULT_NAMESPACE + ID_INDIVIDUAL_TEST));
req.setHeader("accept", "a/b/c");
analyzeIt();
assertRdfRedirectRequestInfo(
"by linked data path, accept an unrecognized content type",
"/display/" + ID_INDIVIDUAL_TEST);
}
// ----------------------------------------------------------------------
// Tests - satisfy requests for RDF formats.
// ----------------------------------------------------------------------
@Test
public void getRdfByUriAndFormatParameters() {
req.setRequestUrl(url(URL_INDIVIDUAL_PAGE));
req.addParameter("uri", URI_INDIVIDUAL_TEST);
req.addParameter("format", "rdfxml");
analyzeIt();
assertLinkedDataRequestInfo("RDF by uri and format parameters",
URI_INDIVIDUAL_TEST, ContentType.RDFXML);
}
@Test
public void getN3ByUriAndFormatParameters() {
req.setRequestUrl(url(URL_INDIVIDUAL_PAGE));
req.addParameter("uri", URI_INDIVIDUAL_TEST);
req.addParameter("format", "n3");
analyzeIt();
assertLinkedDataRequestInfo("N3 by uri and format parameters",
URI_INDIVIDUAL_TEST, ContentType.N3);
}
@Test
public void getTurtleByUriAndFormatParameters() {
req.setRequestUrl(url(URL_INDIVIDUAL_PAGE));
req.addParameter("uri", URI_INDIVIDUAL_TEST);
req.addParameter("format", "ttl");
analyzeIt();
assertLinkedDataRequestInfo("Turtle by uri and format parameters",
URI_INDIVIDUAL_TEST, ContentType.TURTLE);
}
@Test
public void unrecognizedFormatParameter() {
req.setRequestUrl(url(URL_INDIVIDUAL_PAGE));
req.addParameter("uri", URI_INDIVIDUAL_TEST);
req.addParameter("format", "bogus");
analyzeIt();
assertDefaultRequestInfo("unrecognized format means HTML response",
URI_INDIVIDUAL_TEST);
}
/** http://vivo.cornell.edu/individual/n23/n23.rdf */
@Test
public void getRdfByStreamRequest() {
req.setRequestUrl(absoluteUrlForRdfStream(ID_INDIVIDUAL_TEST, ".rdf"));
analyzeIt();
assertLinkedDataRequestInfo("RDF by stream request",
URI_INDIVIDUAL_TEST, ContentType.RDFXML);
}
/** http://vivo.cornell.edu/individual/n23/n23.n3 */
@Test
public void getN3ByStreamRequest() {
req.setRequestUrl(absoluteUrlForRdfStream(ID_INDIVIDUAL_TEST, ".n3"));
analyzeIt();
assertLinkedDataRequestInfo("N3 by stream request",
URI_INDIVIDUAL_TEST, ContentType.N3);
}
/** http://vivo.cornell.edu/individual/n23/n23.rdf */
@Test
public void getTurtleByStreamRequest() {
req.setRequestUrl(absoluteUrlForRdfStream(ID_INDIVIDUAL_TEST, ".ttl"));
analyzeIt();
assertLinkedDataRequestInfo("Turtle by stream request",
URI_INDIVIDUAL_TEST, ContentType.TURTLE);
}
/** http://vivo.cornell.edu/individual/n23/n23.bogus is an error */
@Test
public void unrecognizedFormatForRdfStreamRequest() {
req.setRequestUrl(absoluteUrlForRdfStream(ID_INDIVIDUAL_TEST, ".bogus"));
analyzeIt();
assertNoIndividualRequestInfo("Unrecognized RDF stream request");
}
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
/** /individual/n23/n23.rdf, or the like */
private String redirectUrlForRdfStream(String id, String extension) {
return "/individual/" + id + "/" + id + extension;
}
/** http://vivo.mydomain.edu/individual/n23/n23.rdf, or the like */
private URL absoluteUrlForRdfStream(String id, String extension) {
return url(DEFAULT_NAMESPACE + id + "/" + id + extension);
}
private void analyzeIt() {
vreq = new VitroRequest(req);
analyzer = new IndividualRequestAnalyzer(vreq, analysisContext);
requestInfo = analyzer.analyze();
}
/** We should have a DEFAULT request with the expected Individual. */
private void assertDefaultRequestInfo(String message, String individualUri) {
assertEquals(message + ": expecting DEFAULT request type",
IndividualRequestInfo.Type.DEFAULT, requestInfo.getType());
assertNotNull(message + ": expected an individual",
requestInfo.getIndividual());
assertEquals(message + ": expected individual", individualUri,
requestInfo.getIndividual().getURI());
}
/** We should have a RDF_REDIRECT request with the expected URL. */
private void assertRdfRedirectRequestInfo(String message, String redirectUrl) {
assertEquals(message + ": expecting RDF_REDIRECT request type",
IndividualRequestInfo.Type.RDF_REDIRECT, requestInfo.getType());
assertEquals(message + ": expected redirect URL", redirectUrl,
requestInfo.getRedirectUrl());
}
/**
* We should have a BYTESTREAM_REDIRECT request with the expected Individual
* and alias URL.
*/
private void assertBytestreamRedirectInfo(String message, String aliasUrl) {
assertEquals(message + ": expecting BYTESTREAM_REDIRECT request type",
IndividualRequestInfo.Type.BYTESTREAM_REDIRECT,
requestInfo.getType());
assertEquals(message + ": expected alias URL", aliasUrl,
requestInfo.getRedirectUrl());
}
/**
* We should have a NO_INDIVIDUAL request.
*/
private void assertNoIndividualRequestInfo(String message) {
assertEquals(message + ": expecting NO_INDIVIDUAL request type",
IndividualRequestInfo.Type.NO_INDIVIDUAL, requestInfo.getType());
}
/**
* We should have a LINKED_DATA request, with the expected Individual and
* content type.
*/
private void assertLinkedDataRequestInfo(String message,
String individualUri, ContentType contentType) {
assertEquals(message + ": expecting LINKED_DATA request type",
IndividualRequestInfo.Type.LINKED_DATA, requestInfo.getType());
assertNotNull(message + ": expected an individual",
requestInfo.getIndividual());
assertEquals(message + ": expected individual", individualUri,
requestInfo.getIndividual().getURI());
assertNotNull(message + ": expected a content type",
requestInfo.getRdfFormat());
assertEquals(message + ": expected contentType", contentType,
requestInfo.getRdfFormat());
}
// ----------------------------------------------------------------------
// Supporting classes
// ----------------------------------------------------------------------
private static class MyAnalysisContext implements
IndividualRequestAnalysisContext {
// ----------------------------------------------------------------------
// Stub infrastructure
// ----------------------------------------------------------------------
private final String defaultNamespace;
private final Map<String, Individual> individualsByUri = new HashMap<String, Individual>();
private final Map<String, Individual> profilePages = new HashMap<String, Individual>();
private final Map<String, String> namespacesByPrefix = new HashMap<String, String>();
private final Map<String, String> aliasUrlsByIndividual = new HashMap<String, String>();
public MyAnalysisContext(String defaultNamespace) {
this.defaultNamespace = defaultNamespace;
}
public void addIndividual(Individual individual) {
individualsByUri.put(individual.getURI(), individual);
}
public void addProfilePage(String netId, Individual individual) {
profilePages.put(netId, individual);
}
public void setNamespacePrefix(String prefix, String namespace) {
namespacesByPrefix.put(prefix, namespace);
}
public void setAliasUrl(String individualUri, String aliasUrl) {
aliasUrlsByIndividual.put(individualUri, aliasUrl);
}
// ----------------------------------------------------------------------
// Stub methods
// ----------------------------------------------------------------------
@Override
public String getDefaultNamespace() {
return defaultNamespace;
}
@Override
public String getNamespaceForPrefix(String prefix) {
if (prefix == null) {
return "";
}
String namespace = namespacesByPrefix.get(prefix);
return (namespace == null) ? "" : namespace;
}
@Override
public Individual getIndividualByURI(String individualUri) {
if (individualUri == null) {
return null;
}
return individualsByUri.get(individualUri);
}
@Override
public Individual getIndividualByNetId(String netId) {
if (netId == null) {
return null;
}
return profilePages.get(netId);
}
@Override
public String getAliasUrlForBytestreamIndividual(Individual individual) {
if (individual == null) {
return null;
}
return aliasUrlsByIndividual.get(individual.getURI());
}
}
}

View file

@ -8,7 +8,7 @@ import junit.framework.Assert;
import org.junit.Test;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualController;
import edu.cornell.mannlib.vitro.webapp.controller.individual.IndividualController;
public class ContentTypeTest {
@ -41,7 +41,7 @@ public class ContentTypeTest {
Map<String,Float> clientAccepts = ContentType.getTypesAndQ(
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/rdf+xml;q=0.93,text/rdf+n3;q=0.5");
Map<String,Float> serverTypes = IndividualController.getAcceptedContentTypes();
Map<String,Float> serverTypes = IndividualController.ACCEPTED_CONTENT_TYPES;
Assert.assertEquals("application/rdf+xml", ContentType.getBestContentType(clientAccepts, serverTypes));
}
@ -52,7 +52,7 @@ public class ContentTypeTest {
Map<String,Float> clientAccepts = ContentType.getTypesAndQ(
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
Map<String,Float> serverTypes = IndividualController.getAcceptedContentTypes();
Map<String,Float> serverTypes = IndividualController.ACCEPTED_CONTENT_TYPES;
Assert.assertEquals("application/xhtml+xml", ContentType.getBestContentType(clientAccepts, serverTypes));
}