@Test public void shouldBeAbleToIndexValuesContainingSpaces() throws Exception { final long nodeId = helper.createNode(); final String key = "key"; final String value = "value with spaces in it"; String indexName = "spacey-values"; helper.createNodeIndex(indexName); final RestRequest request = RestRequest.req(); JaxRsResponse response = request.post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(nodeId, key, value)); assertEquals(Status.CREATED.getStatusCode(), response.getStatus()); URI location = response.getLocation(); response.close(); response = request.get(functionalTestHelper.indexNodeUri(indexName, key, URIHelper.encode(value))); assertEquals(Status.OK.getStatusCode(), response.getStatus()); Collection<?> hits = (Collection<?>) JsonHelper.jsonToSingleValue(response.getEntity()); assertEquals(1, hits.size()); response.close(); CLIENT.resource(location).delete(); response = request.get(functionalTestHelper.indexNodeUri(indexName, key, URIHelper.encode(value))); hits = (Collection<?>) JsonHelper.jsonToSingleValue(response.getEntity()); assertEquals(0, hits.size()); }
/** * Find node by exact match. * * <p>NOTE: Spaces in the URI have to be encoded as +%20+. */ @Documented @Test public void shouldAddToIndexAndRetrieveItByExactMatch() throws Exception { String indexName = "favorites"; String key = "key"; String value = "the value"; long nodeId = createNode(); value = URIHelper.encode(value); // implicitly create the index JaxRsResponse response = RestRequest.req() .post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(nodeId, key, value)); assertEquals(201, response.getStatus()); // search it exact String entity = gen() .noGraph() .expectedStatus(200) .get(functionalTestHelper.indexNodeUri(indexName, key, URIHelper.encode(value))) .entity(); Collection<?> hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); assertEquals(1, hits.size()); }
/** * Create node index with configuration. This request is only necessary if you want to customize * the index settings. If you are happy with the defaults, you can just start indexing * nodes/relationships, as non-existent indexes will automatically be created as you do. See * <<indexing-create-advanced>> for more information on index configuration. */ @Documented @Test public void shouldCreateANamedNodeIndexWithConfiguration() throws Exception { int expectedIndexes = helper.getNodeIndexes().length + 1; gen() .noGraph() .payload( "{\"name\":\"fulltext\", \"config\":{\"type\":\"fulltext\",\"provider\":\"lucene\"}}") .expectedStatus(201) .expectedHeader("Location") .post(functionalTestHelper.nodeIndexUri()); assertEquals(expectedIndexes, helper.getNodeIndexes().length); assertThat(helper.getNodeIndexes(), FunctionalTestHelper.arrayContains("fulltext")); }
/** List node indexes. */ @Documented @Test public void shouldGetListOfNodeIndexesWhenOneExist() throws PropertyValueException { String indexName = "favorites"; helper.createNodeIndex(indexName); String entity = gen().noGraph().expectedStatus(200).get(functionalTestHelper.nodeIndexUri()).entity(); Map<String, Object> map = JsonHelper.jsonToMap(entity); assertNotNull(map.get(indexName)); assertEquals( "Was: " + map + ", no-auto-index:" + functionalTestHelper.removeAnyAutoIndex(map), 1, functionalTestHelper.removeAnyAutoIndex(map).size()); }
@Test public void shouldGet404ForNonExistingRelationship() { String uri = functionalTestHelper.dataUri() + "relationship/999999/properties/foo"; JaxRsResponse response = RestRequest.req().get(uri); assertEquals(404, response.getStatus()); response.close(); }
@Test public void shouldGet404ForPropertiesOnNonExistentRelationship() { JaxRsResponse response = RestRequest.req().get(functionalTestHelper.dataUri() + "relationship/999999/properties"); assertEquals(404, response.getStatus()); response.close(); }
@Test public void shouldCreateANamedNodeIndexWithSpaces() { String indexName = "favorites with spaces"; int expectedIndexes = helper.getNodeIndexes().length + 1; Map<String, String> indexSpecification = new HashMap<>(); indexSpecification.put("name", indexName); gen() .payload(JsonHelper.createJsonFrom(indexSpecification)) .expectedStatus(201) .expectedHeader("Location") .post(functionalTestHelper.nodeIndexUri()); assertEquals(expectedIndexes, helper.getNodeIndexes().length); assertThat(helper.getNodeIndexes(), FunctionalTestHelper.arrayContains(indexName)); }
/** Remove all entries with a given node, key and value from an index. */ @Documented @Test public void shouldBeAbleToRemoveIndexingByIdAndKeyAndValue() { String key1 = "kvkey1"; String key2 = "kvkey2"; String value1 = "value1"; String value2 = "value2"; String indexName = "kvnode"; long node = helper.createNode(MapUtil.map(key1, value1, key1, value2, key2, value1, key2, value2)); helper.addNodeToIndex(indexName, key1, value1, node); helper.addNodeToIndex(indexName, key1, value2, node); helper.addNodeToIndex(indexName, key2, value1, node); helper.addNodeToIndex(indexName, key2, value2, node); gen() .noGraph() .expectedStatus(204) .delete( functionalTestHelper.nodeIndexUri() + indexName + "/" + key1 + "/" + value1 + "/" + node); assertEquals(0, helper.getIndexedNodes(indexName, key1, value1).size()); assertEquals(1, helper.getIndexedNodes(indexName, key1, value2).size()); assertEquals(1, helper.getIndexedNodes(indexName, key2, value1).size()); assertEquals(1, helper.getIndexedNodes(indexName, key2, value2).size()); }
/** * Create a unique node or return fail (create). * * <p>Here, in case of an already existing node, an error should be returned. In this example, no * existing indexed node is found and a new node is created. */ @Documented @Test public void create_a_unique_node_or_fail_create() throws Exception { final String index = "people", key = "name", value = "Tobias"; helper.createNodeIndex(index); ResponseEntity response = gen.get() .noGraph() .expectedStatus(201 /* created */) .payloadType(MediaType.APPLICATION_JSON_TYPE) .payload( "{\"key\": \"" + key + "\", \"value\": \"" + value + "\", \"properties\": {\"" + key + "\": \"" + value + "\", \"sequence\": 1}}") .post(functionalTestHelper.nodeIndexUri() + index + "?uniqueness=create_or_fail"); MultivaluedMap<String, String> headers = response.response().getHeaders(); Map<String, Object> result = JsonHelper.jsonToMap(response.entity()); assertEquals(result.get("indexed"), headers.getFirst("Location")); Map<String, Object> data = assertCast(Map.class, result.get("data")); assertEquals(value, data.get(key)); assertEquals(1, data.get("sequence")); }
@Test public void shouldGet404WhenDeletingNonExtistentIndex() { String indexName = "nosuchindex"; String indexUri = functionalTestHelper.nodeIndexUri() + indexName; JaxRsResponse response = RestRequest.req().delete(indexUri); assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus()); }
@Test public void shouldGetNodeRepresentationFromIndexUri() throws JsonParseException { long nodeId = helper.createNode(); String key = "key2"; String value = "value"; String indexName = "mindex"; helper.createNodeIndex(indexName); JaxRsResponse response = RestRequest.req() .post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(nodeId, key, value)); assertEquals(Status.CREATED.getStatusCode(), response.getStatus()); String indexUri = response.getHeaders().getFirst("Location"); response = RestRequest.req().get(indexUri); assertEquals(200, response.getStatus()); String entity = response.getEntity(); Map<String, Object> map = JsonHelper.jsonToMap(entity); assertNotNull(map.get("self")); }
@Test public void get_or_create_node_with_array_properties() throws Exception { final String index = "people", key = "name", value = "Tobias"; helper.createNodeIndex(index); ResponseEntity response = gen() .expectedStatus(201 /* created */) .payloadType(MediaType.APPLICATION_JSON_TYPE) .payload( "{\"key\": \"" + key + "\", \"value\": \"" + value + "\", \"properties\": {\"" + key + "\": \"" + value + "\", \"array\": [1,2,3]}}") .post(functionalTestHelper.nodeIndexUri() + index + "?unique"); MultivaluedMap<String, String> headers = response.response().getHeaders(); Map<String, Object> result = JsonHelper.jsonToMap(response.entity()); String location = headers.getFirst("Location"); assertEquals(result.get("indexed"), location); Map<String, Object> data = assertCast(Map.class, result.get("data")); assertEquals(value, data.get(key)); assertEquals(Arrays.asList(1, 2, 3), data.get("array")); Node node; try (Transaction tx = graphdb().beginTx()) { node = graphdb().index().forNodes(index).get(key, value).getSingle(); } assertThat(node, inTx(graphdb(), hasProperty(key).withValue(value))); assertThat(node, inTx(graphdb(), hasProperty("array").withValue(new int[] {1, 2, 3}))); }
/** Delete node index. */ @Documented @Test public void shouldReturn204WhenRemovingNodeIndexes() { String indexName = "kvnode"; helper.createNodeIndex(indexName); gen().noGraph().expectedStatus(204).delete(functionalTestHelper.indexNodeUri(indexName)); }
@Test public void shouldGetNodeIndexRoot() { JaxRsResponse response = RestRequest.req().get(functionalTestHelper.nodeIndexUri(), MediaType.TEXT_HTML_TYPE); assertEquals(Status.OK.getStatusCode(), response.getStatus()); assertValidHtml(response.getEntity()); response.close(); }
@Before public void cleanTheDatabaseAndInitialiseTheNodeUri() throws Exception { nodeUri = new URI( functionalTestHelper.nodeUri() + "/" + new GraphDbHelper(server().getDatabase()).createNode()); }
private void sendRequest(String userAgent) { for (int i = 0; i < CollectUserAgentFilter.SAMPLE_FREQ; i++) { String url = functionalTestHelper.baseUri().toString(); JaxRsResponse resp = RestRequest.req().header("User-Agent", userAgent).get(url); String json = resp.getEntity(); resp.close(); assertEquals(json, 200, resp.getStatus()); } }
@Test public void shouldGet404WhenRequestingIndexUriWhichDoesntExist() { String key = "key3"; String value = "value"; String indexName = "nosuchindex"; String indexUri = functionalTestHelper.nodeIndexUri() + indexName + "/" + key + "/" + value; JaxRsResponse response = RestRequest.req().get(indexUri); assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus()); }
private String createJsonStringFor(final long nodeId, final String key, final String value) { return "{\"key\": \"" + key + "\", \"value\": \"" + value + "\", \"uri\": \"" + functionalTestHelper.nodeUri(nodeId) + "\"}"; }
@Test public void orderedResultsAreSupersetOfUnordered() throws Exception { // Given String indexName = "bobTheIndex"; String key = "Name"; String value = "Builder"; long node = helper.createNode(MapUtil.map(key, value)); helper.addNodeToIndex(indexName, key, value, node); helper.addNodeToIndex(indexName, "Gender", "Male", node); String entity = gen() .expectedStatus(200) .get( functionalTestHelper.indexNodeUri(indexName) + "?query=Name:Build~0.1%20AND%20Gender:Male") .entity(); Collection<?> hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); LinkedHashMap<String, String> nodeMapUnordered = (LinkedHashMap) hits.iterator().next(); // When entity = gen() .expectedStatus(200) .get( functionalTestHelper.indexNodeUri(indexName) + "?query=Name:Build~0.1%20AND%20Gender:Male&order=score") .entity(); hits = (Collection<?>) JsonHelper.jsonToSingleValue(entity); LinkedHashMap<String, String> nodeMapOrdered = (LinkedHashMap) hits.iterator().next(); // Then for (Map.Entry<String, String> unorderedEntry : nodeMapUnordered.entrySet()) { assertEquals( "wrong entry for key: " + unorderedEntry.getKey(), unorderedEntry.getValue(), nodeMapOrdered.get(unorderedEntry.getKey())); } assertTrue( "There should be only one extra value for the ordered map", nodeMapOrdered.size() == nodeMapUnordered.size() + 1); }
@Test public void shouldRespondWith400WhenSendingCorruptJson() throws Exception { final String indexName = "botherable-index"; helper.createNodeIndex(indexName); final String corruptJson = "{\"key\" \"myKey\"}"; JaxRsResponse response = RestRequest.req().post(functionalTestHelper.indexNodeUri(indexName), corruptJson); assertEquals(400, response.getStatus()); response.close(); }
@Test public void shouldGet200WhenRetrievingValidRelationship() throws DatabaseBlockedException { long relationshipId = helper.createRelationship("LIKES"); JaxRsResponse response = RestRequest.req().get(functionalTestHelper.relationshipUri(relationshipId)); assertEquals(200, response.getStatus()); response.close(); }
@Test public void shouldBeJSONContentTypeOnPropertiesResponse() { long relId = helper.createRelationship("LIKES"); helper.setRelationshipProperties(relId, Collections.<String, Object>singletonMap("foo", "bar")); JaxRsResponse response = RestRequest.req() .get(functionalTestHelper.dataUri() + "relationship/" + relId + "/properties"); assertThat(response.getType().toString(), containsString(MediaType.APPLICATION_JSON)); response.close(); }
/** * Backward Compatibility Test (using old syntax ?unique) Put node if absent - Create. * * <p>Add a node to an index unless a node already exists for the given index data. In this case, * a new node is created since nothing existing is found in the index. */ @Documented @Test public void put_node_if_absent___create() throws Exception { final String index = "people", key = "name", value = "Mattias"; helper.createNodeIndex(index); String uri = functionalTestHelper.nodeIndexUri() + index + "?unique"; gen() .expectedStatus(201 /* created */) .payloadType(MediaType.APPLICATION_JSON_TYPE) .payload( "{\"key\": \"" + key + "\", \"value\": \"" + value + "\", \"uri\":\"" + functionalTestHelper.nodeUri(helper.createNode()) + "\"}") .post(uri); }
@Test public void shouldGetThomasAndersonDirectly() { JaxRsResponse response = RestRequest.req() .get(functionalTestHelper.nodeUri(thomasAnderson), MediaType.TEXT_HTML_TYPE); assertEquals(Status.OK.getStatusCode(), response.getStatus()); String entity = response.getEntity(); assertTrue(entity.contains("Thomas Anderson")); assertValidHtml(entity); response.close(); }
@Test public void shouldGet200AndContentLengthForProperties() { long relId = helper.createRelationship("LIKES"); helper.setRelationshipProperties(relId, Collections.<String, Object>singletonMap("foo", "bar")); JaxRsResponse response = RestRequest.req() .get(functionalTestHelper.dataUri() + "relationship/" + relId + "/properties"); assertEquals(200, response.getStatus()); assertNotNull(response.getHeaders().get("Content-Length")); response.close(); }
@Before public void setupTheDatabase() { cleanDatabase(); long relationship = helper.createRelationship("LIKES"); Map<String, Object> map = new HashMap<String, Object>(); map.put("foo", "bar"); helper.setRelationshipProperties(relationship, map); baseRelationshipUri = functionalTestHelper.dataUri() + "relationship/" + relationship + "/properties/"; }
@Test public void shouldGet200WhenGettingNodesFromIndexWithNoHits() { String indexName = "empty-index"; helper.createNodeIndex(indexName); JaxRsResponse response = RestRequest.req() .get( functionalTestHelper.indexNodeUri( indexName, "non-existent-key", "non-existent-value")); assertEquals(200, response.getStatus()); response.close(); }
@Test public void shouldGetARelationshipRepresentationInJsonWhenRetrievingValidRelationship() throws Exception { long relationshipId = helper.createRelationship("LIKES"); JaxRsResponse response = RestRequest.req().get(functionalTestHelper.relationshipUri(relationshipId)); String entity = response.getEntity(String.class); assertNotNull(entity); isLegalJson(entity); response.close(); }
@Test public void shouldGetTrinityWhenSearchingForHer() { JaxRsResponse response = RestRequest.req() .get( functionalTestHelper.indexNodeUri("node", "name", "Trinity"), MediaType.TEXT_HTML_TYPE); assertEquals(Status.OK.getStatusCode(), response.getStatus()); String entity = response.getEntity(); assertTrue(entity.contains("Trinity")); assertValidHtml(entity); response.close(); }
@Test public void shouldGet200AndArrayOfNodeRepsWhenGettingFromIndex() throws PropertyValueException { String key = "myKey"; String value = "myValue"; String name1 = "Thomas Anderson"; String name2 = "Agent Smith"; String indexName = "matrix"; final RestRequest request = RestRequest.req(); JaxRsResponse responseToPost = request.post(functionalTestHelper.nodeUri(), "{\"name\":\"" + name1 + "\"}"); assertEquals(201, responseToPost.getStatus()); String location1 = responseToPost.getHeaders().getFirst(HttpHeaders.LOCATION); responseToPost.close(); responseToPost = request.post(functionalTestHelper.nodeUri(), "{\"name\":\"" + name2 + "\"}"); assertEquals(201, responseToPost.getStatus()); String location2 = responseToPost.getHeaders().getFirst(HttpHeaders.LOCATION); responseToPost.close(); responseToPost = request.post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(functionalTestHelper.getNodeIdFromUri(location1), key, value)); assertEquals(201, responseToPost.getStatus()); String indexLocation1 = responseToPost.getHeaders().getFirst(HttpHeaders.LOCATION); responseToPost.close(); responseToPost = request.post( functionalTestHelper.indexNodeUri(indexName), createJsonStringFor(functionalTestHelper.getNodeIdFromUri(location2), key, value)); assertEquals(201, responseToPost.getStatus()); String indexLocation2 = responseToPost.getHeaders().getFirst(HttpHeaders.LOCATION); Map<String, String> uriToName = new HashMap<>(); uriToName.put(indexLocation1, name1); uriToName.put(indexLocation2, name2); responseToPost.close(); JaxRsResponse response = RestRequest.req().get(functionalTestHelper.indexNodeUri(indexName, key, value)); assertEquals(200, response.getStatus()); Collection<?> items = (Collection<?>) JsonHelper.jsonToSingleValue(response.getEntity()); int counter = 0; for (Object item : items) { Map<?, ?> map = (Map<?, ?>) item; Map<?, ?> properties = (Map<?, ?>) map.get("data"); assertNotNull(map.get("self")); String indexedUri = (String) map.get("indexed"); assertEquals(uriToName.get(indexedUri), properties.get("name")); counter++; } assertEquals(2, counter); response.close(); }