Example #1
0
        public async Task RollbackWithoutRequestsShouldNotGenerateMessage()
        {
            var initTransactionRequest     = MockRequest.PostJson("/transaction", @"{'statements': []}");
            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(200, @"{'results':[], 'errors':[] }")
                }
            }.ShouldNotBeCalled(initTransactionRequest, rollbackTransactionRequest))
            {
                var client = await testHarness.CreateAndConnectTransactionalGraphClient();

                using (var transaction = client.BeginTransaction())
                {
                    // no requests
                    await transaction.RollbackAsync();
                }
            }
        }
Example #2
0
        public void UpdateTransactionEndpointAfterFirstRequest()
        {
            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(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var transaction = client.BeginTransaction())
                {
                    // dummy query to generate request
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();

                    Assert.AreEqual(
                        new Uri("http://foo/db/data/transaction/1"),
                        ((INeo4jTransaction)((TransactionScopeProxy)transaction).TransactionContext).Endpoint);
                }
            }
        }
Example #3
0
        public void OnTransactionDisposeCallRollback()
        {
            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(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var transaction = client.BeginTransaction())
                {
                    // dummy query to generate request
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();
                }
            }
        }
                public async Task UsesTheSetDatabase()
                {
                    const string database = "neo4jclient";

                    var initTransactionRequest      = MockRequest.PostJson($"/db/{database}/tx", "{'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
                    var rollbackTransactionRequest  = MockRequest.Delete($"/db/{database}/tx/1");
                    var commitTransactionRequest    = MockRequest.PostJson($"/db/{database}/tx/1/commit", EmptyStatements);
                    var keepAliveTransactionRequest = MockRequest.PostJson($"/db/{database}/tx/1", EmptyStatements);

                    using (var testHarness = new RestTestHarness(false, "http://foo:7474")
                    {
                        {
                            initTransactionRequest,
                            MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), $"http://foo:7474/db/{database}/tx/1")
                        },
                        { commitTransactionRequest, EmptyOkResponse },
                        { rollbackTransactionRequest, EmptyOkResponse },
                        { keepAliveTransactionRequest, EmptyOkResponse }
                    })
                    {
                        var client = await testHarness.CreateAndConnectTransactionalGraphClient(RestTestHarness.Neo4jVersion.Neo40);

                        using (var transaction = client.BeginTransaction(TransactionScopeOption.Join, null, database))
                        {
                            // dummy query to generate request
                            await client.Cypher
                            .Match("n")
                            .Return(n => n.Count())
                            .ExecuteWithoutResultsAsync().ConfigureAwait(false);

                            await transaction.KeepAliveAsync();
                        }
                    }
                }
        //https://github.com/Readify/Neo4jClient/issues/127
        public async Task ReturnsThe404_WhenVersionIs_2_2_6_Plus_WhenActuallyTimingOut(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);
                await client.ConnectAsync();

                try
                {
                    using (var transaction = client.BeginTransaction())
                    {
                        await client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResultsAsync();
                    }
                    throw new Exception("Should not reach this code, as there is an expected exception.");
                }
                catch (Exception ex)
                {
                    Assert.True(ex.Message.Contains("404"));
                }
            }
        }
        //https://github.com/Readify/Neo4jClient/issues/127
        public async Task ReturnsCorrectError_WhenTransactionIsAutomaticallyRolledBack_ViaNeo4j_2_2_6_Plus(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);
                await client.ConnectAsync();

                using (var transaction = client.BeginTransaction())
                {
                    await Assert.ThrowsAsync <NeoException>(async() => await client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResultsAsync());
                }
            }
        }
        public void TransactionRollbackInTransactionScope()
        {
            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var deleteRequest          = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    deleteRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var scope = new TransactionScope())
                {
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();
                }
            }
        }
        //https://github.com/Readify/Neo4jClient/issues/127
        public async Task ReturnsThe404_WhenVersionIsLessThan_2_2_6(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);
                await client.ConnectAsync();

                try
                {
                    using (var transaction = client.BeginTransaction())
                    {
                        await client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResultsAsync();
                    }
                }
                catch (Exception ex)
                {
                    Assert.True(ex.Message.Contains("404"));
                }
            }
        }
