/**
* PODD is an OWL ontology database used for scientific project management
*
* Copyright (C) 2009-2013 The University Of Queensland
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Affero General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.podd.resources.test;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import org.junit.Assert;
import org.junit.Test;
import org.openrdf.model.Model;
import org.openrdf.model.impl.LinkedHashModel;
import org.openrdf.model.vocabulary.OWL;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.Rio;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.ClientResource;
import org.restlet.resource.ResourceException;
import com.github.podd.api.test.TestConstants;
import com.github.podd.utils.InferredOWLOntologyID;
import com.github.podd.utils.PODD;
import com.github.podd.utils.PoddWebConstants;
/**
* @author kutila
*
*/
public class SearchOntologyResourceImplTest extends AbstractResourceImplTest
{
private Model internalTestSearchRdf(final String searchTerm, final String[] searchTypes,
final MediaType requestMediaType, final String artifactUri) throws Exception
{
final ClientResource searchClientResource = new ClientResource(this.getUrl(PoddWebConstants.PATH_SEARCH));
try
{
searchClientResource.addQueryParameter(PoddWebConstants.KEY_SEARCHTERM, searchTerm);
if(artifactUri != null)
{
searchClientResource.addQueryParameter(PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, artifactUri);
}
for(final String searchType : searchTypes)
{
searchClientResource.addQueryParameter(PoddWebConstants.KEY_SEARCH_TYPES, searchType);
}
// invoke the search resource
final Representation results =
this.doTestAuthenticatedRequest(searchClientResource, Method.GET, null, requestMediaType,
Status.SUCCESS_OK, AbstractResourceImplTest.WITH_ADMIN);
final RDFFormat format = Rio.getParserFormatForMIMEType(requestMediaType.getName(), RDFFormat.RDFXML);
// construct a Model out of the result
return Rio.parse(new StringReader(this.getText(results)), "", format);
}
finally
{
this.releaseClient(searchClientResource);
}
}
@Test
public void testErrorSearchRdfWithInvalidArtifactID() throws Exception
{
// prepare:
final ClientResource searchClientResource = new ClientResource(this.getUrl(PoddWebConstants.PATH_SEARCH));
// there is no need to authenticate or have a test artifact as the
// artifact ID is checked
// for first
try
{
searchClientResource.addQueryParameter(PoddWebConstants.KEY_SEARCHTERM, "Scan");
searchClientResource.addQueryParameter(PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, "http://no.such.artifact");
searchClientResource.addQueryParameter(PoddWebConstants.KEY_SEARCH_TYPES,
"http://purl.org/podd/ns/poddScience#Platform");
searchClientResource.get(MediaType.APPLICATION_RDF_XML);
Assert.fail("Should have thrown a ResourceException");
}
catch(final ResourceException e)
{
Assert.assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, e.getStatus());
}
finally
{
this.releaseClient(searchClientResource);
}
}
@Test
public void testErrorSearchRdfWithoutAuthentication() throws Exception
{
// prepare:
final InferredOWLOntologyID testArtifact =
this.loadTestArtifact(TestConstants.TEST_ARTIFACT_20130206, MediaType.APPLICATION_RDF_TURTLE);
final ClientResource searchClientResource = new ClientResource(this.getUrl(PoddWebConstants.PATH_SEARCH));
// request without authentication
try
{
searchClientResource.addQueryParameter(PoddWebConstants.KEY_SEARCHTERM, "Scan");
searchClientResource.addQueryParameter(PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, testArtifact
.getOntologyIRI().toString());
searchClientResource.addQueryParameter(PoddWebConstants.KEY_SEARCH_TYPES,
"http://purl.org/podd/ns/poddScience#Platform");
searchClientResource.get(MediaType.APPLICATION_RDF_XML);
Assert.fail("Should have thrown a ResourceException");
}
catch(final ResourceException e)
{
Assert.assertEquals(Status.CLIENT_ERROR_UNAUTHORIZED, e.getStatus());
}
finally
{
this.releaseClient(searchClientResource);
}
}
@Test
public void testErrorSearchRdfWithoutSearchTerm() throws Exception
{
// prepare:
final InferredOWLOntologyID testArtifact =
this.loadTestArtifact(TestConstants.TEST_ARTIFACT_20130206, MediaType.APPLICATION_RDF_TURTLE);
final ClientResource searchClientResource = new ClientResource(this.getUrl(PoddWebConstants.PATH_SEARCH));
// there is no need to authenticate or have a test artifact as the
// search term is checked
// for first
try
{
// no search term!
searchClientResource.addQueryParameter(PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, testArtifact
.getOntologyIRI().toString());
searchClientResource.addQueryParameter(PoddWebConstants.KEY_SEARCH_TYPES,
"http://purl.org/podd/ns/poddScience#Platform");
searchClientResource.get(MediaType.APPLICATION_RDF_XML);
Assert.fail("Should have thrown a ResourceException");
}
catch(final ResourceException e)
{
Assert.assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, e.getStatus());
}
finally
{
this.releaseClient(searchClientResource);
}
}
@Test
public void testPostRdfBasic() throws Exception
{
// prepare: add an artifact
final InferredOWLOntologyID testArtifact =
this.loadTestArtifact(TestConstants.TEST_ARTIFACT_20130206, MediaType.APPLICATION_RDF_TURTLE);
final ClientResource searchClientResource = new ClientResource(this.getUrl(PoddWebConstants.PATH_SEARCH));
try
{
searchClientResource.addQueryParameter(PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, testArtifact
.getOntologyIRI().toString());
// prepare: the test input
final String[] objectUris =
{ "http://purl.org/podd/basic-1-20130206/object:2966",
"http://purl.org/podd/basic-2-20130206/artifact:1#Demo-Genotype",
"http://purl.org/podd/basic-2-20130206/artifact:1#SqueekeeMaterial",
"http://purl.org/podd/ns/poddScience#WildType_NotApplicable",
"http://purl.org/podd/ns/poddPlant#DeltaTporometer-63",
"http://purl.org/podd/ns/poddBase#DisplayType_LongText" };
final String[] expectedLabels =
{ "Project#2012-0006_ Cotton Leaf Morphology", "Demo genotype", "Squeekee material",
"Not Applicable", "Delta-T porometer", null };
final Model testModel = new LinkedHashModel();
for(final String s : objectUris)
{
testModel.add(PODD.VF.createURI(s), RDFS.LABEL, PODD.VF.createLiteral("?blank"));
}
final RDFFormat inputFormat = RDFFormat.RDFXML;
final MediaType inputMediaType = MediaType.valueOf(inputFormat.getDefaultMIMEType());
// build input representation
final ByteArrayOutputStream output = new ByteArrayOutputStream(8096);
Rio.write(testModel, output, inputFormat);
final Representation input = new StringRepresentation(output.toString(), inputMediaType);
// invoke service
final Representation results =
this.doTestAuthenticatedRequest(searchClientResource, Method.POST, input, inputMediaType,
Status.SUCCESS_OK, AbstractResourceImplTest.WITH_ADMIN);
// verify: response
final Model resultModel = this.assertRdf(results, RDFFormat.RDFXML, 5);
// verify: each URI has the expected label
for(int i = 0; i < objectUris.length; i++)
{
final String objectString =
resultModel.filter(PODD.VF.createURI(objectUris[i]), RDFS.LABEL, null).objectString();
Assert.assertEquals("Not the expected label", expectedLabels[i], objectString);
}
}
finally
{
this.releaseClient(searchClientResource);
}
}
/**
* Test successful search for a Platform in JSON format
*/
@Test
public void testSearchJson() throws Exception
{
final String[] searchTypes = { "http://purl.org/podd/ns/poddScience#Platform" };// ,
// OWL.THING.stringValue()
// };
final MediaType requestMediaType = MediaType.APPLICATION_JSON;
final Model resultModel = this.internalTestSearchRdf("Scan", searchTypes, requestMediaType, null);
Assert.assertEquals("Not the expected number of results", 10, resultModel.size());
System.out.println(resultModel.toString());
Assert.assertEquals("Expected Platform CabScan not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("CabScan")).size());
Assert.assertEquals("Expected Platform PlantScan not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("PlantScan")).size());
}
/**
* Test successful search for a custom Platform in RDF/XML
*/
@Test
public void testSearchRdfForCustomPlatforms() throws Exception
{
// prepare:
final InferredOWLOntologyID testArtifact =
this.loadTestArtifact(TestConstants.TEST_ARTIFACT_20130206, MediaType.APPLICATION_RDF_TURTLE);
final String[] searchTypes = { "http://purl.org/podd/ns/poddScience#Platform" };
final MediaType requestMediaType = MediaType.APPLICATION_RDF_XML;
final Model resultModel =
this.internalTestSearchRdf("lat", searchTypes, requestMediaType, testArtifact.getOntologyIRI()
.toString());
// verify:
Assert.assertEquals("Not the expected number of results", 1, resultModel.size());
Assert.assertEquals("Expected Platform 1 not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("Platform 1")).size());
}
/**
* Test successful search for a Platform in RDF/XML
*/
@Test
public void testSearchRdfForPlatforms() throws Exception
{
final String[] searchTypes = { "http://purl.org/podd/ns/poddScience#Platform" };// ,
// OWL.THING.stringValue()
// };
final MediaType requestMediaType = MediaType.APPLICATION_RDF_XML;
final Model resultModel = this.internalTestSearchRdf("me", searchTypes, requestMediaType, null);
// verify:
Assert.assertEquals("Not the expected number of results", 14, resultModel.size());
Assert.assertEquals("Expected Platform SPAD Meter not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("SPAD Meter")).size());
Assert.assertEquals("Expected Platform Pyrometer not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("Pyrometer")).size());
Assert.assertEquals("Expected Platform SC1 Porometer not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("SC1 Porometer")).size());
}
/**
* Test successful search for a Platform in RDF/XML including owl:Thing in the list to verify
* that it doesn't expand the search space, as the search types must all match. Ie, it is not
* the case that if "any" types match the search will succeed.
*/
@Test
public void testSearchRdfForPlatformsWithOWLThing() throws Exception
{
final String[] searchTypes = { "http://purl.org/podd/ns/poddScience#Platform", OWL.THING.stringValue() };
final MediaType requestMediaType = MediaType.APPLICATION_RDF_XML;
final Model resultModel = this.internalTestSearchRdf("me", searchTypes, requestMediaType, null);
// verify:
Assert.assertEquals("Not the expected number of results", 14, resultModel.size());
Assert.assertEquals("Expected Platform SPAD Meter not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("SPAD Meter")).size());
Assert.assertEquals("Expected Platform Pyrometer not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("Pyrometer")).size());
Assert.assertEquals("Expected Platform SC1 Porometer not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("SC1 Porometer")).size());
}
/**
* Test successful search for a PODD Project in RDF/XML
*/
@Test
public void testSearchRdfForProjects() throws Exception
{
// prepare:
final InferredOWLOntologyID testArtifact =
this.loadTestArtifact(TestConstants.TEST_ARTIFACT_20130206, MediaType.APPLICATION_RDF_TURTLE);
final String[] searchTypes = { "http://purl.org/podd/ns/poddScience#Project" };
final MediaType requestMediaType = MediaType.APPLICATION_RDF_XML;
final Model resultModel =
this.internalTestSearchRdf("Cot", searchTypes, requestMediaType, testArtifact.getOntologyIRI()
.toString());
// verify:
Assert.assertEquals("Not the expected number of results", 1, resultModel.size());
Assert.assertTrue("Expected Project not found", resultModel.filter(null, RDFS.LABEL, null).objectString()
.contains("Cotton Leaf Morphology"));
}
/**
* Test successful search for PoddScience:Sex values in RDF/XML
*/
@Test
public void testSearchRdfForSex() throws Exception
{
// prepare: add an artifact
final InferredOWLOntologyID testArtifact =
this.loadTestArtifact(TestConstants.TEST_ARTIFACT_20130206, MediaType.APPLICATION_RDF_TURTLE);
final String[] searchTypes = { "http://purl.org/podd/ns/poddScience#Sex" };
final MediaType requestMediaType = MediaType.APPLICATION_RDF_XML;
final Model resultModel =
this.internalTestSearchRdf("", searchTypes, requestMediaType, testArtifact.getOntologyIRI().toString());
Assert.assertEquals("Not the expected number of results", 5, resultModel.size());
Assert.assertEquals("Value Hermaphrodite not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("Hermaphrodite")).size());
Assert.assertEquals("Value Male not found", 1, resultModel.filter(null, null, PODD.VF.createLiteral("Male"))
.size());
}
/**
* Test successful search for a FOR Codes in RDF/XML
*/
@Test
public void testSearchRdfForWildtTypeAssertion() throws Exception
{
final String[] searchTypes = { "http://purl.org/podd/ns/poddScience#WildTypeAssertion" };
final MediaType requestMediaType = MediaType.APPLICATION_RDF_XML;
final Model resultModel = this.internalTestSearchRdf("", searchTypes, requestMediaType, null);
// verify:
Assert.assertEquals("Not the expected number of results", 4, resultModel.size());
Assert.assertEquals("Expected Assertion 'Yes' not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("Yes")).size());
Assert.assertEquals("Expected Assertion 'Unknown' not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("Unknown")).size());
Assert.assertEquals("Expected Assertion 'Not Applicable' not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("Not Applicable")).size());
}
/**
* Test a search in RDF/XML, with no "searchTypes" specified.
*/
@Test
public void testSearchRdfWithoutSearchTypes() throws Exception
{
final String[] searchTypes = {}; // EVERYTHING in the search space is
// compared
final MediaType requestMediaType = MediaType.APPLICATION_RDF_XML;
final Model resultModel = this.internalTestSearchRdf("e", searchTypes, requestMediaType, null);
// verify:
Assert.assertEquals("Not the expected number of results", 310, resultModel.size());
Assert.assertEquals("dcTerms not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("The PODD Ontology for Dublin Core Terms")).size());
Assert.assertEquals("The PODD Ontology for Dublin Core Terms not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("The PODD Ontology for Dublin Core Terms")).size());
}
/**
* Test successful search for a Platform in Turtle
*/
@Test
public void testSearchTurtle() throws Exception
{
final String[] searchTypes = { "http://purl.org/podd/ns/poddScience#Platform" };// ,
// OWL.THING.stringValue()
// };
final MediaType requestMediaType = MediaType.APPLICATION_RDF_TURTLE;
final Model resultModel = this.internalTestSearchRdf("Scan", searchTypes, requestMediaType, null);
Assert.assertEquals("Not the expected number of results", 10, resultModel.size());
System.out.println(resultModel.toString());
Assert.assertEquals("Expected Platform CabScan not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("CabScan")).size());
Assert.assertEquals("Expected Platform PlantScan not found", 1,
resultModel.filter(null, null, PODD.VF.createLiteral("PlantScan")).size());
}
}