public async Task ShouldSendCommandAndNotCareAboutResults() { // Arrange const string queryText = @"START d=node($p0), e=node($p1) CREATE UNIQUE d-[:foo]->e"; var parameters = new Dictionary <string, object> { { "p0", 215 }, { "p1", 219 } }; var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set, CypherResultFormat.Rest, "neo4j"); var transactionApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery) }; using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/transaction/commit", transactionApiQuery), MockResponse.Http((int)HttpStatusCode.OK) } }) { var graphClient = await testHarness.CreateAndConnectGraphClient(); //Act await graphClient.ExecuteCypherAsync(cypherQuery); } }
//https://github.com/Readify/Neo4jClient/issues/127 public void ReturnsCorrectError_WhenTransactionIsAutomaticallyRolledBack_ViaNeo4j_2_2_6_Plus([Values(RestTestHarness.Neo4jVersion.Neo226/*, RestTestHarness.Neo4jVersion.Neo23*/)] RestTestHarness.Neo4jVersion version) { /* In 2.2.6 ClientErrors (Constraint Violations etc) were changed to Automatically rollback. This created a 404 error when *we* tried to rollback on an error, as the transaction no longer existed. */ var initTransactionRequest = MockRequest.PostJson("/transaction", @"{ 'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}"); var rollbackTransactionRequest = MockRequest.Delete("/transaction/1"); using (var testHarness = new RestTestHarness { { initTransactionRequest, MockResponse.Json(201, TransactionRestResponseHelper.GenerateCypherErrorResponse(1, "{\"code\":\"Neo.ClientError.Schema.ConstraintViolation\",\"message\":\"Node 19572 already exists with label User and property.\"}"), "http://foo/db/data/transaction/1") }, { rollbackTransactionRequest, MockResponse.Json(404, "{\"results\":[],\"errors\":[{\"code\":\"Neo.ClientError.Transaction.UnknownId\",\"message\":\"Unrecognized transaction id. Transaction may have timed out and been rolled back.\"}]}") } }) { var client = testHarness.CreateGraphClient(version); client.Connect(); using (var transaction = client.BeginTransaction()) { client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResults(); } } }
public void ShouldSendCommandAndNotCareAboutResults() { // Arrange const string queryText = @"START d=node({p0}), e=node({p1}) CREATE UNIQUE d-[:foo]->e"; var parameters = new Dictionary<string, object> { {"p0", 215}, {"p1", 219} }; var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set); var cypherApiQuery = new CypherApiQuery(cypherQuery); using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/cypher", cypherApiQuery), MockResponse.Http((int)HttpStatusCode.OK) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); //Act graphClient.ExecuteCypher(cypherQuery); } }
public void ShouldSendCommandAndNotCareAboutResultsAsync() { // Arrange const string queryText = @"return 1"; var parameters = new Dictionary<string, object>(); var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set); var cypherApiQuery = new CypherApiQuery(cypherQuery); using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/cypher", cypherApiQuery), MockResponse.Http((int)HttpStatusCode.OK) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); bool raisedEvent = false; graphClient.OperationCompleted += (sender, e) => { raisedEvent = true; }; //Act var task = graphClient.ExecuteCypherAsync(cypherQuery); task.Wait(); Assert.IsTrue(raisedEvent, "Raised OperationCompleted"); } }
public void ShouldUpdatePayload() { using (var testHarness = new RestTestHarness { { MockRequest.Get("/relationship/456/properties"), MockResponse.Json(HttpStatusCode.OK, "{ 'Foo': 'foo', 'Bar': 'bar', 'Baz': 'baz' }") }, { MockRequest.PutObjectAsJson( "/relationship/456/properties", new TestPayload { Foo = "fooUpdated", Bar = "bar", Baz = "bazUpdated" }), MockResponse.Http((int)HttpStatusCode.NoContent) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); graphClient.Update( new RelationshipReference<TestPayload>(456), payloadFromDb => { payloadFromDb.Foo = "fooUpdated"; payloadFromDb.Baz = "bazUpdated"; } ); } }
public void ExecuteAsyncRequestInTransaction() { const string queryText = @"MATCH (n) RETURN count(n) as Total"; const string resultColumn = @"{'columns':['Total'], 'data':[{'row':[1]}]}"; var cypherQuery = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Projection); var cypherApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery, false) }; var commitRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}"); using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/transaction", cypherApiQuery), MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1") }, { commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }") } }) { var client = testHarness.CreateAndConnectTransactionalGraphClient(); var rawClient = (IRawGraphClient)client; using (var tran = client.BeginTransaction()) { var totalObj = rawClient.ExecuteGetCypherResultsAsync <DummyTotal>(cypherQuery).Result.Single(); Assert.AreEqual(1, totalObj.Total); tran.Commit(); } } }
public void ShouldCreateIndex( IndexFor indexFor, IndexProvider indexProvider, IndexType indexType, string createEndpoint, string createJson) { //Arrange using (var testHarness = new RestTestHarness { { MockRequest.PostJson(createEndpoint, createJson), MockResponse.Http(201) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); var indexConfiguration = new IndexConfiguration { Provider = indexProvider, Type = indexType }; graphClient.CreateIndex("foo", indexConfiguration, indexFor); } }
public void ShouldReturnNodeDataForLongId() { using (var testHarness = new RestTestHarness { { MockRequest.Get("/node/21484836470"), MockResponse.Json(HttpStatusCode.OK, @"{ 'self': 'http://foo/db/data/node/21484836470', 'data': { 'Foo': 'foo', 'Bar': 'bar', 'Baz': 'baz' }, 'create_relationship': 'http://foo/db/data/node/21484836470/relationships', 'all_relationships': 'http://foo/db/data/node/21484836470/relationships/all', 'all_typed relationships': 'http://foo/db/data/node/21484836470/relationships/all/{-list|&|types}', 'incoming_relationships': 'http://foo/db/data/node/21484836470/relationships/in', 'incoming_typed relationships': 'http://foo/db/data/node/21484836470/relationships/in/{-list|&|types}', 'outgoing_relationships': 'http://foo/db/data/node/21484836470/relationships/out', 'outgoing_typed relationships': 'http://foo/db/data/node/21484836470/relationships/out/{-list|&|types}', 'properties': 'http://foo/db/data/node/21484836470/properties', 'property': 'http://foo/db/data/node/21484836470/property/{key}', 'traverse': 'http://foo/db/data/node/21484836470/traverse/{returnType}' }") } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); var node = graphClient.Get<TestNode>((NodeReference)21484836470); Assert.AreEqual(21484836470, node.Reference.Id); Assert.AreEqual("foo", node.Data.Foo); Assert.AreEqual("bar", node.Data.Bar); Assert.AreEqual("baz", node.Data.Baz); } }
public void ShouldReturnEmptyEnumerableForNullResult() { //Arrange const string gremlinQueryExpected = "foo bar query"; var query = new GremlinApiQuery(gremlinQueryExpected, null); using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/ext/GremlinPlugin/graphdb/execute_script", query), MockResponse.Json(HttpStatusCode.OK, @"[]") } }) { var graphClient = (GraphClient)testHarness.CreateAndConnectGraphClient(); //Act var nodes = graphClient .ExecuteGetAllRelationshipsGremlin(gremlinQueryExpected, null) .ToList(); //Assert Assert.AreEqual(0, nodes.Count()); } }
public void ShouldSendCommandAndNotCareAboutResults() { // Arrange const string queryText = @"START d=node({p0}), e=node({p1}) CREATE UNIQUE d-[:foo]->e"; var parameters = new Dictionary <string, object> { { "p0", 215 }, { "p1", 219 } }; var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set); var cypherApiQuery = new CypherApiQuery(cypherQuery); using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/cypher", cypherApiQuery), MockResponse.Http((int)HttpStatusCode.OK) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); //Act graphClient.ExecuteCypher(cypherQuery); } }
public async Task ThrowsClientException_WhenGettingErrorResponse() { const string queryText = @"return 1"; var parameters = new Dictionary <string, object>(); var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set, "neo4j"); var transactionApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery) }; using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/transaction/commit", transactionApiQuery), EmptyErrorResponse } }) { var graphClient = await testHarness.CreateAndConnectGraphClient(); //Act var ex = await Assert.ThrowsAsync <ClientException>(async() => await graphClient.ExecuteCypherAsync(cypherQuery)); ex.Code.Should().Be("Error 1"); ex.Message.Should().Be("Unable to do Cypher"); } }
public async Task WhenExecuteCypherFails_ShouldRaiseCompletedWithException() { // Arrange const string queryText = @"bad cypher"; var parameters = new Dictionary <string, object>(); var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set, "neo4j"); var transactionApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery) }; using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/transaction/commit", transactionApiQuery), MockResponse.Throws() } }) { var graphClient = await testHarness.CreateAndConnectGraphClient(); OperationCompletedEventArgs eventArgs = null; graphClient.OperationCompleted += (sender, e) => { eventArgs = e; }; //Act await Assert.ThrowsAsync <MockResponseThrowsException>(async() => { await graphClient.ExecuteCypherAsync(cypherQuery); }); Assert.NotNull(eventArgs); Assert.True(eventArgs.HasException); Assert.Equal(typeof(MockResponseThrowsException), eventArgs.Exception.GetType()); Assert.Equal(-1, eventArgs.ResourcesReturned); } }
public void ShouldPromoteBadQueryResponseToNiceException() { // Arrange const string queryText = @"broken query"; var cypherQuery = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Projection); var cypherApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery, false) }; using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/transaction", cypherApiQuery), MockResponse.Json(HttpStatusCode.OK, @"{'results':[], 'errors': [{ 'code' : 'Neo.ClientError.Statement.InvalidSyntax', 'message' : 'Invalid input b: expected SingleStatement (line 1, column 1)\nThis is not a valid Cypher Statement.\n ^' }]}") } }) { var graphClient = testHarness.CreateAndConnectTransactionalGraphClient(); var rawClient = (IRawGraphClient)graphClient; using (graphClient.BeginTransaction()) { var ex = Assert.Throws <NeoException>(() => rawClient.ExecuteCypher(cypherQuery)); Assert.AreEqual("InvalidSyntax: Invalid input b: expected SingleStatement (line 1, column 1)\nThis is not a valid Cypher Statement.\n ^", ex.Message); Assert.AreEqual("Invalid input b: expected SingleStatement (line 1, column 1)\nThis is not a valid Cypher Statement.\n ^", ex.NeoMessage); Assert.AreEqual("InvalidSyntax", ex.NeoExceptionName); Assert.AreEqual("Neo.ClientError.Statement.InvalidSyntax", ex.NeoFullName); CollectionAssert.AreEqual(new String[] {}, ex.NeoStackTrace); } } }
//https://github.com/Readify/Neo4jClient/issues/127 public void ReturnsThe404_WhenVersionIsLessThan_2_2_6([Values(RestTestHarness.Neo4jVersion.Neo20, RestTestHarness.Neo4jVersion.Neo22, RestTestHarness.Neo4jVersion.Neo225)] RestTestHarness.Neo4jVersion version) { var initTransactionRequest = MockRequest.PostJson("/transaction", @"{ 'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}"); var rollbackTransactionRequest = MockRequest.Delete("/transaction/1"); using (var testHarness = new RestTestHarness { { initTransactionRequest, MockResponse.Json(201, TransactionRestResponseHelper.GenerateCypherErrorResponse(1, "{\"code\":\"Neo.ClientError.Schema.ConstraintViolation\",\"message\":\"Node 19572 already exists with label User and property.\"}"), "http://foo/db/data/transaction/1") }, { rollbackTransactionRequest, MockResponse.Json(404, "{\"results\":[],\"errors\":[{\"code\":\"Neo.ClientError.Transaction.UnknownId\",\"message\":\"Unrecognized transaction id. Transaction may have timed out and been rolled back.\"}]}") } }) { var client = testHarness.CreateGraphClient(version); client.Connect(); try { using (var transaction = client.BeginTransaction()) { client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResults(); } } catch (Exception ex) { Assert.That(ex.Message.Contains("404")); } } }
//https://github.com/Readify/Neo4jClient/issues/127 public void ReturnsCorrectError_WhenTransactionIsAutomaticallyRolledBack_ViaNeo4j_2_2_6_Plus([Values(RestTestHarness.Neo4jVersion.Neo226 /*, RestTestHarness.Neo4jVersion.Neo23*/)] RestTestHarness.Neo4jVersion version) { /* In 2.2.6 ClientErrors (Constraint Violations etc) were changed to Automatically rollback. This created a 404 error when *we* tried to rollback on an error, as the transaction no longer existed. */ var initTransactionRequest = MockRequest.PostJson("/transaction", @"{ 'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}"); var rollbackTransactionRequest = MockRequest.Delete("/transaction/1"); using (var testHarness = new RestTestHarness { { initTransactionRequest, MockResponse.Json(201, TransactionRestResponseHelper.GenerateCypherErrorResponse(1, "{\"code\":\"Neo.ClientError.Schema.ConstraintViolation\",\"message\":\"Node 19572 already exists with label User and property.\"}"), "http://foo/db/data/transaction/1") }, { rollbackTransactionRequest, MockResponse.Json(404, "{\"results\":[],\"errors\":[{\"code\":\"Neo.ClientError.Transaction.UnknownId\",\"message\":\"Unrecognized transaction id. Transaction may have timed out and been rolled back.\"}]}") } }) { var client = testHarness.CreateGraphClient(version); client.Connect(); using (var transaction = client.BeginTransaction()) { Assert.That(() => client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResults(), Throws.TypeOf <NeoException>()); } } }
public void JoinedTransactionsCommitAfterAllEmitVote() { using (var testHarness = new RestTestHarness()) { var client = testHarness.CreateAndConnectTransactionalGraphClient(); using (var tran = client.BeginTransaction()) { using (var tran2 = client.BeginTransaction()) { tran2.Commit(); } Assert.IsTrue(tran.IsOpen); using (var tran3 = client.BeginTransaction(TransactionScopeOption.Suppress)) { Assert.AreNotSame(GetRealTransaction(tran3), GetRealTransaction(tran)); Assert.IsFalse(client.InTransaction); } Assert.IsTrue(client.InTransaction); Assert.IsTrue(tran.IsOpen); tran.Commit(); Assert.IsFalse(tran.IsOpen); } Assert.IsFalse(client.InTransaction); } }
//https://github.com/Readify/Neo4jClient/issues/127 public void ReturnsThe404_WhenVersionIs_2_2_6_Plus_WhenActuallyTimingOut([Values(RestTestHarness.Neo4jVersion.Neo226, RestTestHarness.Neo4jVersion.Neo23)] RestTestHarness.Neo4jVersion version) { var initTransactionRequest = MockRequest.PostJson("/transaction", @"{ 'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}"); var rollbackTransactionRequest = MockRequest.Delete("/transaction/1"); using (var testHarness = new RestTestHarness() { { initTransactionRequest, MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1") }, { rollbackTransactionRequest, MockResponse.Json(404, "{\"results\":[],\"errors\":[{\"code\":\"Neo.ClientError.Transaction.UnknownId\",\"message\":\"Unrecognized transaction id. Transaction may have timed out and been rolled back.\"}]}") } }) { var client = testHarness.CreateGraphClient(version); client.Connect(); try { using (var transaction = client.BeginTransaction()) { client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResults(); } Assert.Fail("Should not reach this code, as there is an expected exception."); } catch (Exception ex) { Assert.That(ex.Message.Contains("404")); } } }
public void ShouldReturnEmptyEnumerableForNullResult() { //Arrange const string gremlinQueryExpected = "foo bar query"; var query = new GremlinApiQuery(gremlinQueryExpected, null); using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/ext/GremlinPlugin/graphdb/execute_script", query), MockResponse.Json(HttpStatusCode.OK, @"[]") } }) { var graphClient = (GraphClient)testHarness.CreateAndConnectGraphClient(); //Act var nodes = graphClient .ExecuteGetAllRelationshipsGremlin(gremlinQueryExpected, null) .ToList(); //Assert Assert.Equal(0, nodes.Count()); } }
public async Task SendsCommandWithCorrectTimeout() { const string queryText = "MATCH n SET n.Value = 'value'"; const int expectedMaxExecutionTime = 100; var cypherQuery = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Set, CypherResultFormat.DependsOnEnvironment, "neo4j", maxExecutionTime: expectedMaxExecutionTime); var transactionApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery) }; using (var testHarness = new RestTestHarness { { MockRequest.Get(""), MockResponse.NeoRoot20() }, { MockRequest.PostObjectAsJson("/transaction/commit", transactionApiQuery), MockResponse.Http((int)HttpStatusCode.OK) } }) { var httpClient = testHarness.GenerateHttpClient(testHarness.BaseUri); var graphClient = new GraphClient(new Uri(testHarness.BaseUri), httpClient); await graphClient.ConnectAsync(); httpClient.ClearReceivedCalls(); await((IRawGraphClient)graphClient).ExecuteCypherAsync(cypherQuery); var call = httpClient.ReceivedCalls().Single(); var requestMessage = (HttpRequestMessage)call.GetArguments()[0]; var maxExecutionTimeHeader = requestMessage.Headers.Single(h => h.Key == "max-execution-time"); Assert.Equal(expectedMaxExecutionTime.ToString(CultureInfo.InvariantCulture), maxExecutionTimeHeader.Value.Single()); } }
public void WhenExecuteCypherFails_ShouldRaiseCompletedWithException() { // Arrange const string queryText = @"bad cypher"; var parameters = new Dictionary <string, object>(); var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set); var cypherApiQuery = new CypherApiQuery(cypherQuery); using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/cypher", cypherApiQuery), MockResponse.Throws() } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); OperationCompletedEventArgs eventArgs = null; graphClient.OperationCompleted += (sender, e) => { eventArgs = e; }; //Act Assert.Throws <MockResponseThrowsException>(() => { graphClient.ExecuteCypher(cypherQuery); }, "We should expect an exception"); Assert.IsNotNull(eventArgs, "but we should also have received the completion event"); Assert.IsTrue(eventArgs.HasException); Assert.AreEqual(typeof(MockResponseThrowsException), eventArgs.Exception.GetType()); Assert.AreEqual(-1, eventArgs.ResourcesReturned); } }
public async Task DoesntSetHeaders_WhenNotSet() { const string queryText = "MATCH n SET n.Value = 'value'"; var cypherQuery = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Set, "neo4j"); var transactionApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery) }; using (var testHarness = new RestTestHarness { { MockRequest.Get(""), MockResponse.NeoRoot20() }, { MockRequest.PostObjectAsJson("/transaction/commit", transactionApiQuery), MockResponse.Http((int)HttpStatusCode.OK) } }) { var httpClient = testHarness.GenerateHttpClient(testHarness.BaseUri); var graphClient = new GraphClient(new Uri(testHarness.BaseUri), httpClient); await graphClient.ConnectAsync(); httpClient.ClearReceivedCalls(); await((IRawGraphClient)graphClient).ExecuteCypherAsync(cypherQuery); var call = httpClient.ReceivedCalls().Single(); var requestMessage = (HttpRequestMessage)call.GetArguments()[0]; Assert.False(requestMessage.Headers.Any(h => h.Key == "max-execution-time")); } }
public void ShouldSendCommandAndNotCareAboutResultsAsync() { // Arrange const string queryText = @"return 1"; var parameters = new Dictionary <string, object>(); var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set); var cypherApiQuery = new CypherApiQuery(cypherQuery); using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/cypher", cypherApiQuery), MockResponse.Http((int)HttpStatusCode.OK) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); bool raisedEvent = false; graphClient.OperationCompleted += (sender, e) => { raisedEvent = true; }; //Act var task = graphClient.ExecuteCypherAsync(cypherQuery); task.Wait(); Assert.IsTrue(raisedEvent, "Raised OperationCompleted"); } }
//https://github.com/Readify/Neo4jClient/issues/127 public void ReturnsThe404_WhenVersionIs_2_2_6_Plus_WhenActuallyTimingOut([Values(RestTestHarness.Neo4jVersion.Neo226, RestTestHarness.Neo4jVersion.Neo23)] RestTestHarness.Neo4jVersion version) { var initTransactionRequest = MockRequest.PostJson("/transaction", @"{ 'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}"); var rollbackTransactionRequest = MockRequest.Delete("/transaction/1"); using (var testHarness = new RestTestHarness() { { initTransactionRequest, MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1") }, { rollbackTransactionRequest, MockResponse.Json(404, "{\"results\":[],\"errors\":[{\"code\":\"Neo.ClientError.Transaction.UnknownId\",\"message\":\"Unrecognized transaction id. Transaction may have timed out and been rolled back.\"}]}") } }) { var client = testHarness.CreateGraphClient(version); client.Connect(); try { using (var transaction = client.BeginTransaction()) { client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResults(); } Assert.Fail("Should not reach this code, as there is an expected exception."); } catch (ApplicationException ex) { Assert.That(ex.Message.Contains("404")); } } }
public void GraphClientFactoryUseCase() { const string queryText = @"MATCH (d) RETURN d"; var cypherQuery = new CypherQuery(queryText, null, CypherResultMode.Set, CypherResultFormat.Rest); var cypherApiQuery = new CypherApiQuery(cypherQuery); using (var testHarness = new RestTestHarness { { MockRequest.Get("/"), MockResponse.NeoRoot() }, { MockRequest.PostObjectAsJson("/cypher", cypherApiQuery), new MockResponse { StatusCode = HttpStatusCode.OK } } }) { var httpClient = testHarness.GenerateHttpClient(testHarness.BaseUri); var executeConfiguration = new ExecutionConfiguration { HttpClient = httpClient, UserAgent = string.Format("Neo4jClient/{0}", typeof(NeoServerConfiguration).Assembly.GetName().Version), UseJsonStreaming = true, JsonConverters = GraphClient.DefaultJsonConverters }; var configuration = NeoServerConfiguration.GetConfiguration(new Uri(testHarness.BaseUri), null, null, executeConfiguration); var factory = new GraphClientFactory(configuration); using (var client = factory.Create(httpClient)) { client.Cypher.Match("(d)").Return<object>("d").ExecuteWithoutResults(); } } }
public async Task EmptyCollectionShouldDeserializeCorrectly() { const string queryText = @"RETURN [] AS p"; var cypherQuery = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Set, CypherResultFormat.Rest, "neo4j"); var cypherApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery) }; using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/transaction/commit", cypherApiQuery), MockResponse.Json(HttpStatusCode.OK, @"{'results': [{'columns' : [ 'p' ], 'data' : []}]}") } }) { var graphClient = await testHarness.CreateAndConnectGraphClient(); var results = (await graphClient .ExecuteGetCypherResultsAsync <PathsResult>(cypherQuery)) .ToArray(); Assert.Empty(results); } }
public void ShouldReturnNodeDataAndDeserializeToEnumType() { using (var testHarness = new RestTestHarness { { MockRequest.Get("/node/456"), MockResponse.Json(HttpStatusCode.OK, @"{ 'self': 'http://foo/db/data/node/456', 'data': { 'Foo': 'foo', 'Status': 'Value1' }, 'create_relationship': 'http://foo/db/data/node/456/relationships', 'all_relationships': 'http://foo/db/data/node/456/relationships/all', 'all_typed relationships': 'http://foo/db/data/node/456/relationships/all/{-list|&|types}', 'incoming_relationships': 'http://foo/db/data/node/456/relationships/in', 'incoming_typed relationships': 'http://foo/db/data/node/456/relationships/in/{-list|&|types}', 'outgoing_relationships': 'http://foo/db/data/node/456/relationships/out', 'outgoing_typed relationships': 'http://foo/db/data/node/456/relationships/out/{-list|&|types}', 'properties': 'http://foo/db/data/node/456/properties', 'property': 'http://foo/db/data/node/456/property/{key}', 'traverse': 'http://foo/db/data/node/456/traverse/{returnType}' }") } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); var node = graphClient.Get<TestNodeWithEnum>((NodeReference)456); Assert.AreEqual(456, node.Reference.Id); Assert.AreEqual("foo", node.Data.Foo); Assert.AreEqual(TestEnum.Value1, node.Data.Status); } }
public void ShouldThrowExceptionIfHttpCodeIsNot201( IndexFor indexFor, IndexProvider indexProvider, IndexType indexType, string createEndpoint, string createJson) { //Arrange using (var testHarness = new RestTestHarness { { MockRequest.PostJson(createEndpoint, createJson), MockResponse.Http(500) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); var indexConfiguration = new IndexConfiguration { Provider = indexProvider, Type = indexType }; Assert.Throws <Exception>(() => graphClient.CreateIndex("foo", indexConfiguration, indexFor)); } }
public async Task ShouldDeserializeSimpleTableStructure() { // Arrange const string queryText = @" START x = node($p0) MATCH x-[r]->n RETURN type(r) AS RelationshipType, n.Name? AS Name, n.UniqueId? AS UniqueId LIMIT 3"; var cypherQuery = new CypherQuery( queryText, new Dictionary <string, object> { { "p0", 123 } }, CypherResultMode.Projection, CypherResultFormat.Rest, "neo4j"); var cypherApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery) }; using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/transaction/commit", cypherApiQuery), MockResponse.Json(HttpStatusCode.OK, @"{ 'data' : [ [ 'HOSTS', 'foo', 44321 ], [ 'LIKES', 'bar', 44311 ], [ 'HOSTS', 'baz', 42586 ] ], 'columns' : [ 'RelationshipType', 'Name', 'UniqueId' ] }") } }) { var graphClient = await testHarness.CreateAndConnectGraphClient(); //Act var results = await graphClient.ExecuteGetCypherResultsAsync <SimpleResultDto>(cypherQuery); //Assert Assert.IsAssignableFrom <IEnumerable <SimpleResultDto> >(results); var resultsArray = results.ToArray(); Assert.Equal(3, resultsArray.Count()); var firstResult = resultsArray[0]; Assert.Equal("HOSTS", firstResult.RelationshipType); Assert.Equal("foo", firstResult.Name); Assert.Equal(44321, firstResult.UniqueId); var secondResult = resultsArray[1]; Assert.Equal("LIKES", secondResult.RelationshipType); Assert.Equal("bar", secondResult.Name); Assert.Equal(44311, secondResult.UniqueId); var thirdResult = resultsArray[2]; Assert.Equal("HOSTS", thirdResult.RelationshipType); Assert.Equal("baz", thirdResult.Name); Assert.Equal(42586, thirdResult.UniqueId); } }
public async Task ShouldDeserializePathsResultAsSetBased() { // Arrange const string queryText = @"START d=node($p0), e=node($p1) MATCH p = allShortestPaths( d-[*..15]-e ) RETURN p"; var parameters = new Dictionary <string, object> { { "p0", 215 }, { "p1", 219 } }; var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set, CypherResultFormat.Rest, "neo4j"); var cypherApiQuery = new CypherStatementList { new CypherTransactionStatement(cypherQuery) }; using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/transaction/commit", cypherApiQuery), MockResponse.Json(HttpStatusCode.OK, @"{ 'data' : [ [ { 'start' : 'http://foo/db/data/node/215', 'nodes' : [ 'http://foo/db/data/node/215', 'http://foo/db/data/node/0', 'http://foo/db/data/node/219' ], 'length' : 2, 'relationships' : [ 'http://foo/db/data/relationship/247', 'http://foo/db/data/relationship/257' ], 'end' : 'http://foo/db/data/node/219' } ], [ { 'start' : 'http://foo/db/data/node/215', 'nodes' : [ 'http://foo/db/data/node/215', 'http://foo/db/data/node/1', 'http://foo/db/data/node/219' ], 'length' : 2, 'relationships' : [ 'http://foo/db/data/relationship/248', 'http://foo/db/data/relationship/258' ], 'end' : 'http://foo/db/data/node/219' } ] ], 'columns' : [ 'p' ] }") } }) { var graphClient = await testHarness.CreateAndConnectGraphClient(); //Act var results = (await graphClient .ExecuteGetCypherResultsAsync <PathsResult>(cypherQuery)) .ToArray(); //Assert Assert.IsAssignableFrom <IEnumerable <PathsResult> >(results); Assert.Equal(results.First().Length, 2); Assert.Equal(results.First().Start, "http://foo/db/data/node/215"); Assert.Equal(results.First().End, "http://foo/db/data/node/219"); Assert.Equal(results.Skip(1).First().Length, 2); Assert.Equal(results.Skip(1).First().Start, "http://foo/db/data/node/215"); Assert.Equal(results.Skip(1).First().End, "http://foo/db/data/node/219"); } }
public void RootNodeShouldHaveReferenceBackToClient() { using (var testHarness = new RestTestHarness()) { var client = testHarness.CreateAndConnectGraphClient(); var rootNode = client.RootNode; Assert.AreEqual(client, ((IGremlinQuery) rootNode).Client); } }
public void BeginTransactionShouldFailWithLower20Versions() { using (var testHarness = new RestTestHarness()) { var client = testHarness.CreateGraphClient(false); client.Connect(); client.BeginTransaction(); } }
[Test] public void ShouldDeserializePathsResultAsSetBased() { // Arrange const string queryText = @"START d=node({p0}), e=node({p1}) MATCH p = allShortestPaths( d-[*..15]-e ) RETURN p"; var parameters = new Dictionary<string, object> { {"p0", 215}, {"p1", 219} }; var cypherQuery = new CypherQuery(queryText, parameters, CypherResultMode.Set, CypherResultFormat.Rest); var cypherApiQuery = new CypherApiQuery(cypherQuery); using (var testHarness = new RestTestHarness { { MockRequest.PostObjectAsJson("/cypher", cypherApiQuery), MockResponse.Json(HttpStatusCode.OK, @"{ 'data' : [ [ { 'start' : 'http://foo/db/data/node/215', 'nodes' : [ 'http://foo/db/data/node/215', 'http://foo/db/data/node/0', 'http://foo/db/data/node/219' ], 'length' : 2, 'relationships' : [ 'http://foo/db/data/relationship/247', 'http://foo/db/data/relationship/257' ], 'end' : 'http://foo/db/data/node/219' } ], [ { 'start' : 'http://foo/db/data/node/215', 'nodes' : [ 'http://foo/db/data/node/215', 'http://foo/db/data/node/1', 'http://foo/db/data/node/219' ], 'length' : 2, 'relationships' : [ 'http://foo/db/data/relationship/248', 'http://foo/db/data/relationship/258' ], 'end' : 'http://foo/db/data/node/219' } ] ], 'columns' : [ 'p' ] }") } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); //Act var results = graphClient .ExecuteGetCypherResults<PathsResult>(cypherQuery) .ToArray(); //Assert Assert.IsInstanceOf<IEnumerable<PathsResult>>(results); Assert.AreEqual(results.First().Length, 2); Assert.AreEqual(results.First().Start, "http://foo/db/data/node/215"); Assert.AreEqual(results.First().End, "http://foo/db/data/node/219"); Assert.AreEqual(results.Skip(1).First().Length, 2); Assert.AreEqual(results.Skip(1).First().Start, "http://foo/db/data/node/215"); Assert.AreEqual(results.Skip(1).First().End, "http://foo/db/data/node/219"); } }
public void BeginTransactionShouldFailWithLower20Versions() { using (var testHarness = new RestTestHarness()) { var client = testHarness.CreateGraphClient(RestTestHarness.Neo4jVersion.Neo19); client.Connect(); Assert.That(() => client.BeginTransaction(), Throws.TypeOf<NotSupportedException>()); } }
public void RootNodeShouldSupportGremlinQueries() { using (var testHarness = new RestTestHarness()) { var client = testHarness.CreateAndConnectGraphClient(); var rootNode = client.RootNode; Assert.AreEqual("g.v(p0)", ((IGremlinQuery) rootNode).QueryText); Assert.AreEqual(123, ((IGremlinQuery) rootNode).QueryParameters["p0"]); } }
public void RootNode_ShouldReturnReferenceNode() { using (var testHarness = new RestTestHarness()) { var graphClient = testHarness.CreateAndConnectGraphClient(); Assert.IsNotNull(graphClient.RootNode); Assert.AreEqual(123, graphClient.RootNode.Id); } }
public void ShouldParse15M02Version() { using (var testHarness = new RestTestHarness { { MockRequest.Get(""), MockResponse.NeoRoot() } }) { var graphClient = (GraphClient)testHarness.CreateAndConnectGraphClient(); Assert.AreEqual("1.5.0.2", graphClient.ServerVersion.ToString()); } }
public void ShouldRetrieveApiEndpoints() { using (var testHarness = new RestTestHarness()) { var graphClient = (GraphClient)testHarness.CreateAndConnectGraphClient(); Assert.AreEqual("/node", graphClient.RootApiResponse.Node); Assert.AreEqual("/index/node", graphClient.RootApiResponse.NodeIndex); Assert.AreEqual("/index/relationship", graphClient.RootApiResponse.RelationshipIndex); Assert.AreEqual("http://foo/db/data/node/123", graphClient.RootApiResponse.ReferenceNode); Assert.AreEqual("/ext", graphClient.RootApiResponse.ExtensionsInfo); } }
public void ShouldThrowConnectionExceptionFor500Response() { using (var testHarness = new RestTestHarness { { MockRequest.Get(""), MockResponse.Http(500) } }) { testHarness.CreateAndConnectGraphClient(); } }
public void ShouldThrowApplicationExceptionWhenDeleteFails() { using (var testHarness = new RestTestHarness { { MockRequest.Delete("/node/456"), MockResponse.Http(409) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); graphClient.Delete(456, DeleteMode.NodeOnly); } }
public void ShouldDeleteNodeOnly() { using (var testHarness = new RestTestHarness { { MockRequest.Delete("/node/456"), MockResponse.Http(204) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); graphClient.Delete(456, DeleteMode.NodeOnly); } }
public void ShouldThrowApplicationExceptionWhenDeleteFails() { using (var testHarness = new RestTestHarness { { MockRequest.Delete("/relationship/456"), MockResponse.Http(404) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); graphClient.DeleteRelationship(456); } }
public void ShouldDeleteRelationship() { using (var testHarness = new RestTestHarness { { MockRequest.Delete("/relationship/456"), MockResponse.Http(204) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); graphClient.DeleteRelationship(456); } }
public void ShouldUpdateNode() { var nodeToUpdate = new TestNode { Foo = "foo", Bar = "bar", Baz = "baz" }; using (var testHarness = new RestTestHarness { { MockRequest.Get("/node/456"), MockResponse.Json(HttpStatusCode.OK, @"{ 'self': 'http://foo/db/data/node/456', 'data': { 'Foo': 'foo', 'Bar': 'bar', 'Baz': 'baz' }, 'create_relationship': 'http://foo/db/data/node/456/relationships', 'all_relationships': 'http://foo/db/data/node/456/relationships/all', 'all_typed relationships': 'http://foo/db/data/node/456/relationships/all/{-list|&|types}', 'incoming_relationships': 'http://foo/db/data/node/456/relationships/in', 'incoming_typed relationships': 'http://foo/db/data/node/456/relationships/in/{-list|&|types}', 'outgoing_relationships': 'http://foo/db/data/node/456/relationships/out', 'outgoing_typed relationships': 'http://foo/db/data/node/456/relationships/out/{-list|&|types}', 'properties': 'http://foo/db/data/node/456/properties', 'property': 'http://foo/db/data/node/456/property/{key}', 'traverse': 'http://foo/db/data/node/456/traverse/{returnType}' }") }, { MockRequest.PutObjectAsJson("/node/456/properties", nodeToUpdate), MockResponse.Http((int)HttpStatusCode.NoContent) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); //Act var pocoReference = new NodeReference<TestNode>(456); graphClient.Update( pocoReference, nodeFromDb => { nodeFromDb.Foo = "fooUpdated"; nodeFromDb.Baz = "bazUpdated"; nodeToUpdate = nodeFromDb; } ); Assert.AreEqual("fooUpdated", nodeToUpdate.Foo); Assert.AreEqual("bazUpdated", nodeToUpdate.Baz); Assert.AreEqual("bar", nodeToUpdate.Bar); } }
public void ShouldThrowExceptionWhenDeleteFails() { using (var testHarness = new RestTestHarness { { MockRequest.Delete("/relationship/456"), MockResponse.Http(404) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); var ex = Assert.Throws<Exception>(() => graphClient.DeleteRelationship(456)); ex.Message.Should().Be("Unable to delete the relationship. The response status was: 404 NotFound"); } }
public void CurrentInternalTransaction_ReturnsNullWhenEmpty() { using (var testHarness = new RestTestHarness()) { var client = testHarness.CreateAndConnectTransactionalGraphClient(); client.Connect(); var tm = new Neo4jClient.Transactions.TransactionManager(client) { ScopedTransactions = new Stack<TransactionScopeProxy>() }; Assert.AreEqual(0, tm.ScopedTransactions.Count); Assert.IsNull(tm.CurrentInternalTransaction); } }
public void ShouldReturnEmptyDictionaryOfIndexesForHttpResponse204() { using (var testHarness = new RestTestHarness { { MockRequest.Get("/index/node"), MockResponse.Http(204) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); var indexes = graphClient.GetIndexes(IndexFor.Node); Assert.IsFalse(indexes.Any()); } }
public void ShouldThrowExceptionWhenDeleteFails() { using (var testHarness = new RestTestHarness { { MockRequest.Delete("/node/456"), MockResponse.Http(409) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); var ex = Assert.Throws<Exception>(() => graphClient.Delete(456, DeleteMode.NodeOnly)); ex.Message.Should().Be("Unable to delete the node. The node may still have relationships. The response status was: 409 Conflict"); } }
public void CannotJoinAfterClosedTransaction() { using (var testHarness = new RestTestHarness()) { var client = testHarness.CreateAndConnectTransactionalGraphClient(); using (var tran = client.BeginTransaction()) { tran.Commit(); Assert.IsFalse(tran.IsOpen); // should fail here Assert.That(() => client.BeginTransaction(), Throws.TypeOf<ClosedTransactionException>()); } } }
public void ShouldExecuteSilentlyForSuccessfulDelete() { using (var testHarness = new RestTestHarness { { MockRequest.Delete("/index/node/MyIndex"), MockResponse.Http(204) } }) { var graphClient = testHarness.CreateAndConnectGraphClient(); //Act graphClient.DeleteIndex("MyIndex", IndexFor.Node); } }