package com.tinkerpop.rexster;
import com.tinkerpop.blueprints.KeyIndexableGraph;
import com.tinkerpop.blueprints.Vertex;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import java.util.HashMap;
import java.util.Set;
/**
* Tests vertex resource. Should not need to test any specific returns values as they are
* covered under other unit tests. The format of the results themselves should be covered
* under the ElementJSONObject.
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public class VertexResourceTest extends BaseTest {
@Test
public void getVerticesAll() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
final Response response = resource.getVertices(graphName);
this.assertVerticesOkResponseJsonStructure(6, 6, response);
final JSONObject json = (JSONObject) response.getEntity();
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.VERTEX, "1", "2", "3", "4", "5", "6");
}
@Test
public void getVerticesKeyIndexed() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put(Tokens.KEY, "name");
parameters.put(Tokens.VALUE, "marko");
final VertexResource resource = this.constructVertexResource(true, parameters).getResource();
final KeyIndexableGraph graph = (KeyIndexableGraph) this.toyGraph;
graph.createKeyIndex("name", Vertex.class);
final Response response = resource.getVertices(graphName);
assertVerticesOkResponseJsonStructure(1, 1, response);
final JSONObject json = (JSONObject) response.getEntity();
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.VERTEX, "1");
}
@Test
public void getVerticesNoResults() {
final VertexResource resource = this.constructVertexResourceWithEmptyGraph().getResource();
final Response response = resource.getVertices(graphName);
this.assertVerticesOkResponseJsonStructure(0, 0, response);
}
@Test
public void getVerticesWithValidOffset() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_START, "1");
parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_END, "3");
final VertexResource resource = this.constructVertexResource(true, parameters).getResource();
final Response response = resource.getVertices(graphName);
this.assertVerticesOkResponseJsonStructure(2, 2, response);
final JSONObject json = (JSONObject) response.getEntity();
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.VERTEX, "2", "1");
}
@Test
public void getVerticesWithInvalidOffsetNotEnoughResults() {
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 VertexResource resource = this.constructVertexResource(true, parameters).getResource();
final Response response = resource.getVertices(graphName);
this.assertVerticesOkResponseJsonStructure(0, 0, response);
}
@Test
public void getVerticesWithInvalidOffsetStartAfterEnd() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_START, "100");
parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_END, "20");
final VertexResource resource = this.constructVertexResource(true, parameters).getResource();
final Response response = resource.getVertices(graphName);
this.assertVerticesOkResponseJsonStructure(0, 0, response);
}
@Test(expected = WebApplicationException.class)
public void getSingleVertexNotFound() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
resource.getSingleVertex(graphName, "id-does-not-match-any");
}
@Test
public void getSingleVertexFound() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
final Response response = resource.getSingleVertex(graphName, "1");
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.QUERY_TIME));
Assert.assertTrue(json.has(Tokens.RESULTS));
Assert.assertFalse(json.isNull(Tokens.RESULTS));
final JSONObject jsonResult = json.optJSONObject(Tokens.RESULTS);
Assert.assertNotNull(jsonResult);
}
@Test(expected = WebApplicationException.class)
public void getVertexEdgesNotFound() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
resource.getSingleVertex(graphName, "id-does-not-match-any");
}
@Test
public void getVertexEdgesFoundVertexReturnInEdgesNoOffset() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
final Response response = resource.getVertexEdges(graphName, "3", Tokens.IN_E);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 3);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.EDGE, "9", "11", "12");
}
@Test
public void getVertexEdgesFoundVertexReturnOutEdgesNoOffsetWithLabel() {
final HashMap<String, Object> map = new HashMap<String, Object>() {{
put(Tokens._LABEL, "created");
}};
final VertexResource resource = this.constructVertexResource(true, map).getResource();
final Response response = resource.getVertexEdges(graphName, "1", Tokens.OUT_E);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 1);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.EDGE, "9");
}
@Test
public void getVertexEdgesFoundVertexReturnInVerticesNoOffset() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
final Response response = resource.getVertexEdges(graphName, "3", Tokens.IN);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 3);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.VERTEX, "1", "6", "4");
}
@Test
public void getVertexEdgesFoundVertexReturnInVerticesNoOffsetWithLabel() {
// add a edge to make sure the test is actually filtering
final Vertex vertexMarko = this.toyGraph.getVertex(1);
final Vertex vertexStephen = this.toyGraph.addVertex(null);
this.toyGraph.addEdge(null, vertexStephen, vertexMarko, "knows");
final HashMap<String, Object> map = new HashMap<String, Object>() {{
put(Tokens._LABEL, "knows");
}};
final VertexResource resource = this.constructVertexResource(true, map).getResource();
final Response response = resource.getVertexEdges("graph", "1", Tokens.IN);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 1);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.VERTEX, vertexStephen.getId().toString());
}
@Test
public void getVertexEdgesFoundVertexOutEdgesNoOffset() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
final Response response = resource.getVertexEdges(graphName, "6", Tokens.OUT_E);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 1);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.EDGE, "12");
}
@Test
public void getVertexEdgesFoundVertexOutVerticesNoOffset() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
final Response response = resource.getVertexEdges(graphName, "6", Tokens.OUT);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 1);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.VERTEX, "3");
}
@Test
public void getVertexEdgesFoundVertexBothEdgesNoOffset() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
final Response response = resource.getVertexEdges(graphName, "4", Tokens.BOTH_E);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 3);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.EDGE, "8", "10", "11");
}
@Test
public void getVertexEdgesFoundVertexBothVerticesNoOffset() {
final VertexResource resource = this.constructVertexResourceWithToyGraph().getResource();
final Response response = resource.getVertexEdges(graphName, "4", Tokens.BOTH);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 3);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.VERTEX, "1", "3", "5");
}
@Test
public void getVertexEdgesFoundVertexBothEdgesWithValidOffset() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_START, "1");
parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_END, "3");
final VertexResource resource = this.constructVertexResource(true, parameters).getResource();
final Response response = resource.getVertexEdges(graphName, "1", Tokens.BOTH_E);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 3);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
this.assertFoundElementsInResults(jsonResultArray, Tokens.EDGE, "8", "9");
}
@Test
public void getVertexEdgesFoundVertexBothEdgesWithOffsetNotEnoughResults() {
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 VertexResource resource = this.constructVertexResource(true, parameters).getResource();
final Response response = resource.getVertexEdges(graphName, "1", Tokens.BOTH_E);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 3);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
Assert.assertNotNull(jsonResultArray);
Assert.assertEquals(0, jsonResultArray.length());
}
@Test
public void getVertexEdgesFoundVertexBothEdgesWithOffsetStartAfterEnd() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_START, "30");
parameters.put(Tokens.REXSTER + "." + Tokens.OFFSET_END, "20");
final VertexResource resource = this.constructVertexResource(true, parameters).getResource();
final Response response = resource.getVertexEdges(graphName, "1", Tokens.BOTH_E);
final JSONObject json = assertEdgesOkResponseJsonStructure(response, 3);
final JSONArray jsonResultArray = json.optJSONArray(Tokens.RESULTS);
Assert.assertNotNull(jsonResultArray);
Assert.assertEquals(0, jsonResultArray.length());
}
@Test
public void postNullVertexOnUriAcceptTypedJsonValid() {
// types are always parsed on the URI
final HashMap<String, Object> parameters = generateVertexParametersToPost(true);
final ResourceHolder<VertexResource> holder = constructVertexResource(false, parameters,
RexsterMediaType.APPLICATION_REXSTER_TYPED_JSON_TYPE);
final VertexResource resource = holder.getResource();
final Response response = resource.postNullVertexOnUri(holder.getRequest(), graphName);
assertPostVertexProducesJson(response, false, true);
}
@Test
public void postNullVertexRexsterConsumesJsonAcceptJsonValid() {
final HashMap<String, Object> parameters = generateVertexParametersToPost(false);
final JSONObject jsonToPost = new JSONObject(parameters);
final ResourceHolder<VertexResource> holder = constructVertexResource(false, parameters);
final VertexResource resource = holder.getResource();
final Response response = resource.postNullVertexRexsterConsumesJson(holder.getRequest(), graphName, jsonToPost);
assertPostVertexProducesJson(response, false, false);
}
@Test
public void postNullVertexRexsterConsumesTypedJsonAcceptTypedJsonValid() {
final HashMap<String, Object> parameters = generateVertexParametersToPost(true);
final JSONObject jsonToPost = new JSONObject(parameters);
final ResourceHolder<VertexResource> holder = constructVertexResource(false, parameters, RexsterMediaType.APPLICATION_REXSTER_TYPED_JSON_TYPE);
final VertexResource resource = holder.getResource();
final Response response = resource.postNullVertexRexsterConsumesTypedJson(holder.getRequest(), graphName, jsonToPost);
assertPostVertexProducesJson(response, false, true);
}
@Test(expected = WebApplicationException.class)
public void postVertexOnUriButHasElementProperties() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put(Tokens._ID, "300");
final ResourceHolder<VertexResource> holder = constructVertexResource(true, parameters);
final VertexResource resource = holder.getResource();
resource.postVertexOnUri(holder.getRequest(), graphName, "1");
}
@Test
public void putVertexConsumesUriValid() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("some-property", "300a");
final ResourceHolder<VertexResource> holder = this.constructVertexResource(true, parameters);
final VertexResource resource = holder.getResource();
final Response response = resource.putVertexConsumesUri(holder.getRequest(), graphName, "1");
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.QUERY_TIME));
Assert.assertTrue(json.has(Tokens.RESULTS));
Assert.assertFalse(json.isNull(Tokens.RESULTS));
final Vertex v = this.toyGraph.getVertex(1);
Assert.assertEquals("300a", v.getProperty("some-property"));
Assert.assertFalse(v.getPropertyKeys().contains("name"));
}
@Test(expected = WebApplicationException.class)
public void putVertexConsumesUriNoVertexFound() {
final HashMap<String, Object> parameters = generateVertexParametersToPost(false);
final ResourceHolder<VertexResource> holder = constructVertexResource(false, parameters);
holder.getResource().putVertexConsumesUri(holder.getRequest(), graphName, "1");
}
@Test
public void deleteVertexValid() {
final ResourceHolder<VertexResource> holder = this.constructVertexResourceWithToyGraph();
final VertexResource resource = holder.getResource();
final Response response = resource.deleteVertex(graphName, "1");
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.QUERY_TIME));
}
@Test(expected = WebApplicationException.class)
public void deleteVertexNoVertexFound() {
final ResourceHolder<VertexResource> holder = this.constructVertexResourceWithToyGraph();
final VertexResource resource = holder.getResource();
resource.deleteVertex(graphName, "100");
}
@Test
public void deleteVertexPropertiesValid() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("name", "");
final ResourceHolder<VertexResource> holder = this.constructVertexResource(true, parameters);
final VertexResource resource = holder.getResource();
final Response response = resource.deleteVertex(graphName, "1");
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.QUERY_TIME));
final Vertex v = this.toyGraph.getVertex(1);
final Set<String> keys = v.getPropertyKeys();
Assert.assertEquals(1, keys.size());
}
private static HashMap<String, Object> generateVertexParametersToPost(boolean rexsterTyped) {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
if (rexsterTyped) {
parameters.put("some-property", "(s,300a)");
parameters.put("int-property", "(i,300)");
} else {
parameters.put("some-property", "300a");
parameters.put("int-property", 300);
}
return parameters;
}
private static void assertPostVertexProducesJson(final Response response, final boolean hasHypermedia, final boolean hasTypes) {
Assert.assertNotNull(response);
Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus());
Assert.assertNotNull(response.getEntity());
Assert.assertTrue(response.getEntity() instanceof JSONObject);
JSONObject json = (JSONObject) response.getEntity();
Assert.assertTrue(json.has(Tokens.QUERY_TIME));
Assert.assertTrue(json.has(Tokens.RESULTS));
Assert.assertFalse(json.isNull(Tokens.RESULTS));
JSONObject postedVertex = json.optJSONObject(Tokens.RESULTS);
if (hasTypes) {
JSONObject somePropertyJson = postedVertex.optJSONObject("some-property");
Assert.assertEquals("string", somePropertyJson.optString("type"));
Assert.assertEquals("300a", somePropertyJson.optString("value"));
JSONObject intPropertyJson = postedVertex.optJSONObject("int-property");
Assert.assertEquals("integer", intPropertyJson.optString("type"));
Assert.assertEquals(300, intPropertyJson.optInt("value"));
} else {
Assert.assertEquals("300a", postedVertex.optString("some-property"));
Assert.assertEquals(300, postedVertex.optInt("int-property"));
}
if (hasHypermedia) {
Assert.assertTrue(json.has(Tokens.EXTENSIONS));
}
}
private JSONObject assertEdgesOkResponseJsonStructure(Response response, int expectedTotalSize) {
Assert.assertNotNull(response);
Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus());
Assert.assertNotNull(response.getEntity());
Assert.assertTrue(response.getEntity() instanceof JSONObject);
JSONObject json = (JSONObject) response.getEntity();
Assert.assertTrue(json.has(Tokens.QUERY_TIME));
Assert.assertTrue(json.has(Tokens.TOTAL_SIZE));
Assert.assertEquals(expectedTotalSize, json.optInt(Tokens.TOTAL_SIZE));
Assert.assertTrue(json.has(Tokens.RESULTS));
Assert.assertFalse(json.isNull(Tokens.RESULTS));
return json;
}
private void assertVerticesOkResponseJsonStructure(int numberOfVerticesReturned, int numberOfVerticesTotal, Response response) {
Assert.assertNotNull(response);
Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus());
Assert.assertNotNull(response.getEntity());
Assert.assertTrue(response.getEntity() instanceof JSONObject);
JSONObject json = (JSONObject) response.getEntity();
Assert.assertTrue(json.has(Tokens.TOTAL_SIZE));
Assert.assertEquals(numberOfVerticesTotal, json.optInt(Tokens.TOTAL_SIZE));
Assert.assertTrue(json.has(Tokens.QUERY_TIME));
Assert.assertTrue(json.has(Tokens.RESULTS));
Assert.assertFalse(json.isNull(Tokens.RESULTS));
JSONArray jsonResults = json.optJSONArray(Tokens.RESULTS);
Assert.assertEquals(numberOfVerticesReturned, jsonResults.length());
}
}