Example #9
0
        public void NestedTransactionMixedBetweenTransactionScopeAndBeginTransaction()
        {
            const string queryText      = @"MATCH (n) RETURN count(n)";
            const string resultColumn   = @"{'columns':['count(n)'], 'data':[{'row':[1]}]}";
            var          cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Projection);
            var          cypherApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery, false)
            };
            var deleteRequest = MockRequest.Delete("/transaction/1");
            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':[] }")
                },
                {
                    deleteRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            }.ShouldNotBeCalled(commitRequest))
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var parentTx = client.BeginTransaction())
                {
                    using (var msTransaction = new TransactionScope())
                    {
                        Assert.IsTrue(client.InTransaction);

                        using (var tx = client.BeginTransaction())
                        {
                            long total = client.Cypher
                                         .Match("(n)")
                                         .Return(n => n.Count())
                                         .Results
                                         .SingleOrDefault();

                            Assert.AreEqual(1, total);

                            // should not be called
                            tx.Commit();
                        }

                        msTransaction.Complete();
                    }
                }

                Assert.IsFalse(client.InTransaction);
            }
        }
Example #10
0
        public void SuppressTransactionScopeShouldNotEmitTransactionalQuery()
        {
            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");

            var nonTransactionalRequest = MockRequest.PostJson("/cypher", @"{'query': 'MATCH n\r\nRETURN count(n)', 'params': {}}");

            var commitTransactionRequest = MockRequest.PostJson("/transaction/1/commit", @"{
                'statements': []}");
            var deleteRequest            = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    commitTransactionRequest,
                    MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                },
                {
                    nonTransactionalRequest,
                    MockResponse.Json(200, @"{'columns':['count(n)'], 'data':[[0]] }")
                },
                {
                    deleteRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            }.ShouldNotBeCalled(deleteRequest))
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var tran = new TransactionScope())
                {
                    using (var tran2 = new TransactionScope(TransactionScopeOption.Suppress))
                    {
                        client.Cypher
                        .Match("n")
                        .Return(n => n.Count())
                        .ExecuteWithoutResults();

                        // no rollback should be generated
                    }

                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();

                    tran.Complete();
                }
            }
        }
Example #11
0
 public void ShouldDeleteNodeOnly()
 {
     using (var testHarness = new RestTestHarness
     {
         {
             MockRequest.Delete("/node/456"),
             MockResponse.Http(204)
         }
     })
     {
         var graphClient = testHarness.CreateAndConnectGraphClient();
         graphClient.Delete(456, DeleteMode.NodeOnly);
     }
 }
Example #12
0
 public void ShouldThrowApplicationExceptionWhenDeleteFails()
 {
     using (var testHarness = new RestTestHarness
     {
         {
             MockRequest.Delete("/relationship/456"),
             MockResponse.Http(404)
         }
     })
     {
         var graphClient = testHarness.CreateAndConnectGraphClient();
         graphClient.DeleteRelationship(456);
     }
 }
Example #13
0
 public void ShouldThrowApplicationExceptionWhenDeleteFails()
 {
     using (var testHarness = new RestTestHarness
     {
         {
             MockRequest.Delete("/node/456"),
             MockResponse.Http(409)
         }
     })
     {
         var graphClient = testHarness.CreateAndConnectGraphClient();
         graphClient.Delete(456, DeleteMode.NodeOnly);
     }
 }
Example #14
0
 public void ShouldDeleteRelationship()
 {
     using (var testHarness = new RestTestHarness
     {
         {
             MockRequest.Delete("/relationship/456"),
             MockResponse.Http(204)
         }
     })
     {
         var graphClient = testHarness.CreateAndConnectGraphClient();
         graphClient.DeleteRelationship(456);
     }
 }
Example #15
0
 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 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");
     }
 }
Example #17
0
        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);
            }
        }
Example #18
0
        public void NestedJoinedTransactionScope()
        {
            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var secondRequest          = MockRequest.PostJson("/transaction/1", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var deleteRequest          = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    secondRequest,
                    MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                },
                {
                    deleteRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var scope = new TransactionScope())
                {
                    using (var scope2 = new TransactionScope())
                    {
                        client.Cypher
                        .Match("n")
                        .Return(n => n.Count())
                        .ExecuteWithoutResults();

                        // this will not commit
                        scope2.Complete();
                    }

                    // this should generate a request to the known transaction ID
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();
                }
            }
        }
        public void ShouldPreserveSlashInRelationshipIndexValue()
        {
            //Arrange
            var indexKeyValues = new Dictionary <string, object>
            {
                { "BarKey", "abc/def" }
            };
            var indexEntries = new List <IndexEntry>
            {
                new IndexEntry
                {
                    Name      = "my_relationships",
                    KeyValues = indexKeyValues,
                }
            };

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/index/relationship/my_relationships",
                                                 new
                    {
                        key = "BarKey",
                        value = "abc/def",
                        uri = "http://foo/db/data/relationship/123"
                    }),
                    MockResponse.Json(HttpStatusCode.Created,
                                      @"Location: http://foo/db/data/index/relationship/my_relationships/BarKey/abc-def/1234")
                },
                {
                    MockRequest.Delete("/index/relationship/my_relationships/123"),
                    MockResponse.Http((int)HttpStatusCode.NoContent)
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                //Act
                var relReference = new RelationshipReference(123);
                graphClient.ReIndex(relReference, indexEntries);

                // Assert
                Assert.Pass("Success.");
            }
        }
