package com.tinkerpop.rexster;
import com.tinkerpop.blueprints.Edge;
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;
/**
* Tests edge 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 EdgeResourceTest extends BaseTest {
@Test
public void getAllEdgesNoOffset() {
final EdgeResource resource = this.constructEdgeResourceWithToyGraph().getResource();
final Response response = resource.getAllEdges(graphName);
this.assertEdgesOkResponseJsonStructure(6, 6, response);
}
@Test
public void getEdgesKeyIndexed() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put(Tokens.KEY, "weight");
parameters.put(Tokens.VALUE, "(f,0.4)");
final EdgeResource resource = this.constructEdgeResource(true, parameters).getResource();
final KeyIndexableGraph graph = (KeyIndexableGraph) this.toyGraph;
graph.createKeyIndex("weight", Edge.class);
assertEdgesOkResponseJsonStructure(2, 2, resource.getAllEdges(graphName));
}
@Test
public void getAllEdgesNoResults() {
final EdgeResource resource = this.constructEdgeResourceWithEmptyGraph().getResource();
final Response response = resource.getAllEdges(graphName);
this.assertEdgesOkResponseJsonStructure(0, 0, response);
}
@Test
public void getAllEdgesWithValidOffset() {
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 EdgeResource resource = this.constructEdgeResource(true, parameters).getResource();
final Response response = resource.getAllEdges(graphName);
this.assertEdgesOkResponseJsonStructure(2, 2, response);
}
@Test
public void getAllEdgesWithInvalidOffsetNotEnoughResults() {
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 EdgeResource resource = this.constructEdgeResource(true, parameters).getResource();
final Response response = resource.getAllEdges(graphName);
this.assertEdgesOkResponseJsonStructure(0, 0, response);
}
@Test
public void getAllEdgesWithInvalidOffsetStartAfterEnd() {
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 EdgeResource resource = this.constructEdgeResource(true, parameters).getResource();
final Response response = resource.getAllEdges(graphName);
this.assertEdgesOkResponseJsonStructure(0, 0, response);
}
@Test(expected = WebApplicationException.class)
public void getSingleEdgeNotFound() {
final EdgeResource resource = this.constructEdgeResourceWithToyGraph().getResource();
resource.getSingleEdge(graphName, "id-does-not-match-any");
}
@Test
public void getSingleVertexFound() {
final EdgeResource resource = this.constructEdgeResourceWithToyGraph().getResource();
final Response response = resource.getSingleEdge(graphName, "12");
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 postNullEdgeConsumesUriBadRequest() {
final ResourceHolder<EdgeResource> holder = this.constructEdgeResourceWithToyGraph();
final EdgeResource resource = holder.getResource();
resource.postNullEdgeConsumesUri(holder.getRequest(), graphName);
}
@Test(expected = WebApplicationException.class)
public void postNullEdgeConsumesUriVerticesNotFound() {
final HashMap<String, Object> parameters = generateEdgeParametersToPost(true);
final ResourceHolder<EdgeResource> holder = this.constructEdgeResource(false, parameters);
final EdgeResource resource = holder.getResource();
resource.postNullEdgeConsumesUri(holder.getRequest(), graphName);
}
@Test(expected = WebApplicationException.class)
public void postEdgeConsumesUriWithIdThatIsExistingEdgeNoProperties() {
final HashMap<String, Object> parameters = generateEdgeParametersToPost(true);
final ResourceHolder<EdgeResource> holder = this.constructEdgeResource(false, parameters);
final EdgeResource resource = holder.getResource();
resource.postEdgeConsumesUri(holder.getRequest(), graphName, "12");
}
@Test
public void postNullEdgeConsumesUriAcceptJsonValid() {
final HashMap<String, Object> parameters = generateEdgeParametersToPost(true);
this.emptyGraph.addVertex(1);
this.emptyGraph.addVertex(2);
final ResourceHolder<EdgeResource> holder = this.constructEdgeResource(false, parameters);
final EdgeResource resource = holder.getResource();
final Response response = resource.postNullEdgeConsumesUri(holder.getRequest(), graphName);
assertPostEdgeProducesJson(response, false, false);
}
@Test
public void postNullEdgeConsumesJsonAcceptJsonValid() {
final HashMap<String, Object> parameters = generateEdgeParametersToPost(false);
final JSONObject jsonToPost = new JSONObject(parameters);
this.emptyGraph.addVertex(1);
this.emptyGraph.addVertex(2);
final ResourceHolder<EdgeResource> holder = this.constructEdgeResource(false, parameters);
final EdgeResource resource = holder.getResource();
final Response response = resource.postNullEdgeConsumesJson(holder.getRequest(), graphName, jsonToPost);
assertPostEdgeProducesJson(response, false, false);
}
@Test
public void postNullEdgeConsumesTypedJsonAcceptJsonValid() {
final HashMap<String, Object> parameters = generateEdgeParametersToPost(true);
final JSONObject jsonToPost = new JSONObject(parameters);
this.emptyGraph.addVertex(1);
this.emptyGraph.addVertex(2);
final ResourceHolder<EdgeResource> holder = this.constructEdgeResource(false, parameters);
final EdgeResource resource = holder.getResource();
final Response response = resource.postNullEdgeConsumesTypedJson(holder.getRequest(), graphName, jsonToPost);
assertPostEdgeProducesJson(response, false, false);
}
@Test
public void postEdgeConsumesUriWithIdThatIsNewEdge() {
final HashMap<String, Object> parameters = generateEdgeParametersToPost(true);
this.emptyGraph.addVertex(1);
this.emptyGraph.addVertex(2);
final ResourceHolder<EdgeResource> holder = this.constructEdgeResource(false, parameters);
final EdgeResource resource = holder.getResource();
final Response response = resource.postEdgeConsumesUri(holder.getRequest(), graphName, "1");
assertPostEdgeProducesJson(response, false, false);
}
@Test
public void postEdgeConsumesUriWithIdThatIsExistingEdgeHasProperties() {
final HashMap<String, Object> parameters = generateEdgeParametersToPost(true);
parameters.put("some-property", "edge-property-value");
final Vertex v1 = this.emptyGraph.addVertex(1);
final Vertex v2 = this.emptyGraph.addVertex(2);
final Edge e = this.emptyGraph.addEdge(1, v1, v2, "knows");
final ResourceHolder<EdgeResource> holder = this.constructEdgeResource(false, parameters);
final EdgeResource resource = holder.getResource();
final Response response = resource.postEdgeConsumesUri(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.assertEquals("edge-property-value", e.getProperty("some-property"));
}
@Test
public void putEdgeOnUriValid() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("newProperty", "NEW");
final Vertex v1 = this.emptyGraph.addVertex(1);
final Vertex v2 = this.emptyGraph.addVertex(2);
final Edge e = this.emptyGraph.addEdge(1, v1, v2, "knows");
e.setProperty("oldProperty", "OLD");
final ResourceHolder<EdgeResource> holder = this.constructEdgeResource(false, parameters);
final EdgeResource resource = holder.getResource();
final Response response = resource.putEdgeOnUri(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.assertEquals("NEW", e.getProperty("newProperty"));
Assert.assertFalse(e.getPropertyKeys().contains("oldProperty"));
}
@Test(expected = WebApplicationException.class)
public void deleteEdgeEdgeNotFound() {
final EdgeResource resource = this.constructEdgeResourceWithToyGraph().getResource();
resource.deleteEdge(graphName, "100");
}
@Test
public void deleteEdgeRemoveEdgeFromGraph() {
Assert.assertNotNull(this.toyGraph.getEdge(12));
final EdgeResource resource = this.constructEdgeResourceWithToyGraph().getResource();
resource.deleteEdge(graphName, "12");
Assert.assertNull(this.toyGraph.getEdge(12));
}
@Test
public void deleteEdgeRemovePropertyFromEdge() {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("to-delete", "");
final Vertex v1 = this.emptyGraph.addVertex(1);
final Vertex v2 = this.emptyGraph.addVertex(2);
final Edge e = this.emptyGraph.addEdge(1, v1, v2, "knows");
e.setProperty("to-delete", "get rid of me");
Assert.assertTrue(this.emptyGraph.getEdge(1).getPropertyKeys().contains("to-delete"));
final ResourceHolder<EdgeResource> holder = this.constructEdgeResource(false, parameters);
final EdgeResource resource = holder.getResource();
final Response response = resource.deleteEdge(graphName, "1");
Assert.assertFalse(this.emptyGraph.getEdge(1).getPropertyKeys().contains("to-delete"));
}
private static void assertPostEdgeProducesJson(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);
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 postedEdge = json.optJSONObject(Tokens.RESULTS);
if (hasTypes) {
final JSONObject somePropertyJson = postedEdge.optJSONObject("some-property");
Assert.assertEquals("string", somePropertyJson.optString("type"));
Assert.assertEquals("300a", somePropertyJson.optString("value"));
final JSONObject intPropertyJson = postedEdge.optJSONObject("int-property");
Assert.assertEquals("integer", intPropertyJson.optString("type"));
Assert.assertEquals(300, intPropertyJson.optInt("value"));
} else {
Assert.assertEquals("300a", postedEdge.optString("some-property"));
Assert.assertEquals(300, postedEdge.optInt("int-property"));
}
if (hasHypermedia) {
Assert.assertTrue(json.has(Tokens.EXTENSIONS));
}
}
private static HashMap<String, Object> generateEdgeParametersToPost(final boolean rexsterTyped) {
final HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put(Tokens._IN_V, "1");
parameters.put(Tokens._OUT_V, "2");
parameters.put(Tokens._LABEL, "edge-label");
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 void assertEdgesOkResponseJsonStructure(final int numberOfEdgesReturned,
final int numberOfEdgesTotal, 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(numberOfEdgesTotal, 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(numberOfEdgesReturned, jsonResults.length());
}
}