package com.tinkerpop.rexster; import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.Graph; import com.tinkerpop.blueprints.Index; import com.tinkerpop.blueprints.IndexableGraph; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.rexster.server.RexsterApplication; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONObject; import org.jmock.Expectations; import org.junit.Assert; import org.junit.Test; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.List; /** * @author Stephen Mallette (http://stephen.genoprime.com) */ public class IndexResourceTest extends BaseTest { @Test(expected = WebApplicationException.class) public void getAllIndicesNonIndexableGraph() { final Graph graph = this.mockery.mock(Graph.class); final RexsterApplicationGraph rag = new RexsterApplicationGraph("graph", graph); final RexsterApplication ra = this.mockery.mock(RexsterApplication.class); final UriInfo uri = this.mockery.mock(UriInfo.class); final HttpServletRequest httpServletRequest = this.mockery.mock(HttpServletRequest.class); this.mockery.checking(new Expectations() {{ allowing(httpServletRequest).getParameterMap(); will(returnValue(new HashMap<String, String>())); allowing(httpServletRequest).getParameterNames(); will(returnValue(new Hashtable().keys())); allowing(ra).getApplicationGraph(with(any(String.class))); will(returnValue(rag)); }}); final IndexResource resource = new IndexResource(uri, httpServletRequest, ra); resource.getAllIndices(graphName); } @Test public void getAllIndicesNoOffset() { final IndexResource resource = constructIndexResourceWithToyGraph().getResource(); final Response response = resource.getAllIndices(graphName); this.assertIndexOkResponseJsonStructure(10, 10, response); } @Test public void getAllIndicesWithValidOffset() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_START, "1"); parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_END, "2"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); final Response response = resource.getAllIndices(graphName); this.assertIndexOkResponseJsonStructure(1, 10, response); } @Test public void getAllIndicesWithOffsetNotEnoughResults() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_START, "10"); parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_END, "20"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); final Response response = resource.getAllIndices(graphName); this.assertIndexOkResponseJsonStructure(0, 10, response); } @Test public void getAllIndicesWithOffsetStartAfterEnd() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_START, "3"); parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_END, "2"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); final Response response = resource.getAllIndices(graphName); this.assertIndexOkResponseJsonStructure(0, 10, response); } @Test(expected = WebApplicationException.class) public void getIndexCountIndexNotFound() { final IndexResource resource = constructIndexResourceWithToyGraph().getResource(); resource.getIndexCount(graphName, "index-name-20"); } @Test(expected = WebApplicationException.class) public void getIndexCountIndexBadRequestNoKey() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("value", "name"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.getIndexCount(graphName, "index-name-0"); } @Test(expected = WebApplicationException.class) public void getIndexCountIndexBadRequestNoValue() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("key", "name"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.getIndexCount(graphName, "index-name-0"); } @Test public void getIndexCountIndexValid() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("key", "name"); parameters.put("value", "marko"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); final Response response = resource.getIndexCount(graphName, "index-name-0"); Assert.assertNotNull(response); Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus()); Assert.assertNotNull(response.getEntity()); Assert.assertTrue(response.getEntity() instanceof JSONObject); final JSONObject json = (JSONObject) response.getEntity(); Assert.assertTrue(json.has(Tokens.TOTAL_SIZE)); Assert.assertEquals(1, json.optInt(Tokens.TOTAL_SIZE)); Assert.assertTrue(json.has(Tokens.QUERY_TIME)); } @Test public void getElementsFromIndexAll() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("key", "field"); parameters.put("value", "X"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); final Response response = resource.getElementsFromIndex(graphName, "index-name-9"); Assert.assertNotNull(response); Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus()); Assert.assertNotNull(response.getEntity()); Assert.assertTrue(response.getEntity() instanceof JSONObject); final JSONObject json = (JSONObject) response.getEntity(); Assert.assertTrue(json.has(Tokens.TOTAL_SIZE)); Assert.assertEquals(4, json.optInt(Tokens.TOTAL_SIZE)); Assert.assertTrue(json.has(Tokens.QUERY_TIME)); final JSONArray results = json.optJSONArray(Tokens.RESULTS); Assert.assertEquals(4, results.length()); final List<String> foundIds = new ArrayList<String>(); for (int ix = 0; ix < results.length(); ix++) { foundIds.add(results.optJSONObject(ix).optString(Tokens._ID)); } Assert.assertTrue(foundIds.contains("1")); Assert.assertTrue(foundIds.contains("2")); Assert.assertTrue(foundIds.contains("4")); Assert.assertTrue(foundIds.contains("6")); } @Test public void getElementsFromIndexAllOffset() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("key", "field"); parameters.put("value", "X"); parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_START, "1"); parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_END, "3"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); final Response response = resource.getElementsFromIndex(graphName, "index-name-9"); Assert.assertNotNull(response); Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus()); Assert.assertNotNull(response.getEntity()); Assert.assertTrue(response.getEntity() instanceof JSONObject); final JSONObject json = (JSONObject) response.getEntity(); Assert.assertTrue(json.has(Tokens.TOTAL_SIZE)); Assert.assertEquals(4, json.optInt(Tokens.TOTAL_SIZE)); Assert.assertTrue(json.has(Tokens.QUERY_TIME)); final JSONArray results = json.optJSONArray(Tokens.RESULTS); Assert.assertEquals(2, results.length()); final List<String> foundIds = new ArrayList<String>(); for (int ix = 0; ix < results.length(); ix++) { foundIds.add(results.optJSONObject(ix).optString(Tokens._ID)); } Assert.assertTrue(foundIds.contains("1")); Assert.assertTrue(foundIds.contains("6")); } @Test(expected = WebApplicationException.class) public void deleteIndexNoIndexFound() { final IndexResource resource = constructIndexResourceWithToyGraph().getResource(); resource.deleteIndex(graphName, "index-name-90000"); } @Test public void deleteIndexValid() { final IndexResource resource = constructIndexResourceWithToyGraph().getResource(); resource.deleteIndex(graphName, "index-name-9"); final Index<Vertex> idx = ((IndexableGraph) this.toyGraph).getIndex("index-name-9", Vertex.class); Assert.assertNull(idx); } @Test public void deleteIndexVertexItem() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("key", "name"); parameters.put("value", "0"); parameters.put("id", "1"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.deleteIndex(graphName, "index-name-0"); final Index<Vertex> idx = ((IndexableGraph) this.toyGraph).getIndex("index-name-9", Vertex.class); final Iterable<Vertex> vertices = idx.get("name", "marko"); Assert.assertFalse(vertices.iterator().hasNext()); } @Test public void deleteIndexEdgeItem() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("key", "weight"); parameters.put("value", "0.2"); parameters.put("id", "12"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.deleteIndex(graphName, "index-name-0"); final Index<Edge> idx = ((IndexableGraph) this.toyGraph).getIndex("index-name-5", Edge.class); final Iterable<Edge> edges = idx.get("weight", "0.2"); Assert.assertFalse(edges.iterator().hasNext()); } @Test(expected = WebApplicationException.class) public void postIndexIdxKeysNotAnArray() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("class", "vertex"); parameters.put("keys", "name"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.postIndex(graphName, "index-name-0"); } @Test public void postIndexNewVertexIndex() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("class", "vertex"); parameters.put("keys", "[name]"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.postIndex(graphName, "index-name-100"); final Index idx = ((IndexableGraph) this.toyGraph).getIndex("index-name-100", Vertex.class); Assert.assertNotNull(idx); } @Test public void postIndexNewEdgeIndex() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("class", "edge"); parameters.put("keys", "[weight]"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.postIndex(graphName, "index-name-100"); final Index idx = ((IndexableGraph) this.toyGraph).getIndex("index-name-100", Edge.class); Assert.assertNotNull(idx); } @Test(expected = WebApplicationException.class) public void postIndexAlreadyExists() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("class", "vertex"); parameters.put("keys", "[name]"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.postIndex(graphName, "index-name-1"); } @Test(expected = WebApplicationException.class) public void putElementInIndexNoIndex() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("class", "vertex"); parameters.put("key", "name"); parameters.put("value", "marko"); parameters.put("id", "1"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.putElementInIndex(graphName, "index-name-100"); } @Test(expected = WebApplicationException.class) public void putElementInIndexBadClass() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("class", "nonsense"); parameters.put("key", "name"); parameters.put("value", "marko"); parameters.put("id", "1"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.postIndex(graphName, "index-name-1"); } @Test public void putElementInIndexVertexItem() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("class", "vertex"); parameters.put("key", "name"); parameters.put("value", "marko"); parameters.put("id", "1"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.putElementInIndex(graphName, "index-name-2"); final Index<Vertex> idx = ((IndexableGraph) this.toyGraph).getIndex("index-name-2", Vertex.class); final Vertex v = idx.get("name", "marko").iterator().next(); Assert.assertEquals(this.toyGraph.getVertex(1), v); } @Test public void putElementInIndexEdgeItem() { final HashMap<String, Object> parameters = new HashMap<String, Object>(); parameters.put("class", "edge"); parameters.put("key", "weight"); parameters.put("value", "(f,0.2)"); parameters.put("id", "12"); final IndexResource resource = constructIndexResource(true, parameters).getResource(); resource.putElementInIndex(graphName, "index-name-1"); final Index<Edge> idx = ((IndexableGraph) this.toyGraph).getIndex("index-name-1", Edge.class); final Edge e = idx.get("weight", 0.2f).iterator().next(); Assert.assertEquals(this.toyGraph.getEdge(12), e); } private JSONObject assertIndexOkResponseJsonStructure(final int numberOfIndicesReturned, final int numberOfIndicesTotal, final Response response) { Assert.assertNotNull(response); Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus()); Assert.assertNotNull(response.getEntity()); Assert.assertTrue(response.getEntity() instanceof JSONObject); final JSONObject json = (JSONObject) response.getEntity(); Assert.assertTrue(json.has(Tokens.TOTAL_SIZE)); Assert.assertEquals(numberOfIndicesTotal, json.optInt(Tokens.TOTAL_SIZE)); Assert.assertTrue(json.has(Tokens.QUERY_TIME)); Assert.assertTrue(json.has(Tokens.RESULTS)); Assert.assertFalse(json.isNull(Tokens.RESULTS)); final JSONArray jsonResults = json.optJSONArray(Tokens.RESULTS); Assert.assertEquals(numberOfIndicesReturned, jsonResults.length()); return json; } }