Example #20
0
 public void ShouldDeleteAllRelationshipsFirst()
 {
     using (var testHarness = new RestTestHarness
     {
         {
             MockRequest.Get("/node/456/relationships/all"),
             MockResponse.Json(HttpStatusCode.OK,
                               @"[
                   { 'self': 'http://foo/db/data/relationship/56',
                     'start': 'http://foo/db/data/node/123',
                     'end': 'http://foo/db/data/node/456',
                     'type': 'KNOWS',
                     'properties': 'http://foo/db/data/relationship/56/properties',
                     'property': 'http://foo/db/data/relationship/56/properties/{key}',
                     'data': { 'date': 1270559208258 }
                   },
                   { 'self': 'http://foo/db/data/relationship/78',
                     'start': 'http://foo/db/data/node/456',
                     'end': 'http://foo/db/data/node/789',
                     'type': 'KNOWS',
                     'properties': 'http://foo/db/data/relationship/78/properties',
                     'property': 'http://foo/db/data/relationship/78/properties/{key}',
                     'data': { 'date': 1270559208258 }
                   }
                 ]")
         },
         {
             MockRequest.Delete("/relationship/56"),
             MockResponse.Http(204)
         },
         {
             MockRequest.Delete("/relationship/78"),
             MockResponse.Http(204)
         },
         {
             MockRequest.Delete("/node/456"),
             MockResponse.Http(204)
         }
     })
     {
         var graphClient = testHarness.CreateAndConnectGraphClient();
         graphClient.Delete(456, DeleteMode.NodeAndRelationships);
     }
 }
        public void ShouldAcceptQuestionMarkInIndexValue()
        {
            //Arrange
            var indexKeyValues = new Dictionary <string, object>
            {
                { "FooKey", "foo?bar" }
            };
            var indexEntries = new List <IndexEntry>
            {
                new IndexEntry
                {
                    Name      = "my_nodes",
                    KeyValues = indexKeyValues,
                }
            };

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/index/node/my_nodes",
                                                 new
                    {
                        key = "FooKey",
                        value = "foo?bar",
                        uri = "http://foo/db/data/node/123"
                    }),
                    MockResponse.Json(HttpStatusCode.Created,
                                      @"Location: http://foo/db/data/index/node/my_nodes/FooKey/%3f/123")
                },
                {
                    MockRequest.Delete("/index/node/my_nodes/123"),
                    MockResponse.Http((int)HttpStatusCode.NoContent)
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                //Act
                graphClient.ReIndex((NodeReference)123, indexEntries);

                // Assert
                Assert.Pass("Success.");
            }
        }
        public void ShouldReindexRelationshipWithDateTimeOffsetIndexEntry()
        {
            //Arrange
            var indexEntries = new List <IndexEntry>
            {
                new IndexEntry
                {
                    Name      = "my_relationships",
                    KeyValues = new Dictionary <string, object>
                    {
                        { "BarKey", new DateTimeOffset(1000, new TimeSpan(0)) }
                    },
                }
            };

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/index/relationship/my_relationships",
                                                 new
                    {
                        key = "BarKey",
                        value = "1000",
                        uri = "http://foo/db/data/relationship/1234"
                    }),
                    MockResponse.Json(HttpStatusCode.Created,
                                      @"Location: http://foo/db/data/index/relationship/my_relationships/BarKey/someDateValue/1234")
                },
                {
                    MockRequest.Delete("/index/relationship/my_relationships/1234"),
                    MockResponse.Http((int)HttpStatusCode.NoContent)
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                //Act
                var relReference = new RelationshipReference(1234);
                graphClient.ReIndex(relReference, indexEntries);

                // Assert
                Assert.Pass("Success.");
            }
        }
Example #23
0
        public async Task DeserializeResultsFromTransaction()
        {
            var initTransactionRequest     = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var deserializationRequest     = MockRequest.PostJson("/transaction/1", @"{
                '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")
                },
                {
                    deserializationRequest,
                    MockResponse.Json(200, @"{'results':[{'columns': ['count(n)'], 'data': [{'row': [0]}]}]}")
                },
                {
                    rollbackTransactionRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = await testHarness.CreateAndConnectTransactionalGraphClient();

                using (var transaction = client.BeginTransaction())
                {
                    // dummy query to generate request
                    await client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResultsAsync();

                    // this query will hit the deserializer
                    var count = await client.Cypher
                                .Match("n")
                                .Return(n => n.Count())
                                .ResultsAsync;

                    Assert.Equal(count.First(), 0);
                }
            }
        }
        public void ShouldReindexRelationshipWithIndexEntryContainingSpace()
        {
            //Arrange
            var indexEntries = new List <IndexEntry>
            {
                new IndexEntry
                {
                    Name      = "my_relationships",
                    KeyValues = new Dictionary <string, object>
                    {
                        { "BarKey", "the_value with space" }
                    },
                }
            };

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/index/relationship/my_relationships",
                                                 new
                    {
                        key = "BarKey",
                        value = "the_value with space",
                        uri = "http://foo/db/data/relationship/1234"
                    }),
                    MockResponse.Json(HttpStatusCode.Created,
                                      @"Location: http://foo/db/data/index/relationship/my_relationships/BarKey/the_value%20with%20space/1234")
                },
                {
                    MockRequest.Delete("/index/relationship/my_relationships/1234"),
                    MockResponse.Http((int)HttpStatusCode.NoContent)
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                //Act
                var relReference = new RelationshipReference(1234);
                graphClient.ReIndex(relReference, indexEntries);

                // Assert
            }
        }
        public void ShouldReindexNodeWithDateTimeOffsetIndexEntry()
        {
            //Arrange
            var indexEntries = new List <IndexEntry>
            {
                new IndexEntry
                {
                    Name      = "my_nodes",
                    KeyValues = new Dictionary <string, object>
                    {
                        { "FooKey", new DateTimeOffset(1000, new TimeSpan(0)) }
                    },
                }
            };

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/index/node/my_nodes",
                                                 new
                    {
                        key = "FooKey",
                        value = "1000",
                        uri = "http://foo/db/data/node/123"
                    }),
                    MockResponse.Json(HttpStatusCode.Created,
                                      @"Location: http://foo/db/data/index/node/my_nodes/FooKey/someDateValue/123")
                },
                {
                    MockRequest.Delete("/index/node/my_nodes/123"),
                    MockResponse.Http((int)HttpStatusCode.NoContent)
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                //Act
                graphClient.ReIndex((NodeReference)123, indexEntries);

                // Assert
            }
        }
        public void ShouldReplaceNodeWithIndexEntries()
        {
            var newData = new TestNode {
                Foo = "foo", Bar = "bar", Baz = "baz"
            };

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PutObjectAsJson("/node/456/properties", newData),
                    MockResponse.Http((int)HttpStatusCode.NoContent)
                },
                {
                    MockRequest.Delete("/index/node/foo/456"),
                    MockResponse.Http((int)HttpStatusCode.NoContent)
                },
                {
                    MockRequest.PostObjectAsJson("/index/node/foo", new { key = "foo", value = "bar", uri = "http://foo/db/data/node/456" }),
                    MockResponse.Json(HttpStatusCode.Created, "Location: http://foo/db/data/index/node/foo/bar/456")
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                // Act
                var pocoReference = new NodeReference <TestNode>(456);
                graphClient.Update(
                    pocoReference,
                    newData,
                    new []
                {
                    new IndexEntry
                    {
                        Name      = "foo",
                        KeyValues = new Dictionary <string, object> {
                            { "foo", "bar" }
                        },
                    }
                });
            }
        }
        public void ShouldUpdateNodeWithIndexEntries()
        {
            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)
                },
                {
                    MockRequest.Delete("/index/node/foo/456"),
                    MockResponse.Http((int)HttpStatusCode.NoContent)
                },
                {
                    MockRequest.PostObjectAsJson("/index/node/foo", new { key = "foo", value = "bar", uri = "http://foo/db/data/node/456" }),
                    MockResponse.Json(HttpStatusCode.Created, "Location: http://foo/db/data/index/node/foo/bar/456")
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                // Act
                var pocoReference = new NodeReference <TestNode>(456);
                graphClient.Update(
                    pocoReference, nodeFromDb =>
                {
                    nodeFromDb.Foo = "fooUpdated";
                    nodeFromDb.Baz = "bazUpdated";
                    nodeToUpdate   = nodeFromDb;
                }, nodeFromDb => new List <IndexEntry>
                {
                    new IndexEntry
                    {
                        Name      = "foo",
                        KeyValues = new Dictionary <string, object> {
                            { "foo", "bar" }
                        },
                    }
                });

                Assert.AreEqual("fooUpdated", nodeToUpdate.Foo);
                Assert.AreEqual("bazUpdated", nodeToUpdate.Baz);
                Assert.AreEqual("bar", nodeToUpdate.Bar);
            }
        }