Пример #1
0
        public void EmptyCollectionShouldDeserializeCorrectly()
        {
            const string queryText = @"RETURN [] AS p";

            var cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Set, CypherResultFormat.Rest);
            var cypherApiQuery = new CypherApiQuery(cypherQuery);

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/cypher", cypherApiQuery),
                    MockResponse.Json(HttpStatusCode.OK,
                                      @"{'columns' : [ 'p' ], 'data' : [[  ]]}")
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                var results = graphClient
                              .ExecuteGetCypherResults <PathsResult>(cypherQuery)
                              .ToArray();

                Assert.Empty(results);
            }
        }
Пример #2
0
        public void WhenAsyncCommandFails_ShouldNotRaiseCompleted()
        {
            // 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.Throws()
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                bool raisedEvent = false;

                graphClient.OperationCompleted += (sender, e) => { raisedEvent = true; };

                //Act
                var task = graphClient.ExecuteCypherAsync(cypherQuery)
                           .ContinueWith(t =>
                {
                    Assert.True(t.IsFaulted);
                    Assert.IsAssignableFrom <MockResponseThrowsException>(t.Exception.Flatten().InnerException);
                });
                task.Wait();

                Assert.False(raisedEvent, "Raised OperationCompleted");
            }
        }
Пример #3
0
        public void CommitFailsOnPendingAsyncRequests()
        {
            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)
            };

            using (var testHarness = new RestTestHarness(false)
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                }
            })
            {
                var client    = testHarness.CreateAndConnectTransactionalGraphClient();
                var rawClient = (IRawGraphClient)client;
                using (var tran = client.BeginTransaction())
                {
                    rawClient.ExecuteGetCypherResultsAsync <DummyTotal>(cypherQuery);
                    tran.Commit();
                }
            }
        }
Пример #4
0
        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 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);
                }
            }
        }
Пример #6
0
        public void 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, maxExecutionTime: expectedMaxExecutionTime);
            var cypherApiQuery = new CypherApiQuery(cypherQuery);

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.Get(""),
                    MockResponse.NeoRoot()
                },
                {
                    MockRequest.PostObjectAsJson("/cypher", cypherApiQuery),
                    MockResponse.Http((int)HttpStatusCode.OK)
                }
            })
            {
                var httpClient  = testHarness.GenerateHttpClient(testHarness.BaseUri);
                var graphClient = new GraphClient(new Uri(testHarness.BaseUri), httpClient);
                graphClient.Connect();

                httpClient.ClearReceivedCalls();
                ((IRawGraphClient)graphClient).ExecuteCypher(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());
            }
        }
Пример #7
0
        public async Task CommitFailsOnPendingAsyncRequests()
        {
            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, "neo4j");
            var cypherApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery)
            };

            using (var testHarness = new RestTestHarness(false)
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                }
            })
            {
                var client = await testHarness.CreateAndConnectTransactionalGraphClient();

                var rawClient = (IRawGraphClient)client;
                using (var tran = client.BeginTransaction())
                {
                    await rawClient.ExecuteGetCypherResultsAsync <DummyTotal>(cypherQuery);

                    var ex = await Assert.ThrowsAsync <InvalidOperationException>(async() => await tran.CommitAsync());

                    Assert.Equal("Cannot commit unless all tasks have been completed", ex.Message);
                }
            }
        }
Пример #8
0
        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.True(raisedEvent, "Raised OperationCompleted");
            }
        }
        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());
            }
        }
Пример #10
0
        public void DoesntSetHeaders_WhenNotSet()
        {
            const string queryText = "MATCH n SET n.Value = 'value'";

            var cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Set);
            var cypherApiQuery = new CypherApiQuery(cypherQuery);

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.Get(""),
                    MockResponse.NeoRoot()
                },
                {
                    MockRequest.PostObjectAsJson("/cypher", cypherApiQuery),
                    MockResponse.Http((int)HttpStatusCode.OK)
                }
            })
            {
                var httpClient  = testHarness.GenerateHttpClient(testHarness.BaseUri);
                var graphClient = new GraphClient(new Uri(testHarness.BaseUri), httpClient);
                graphClient.Connect();

                httpClient.ClearReceivedCalls();
                ((IRawGraphClient)graphClient).ExecuteCypher(cypherQuery);

                var call           = httpClient.ReceivedCalls().Single();
                var requestMessage = (HttpRequestMessage)call.GetArguments()[0];
                Assert.False(requestMessage.Headers.Any(h => h.Key == "max-execution-time"));
            }
        }
Пример #11
0
        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();
                }
            }
        }
Пример #12
0
        public async Task DoesntSetMaxExecutionTime_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"));
            }
        }
Пример #13
0
        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);
            }
        }
Пример #14
0
        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);
            }
        }
Пример #15
0
        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");
            }
        }
Пример #16
0
        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, CypherResultFormat.Rest);
            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);
            }
        }
Пример #17
0
        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); });

                Assert.NotNull(eventArgs);
                Assert.True(eventArgs.HasException);
                Assert.Equal(typeof(MockResponseThrowsException), eventArgs.Exception.GetType());
                Assert.Equal(-1, eventArgs.ResourcesReturned);
            }
        }
Пример #18
0
        public void WhenExecuteGetCypherResultsFails_ShouldRaiseCompletedWithException()
        {
            // 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.Throws()
                }
            })
            {
                var graphClient = testHarness.CreateAndConnectGraphClient();

                OperationCompletedEventArgs eventArgs = null;

                graphClient.OperationCompleted += (sender, e) => { eventArgs = e; };

                //Act
                Assert.Throws <MockResponseThrowsException>(() =>
                {
                    graphClient.ExecuteGetCypherResults <ExecuteGetCypherResultsTests.SimpleResultDto>(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);
            }
        }
Пример #19
0
        public void SendsCommandWithCorrectTimeout()
        {
            const int expectedMaxExecutionTime = 100;

            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.Transactional, maxExecutionTime: expectedMaxExecutionTime);
            var cypherApiQuery = new CypherApiQuery(cypherQuery);

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.Get(""),
                    MockResponse.NeoRoot()
                },
                {
                    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 httpClient  = testHarness.GenerateHttpClient(testHarness.BaseUri);
                var graphClient = new GraphClient(new Uri(testHarness.BaseUri), httpClient);
                graphClient.Connect();

                httpClient.ClearReceivedCalls();
                ((IRawGraphClient)graphClient).ExecuteGetCypherResults <object>(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());
            }
        }
Пример #20
0
        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");
            }
        }
Пример #21
0
        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);
            }
        }
Пример #22
0
        public async Task DoesntSendMaxExecutionTime_WhenNotAddedToQuery()
        {
            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, "neo4j");
            var cypherApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery)
            };

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.Get(""),
                    MockResponse.NeoRoot20()
                },
                {
                    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 httpClient  = testHarness.GenerateHttpClient(testHarness.BaseUri);
                var graphClient = new GraphClient(new Uri(testHarness.BaseUri), httpClient);
                await graphClient.ConnectAsync();

                httpClient.ClearReceivedCalls();
                await((IRawGraphClient)graphClient).ExecuteGetCypherResultsAsync <object>(cypherQuery);

                var call           = httpClient.ReceivedCalls().Single();
                var requestMessage = (HttpRequestMessage)call.GetArguments()[0];
                Assert.False(requestMessage.Headers.Any(h => h.Key == "max-execution-time"));
            }
        }
Пример #23
0
        [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);
            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");
            }
        }
Пример #24
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);
            }
        }
Пример #25
0
        public void ShouldNotThrowANotSupportedExceptionForPre15M02DatabaseWhenThereAreNoIndexEntries()
        {
            var testNode = new TestNode {
                Foo = "foo", Bar = "bar", Baz = "baz"
            };
            var batch = new List <BatchStep>();

            batch.Add(HttpMethod.Post, "/node", testNode);

            var testHarness = new RestTestHarness
            {
                {
                    MockRequest.Get(""),
                    MockResponse.NeoRootPre15M02()
                },
                {
                    MockRequest.PostObjectAsJson("/batch", batch),
                    MockResponse.Json(HttpStatusCode.OK,
                                      @"[{'id':0,'location':'http://foo/db/data/node/760','body':{
                          'outgoing_relationships' : 'http://foo/db/data/node/760/relationships/out',
                          'data' : {
                            'Foo' : 'foo',
                            'Bar' : 'bar',
                            'Baz' : 'baz'
                          },
                          'traverse' : 'http://foo/db/data/node/760/traverse/{returnType}',
                          'all_typed_relationships' : 'http://foo/db/data/node/760/relationships/all/{-list|&|types}',
                          'self' : 'http://foo/db/data/node/760',
                          'property' : 'http://foo/db/data/node/760/properties/{key}',
                          'outgoing_typed_relationships' : 'http://foo/db/data/node/760/relationships/out/{-list|&|types}',
                          'properties' : 'http://foo/db/data/node/760/properties',
                          'incoming_relationships' : 'http://foo/db/data/node/760/relationships/in',
                          'extensions' : {
                          },
                          'create_relationship' : 'http://foo/db/data/node/760/relationships',
                          'paged_traverse' : 'http://foo/db/data/node/760/paged/traverse/{returnType}{?pageSize,leaseTime}',
                          'all_relationships' : 'http://foo/db/data/node/760/relationships/all',
                          'incoming_typed_relationships' : 'http://foo/db/data/node/760/relationships/in/{-list|&|types}'
                        },'from':'/node'}]"
                                      )
                }
            };

            var graphClient = testHarness.CreateAndConnectGraphClient();

            graphClient.Create(testNode, null, null);

            testHarness.AssertRequestConstraintsAreMet();
        }
Пример #26
0
        public async Task ShouldPromoteBadQueryResponseToNiceException()
        {
            // Arrange
            const string queryText      = @"broken query";
            var          cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), 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.BadRequest, @"{
  'message' : 'expected START or CREATE\n\'bad query\'\n ^',
  'exception' : 'SyntaxException',
  'fullname' : 'org.neo4j.cypher.SyntaxException',
  'stacktrace' : [ 'org.neo4j.cypher.internal.parser.v1_9.CypherParserImpl.parse(CypherParserImpl.scala:45)', 'org.neo4j.cypher.CypherParser.parse(CypherParser.scala:44)', 'org.neo4j.cypher.ExecutionEngine$$anonfun$prepare$1.apply(ExecutionEngine.scala:80)', 'org.neo4j.cypher.ExecutionEngine$$anonfun$prepare$1.apply(ExecutionEngine.scala:80)', 'org.neo4j.cypher.internal.LRUCache.getOrElseUpdate(LRUCache.scala:37)', 'org.neo4j.cypher.ExecutionEngine.prepare(ExecutionEngine.scala:80)', 'org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:72)', 'org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:76)', 'org.neo4j.cypher.javacompat.ExecutionEngine.execute(ExecutionEngine.java:79)', 'org.neo4j.server.rest.web.CypherService.cypher(CypherService.java:94)', 'java.lang.reflect.Method.invoke(Unknown Source)', 'org.neo4j.server.rest.security.SecurityFilter.doFilter(SecurityFilter.java:112)' ]
}")
                }
            })
            {
                var graphClient = await testHarness.CreateAndConnectGraphClient();

                var ex = await Assert.ThrowsAsync <NeoException>(async() => await graphClient.ExecuteGetCypherResultsAsync <ResultWithRelationshipDto>(cypherQuery));

                Assert.Equal("SyntaxException: expected START or CREATE\n'bad query'\n ^", ex.Message);
                Assert.Equal("expected START or CREATE\n'bad query'\n ^", ex.NeoMessage);
                Assert.Equal("SyntaxException", ex.NeoExceptionName);
                Assert.Equal("org.neo4j.cypher.SyntaxException", ex.NeoFullName);

                var expectedStack = new[]
                {
                    "org.neo4j.cypher.internal.parser.v1_9.CypherParserImpl.parse(CypherParserImpl.scala:45)",
                    "org.neo4j.cypher.CypherParser.parse(CypherParser.scala:44)",
                    "org.neo4j.cypher.ExecutionEngine$$anonfun$prepare$1.apply(ExecutionEngine.scala:80)",
                    "org.neo4j.cypher.ExecutionEngine$$anonfun$prepare$1.apply(ExecutionEngine.scala:80)",
                    "org.neo4j.cypher.internal.LRUCache.getOrElseUpdate(LRUCache.scala:37)",
                    "org.neo4j.cypher.ExecutionEngine.prepare(ExecutionEngine.scala:80)",
                    "org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:72)",
                    "org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:76)",
                    "org.neo4j.cypher.javacompat.ExecutionEngine.execute(ExecutionEngine.java:79)",
                    "org.neo4j.server.rest.web.CypherService.cypher(CypherService.java:94)",
                    "java.lang.reflect.Method.invoke(Unknown Source)",
                    "org.neo4j.server.rest.security.SecurityFilter.doFilter(SecurityFilter.java:112)"
                };
                Assert.Equal(expectedStack, ex.NeoStackTrace);
            }
        }
Пример #27
0
        public void TestTransactionScopeWithComplexDeserialization_WithCulture()
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("nb-NO");

            const string queryText      = @"MATCH (dt:DummyTotal) RETURN dt";
            const string resultColumn   = @"{'columns':['dt'],'data':[{'row':[{'date':'2015-07-27T22:30:35Z'}]}]}";
            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();
                client.JsonContractResolver = new CamelCasePropertyNamesContractResolver();
                using (var msTransaction = new TransactionScope())
                {
                    Assert.IsTrue(client.InTransaction);

                    var query = client.Cypher.Match("(dt:DummyTotal)")
                                .Return(dt => dt.As <DateHolder>());

                    var eResults = query.Results;
                    var results  = eResults.ToList();

                    Assert.AreEqual(1, results.Count);
                    var date = results.First().Date;

                    Assert.AreEqual(date.Kind, DateTimeKind.Utc);
                    Assert.AreEqual(new DateTime(2015, 7, 27, 22, 30, 35), results.First().Date);

                    msTransaction.Complete();
                }

                Assert.IsFalse(client.InTransaction);
            }
        }
Пример #28
0
        public void ShouldReturnReferenceToCreatedNodeWithLongId()
        {
            var testNode = new TestNode {
                Foo = "foo", Bar = "bar", Baz = "baz"
            };
            var batch = new List <BatchStep>();

            batch.Add(HttpMethod.Post, "/node", testNode);

            var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/batch", batch),
                    MockResponse.Json(HttpStatusCode.OK,
                                      @"[{'id':0,'location':'http://foo/db/data/node/2157483647','body':{
                          'outgoing_relationships' : 'http://foo/db/data/node/2157483647/relationships/out',
                          'data' : {
                            'Foo' : 'foo',
                            'Bar' : 'bar',
                            'Baz' : 'baz'
                          },
                          'traverse' : 'http://foo/db/data/node/2157483647/traverse/{returnType}',
                          'all_typed_relationships' : 'http://foo/db/data/node/2157483647/relationships/all/{-list|&|types}',
                          'self' : 'http://foo/db/data/node/2157483647',
                          'property' : 'http://foo/db/data/node/2157483647/properties/{key}',
                          'outgoing_typed_relationships' : 'http://foo/db/data/node/2157483647/relationships/out/{-list|&|types}',
                          'properties' : 'http://foo/db/data/node/2157483647/properties',
                          'incoming_relationships' : 'http://foo/db/data/node/2157483647/relationships/in',
                          'extensions' : {
                          },
                          'create_relationship' : 'http://foo/db/data/node/2157483647/relationships',
                          'paged_traverse' : 'http://foo/db/data/node/2157483647/paged/traverse/{returnType}{?pageSize,leaseTime}',
                          'all_relationships' : 'http://foo/db/data/node/2157483647/relationships/all',
                          'incoming_typed_relationships' : 'http://foo/db/data/node/2157483647/relationships/in/{-list|&|types}'
                        },'from':'/node'}]"
                                      )
                }
            };

            var graphClient = testHarness.CreateAndConnectGraphClient();

            var node = graphClient.Create(testNode);

            Assert.AreEqual(2157483647, node.Id);
            testHarness.AssertRequestConstraintsAreMet();
        }
        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.");
            }
        }
        public void ShouldReturnListOfRelationshipInstancesWithPayloads()
        {
            //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, @"[ {
                          'start' : 'http://127.0.0.1:5118/db/data/node/123',
                          'data' : {
                            'Foo': 'Foo',
                            'Bar': 'Bar'
                          },
                          'self' : 'http://127.0.0.1:5118/db/data/relationship/456',
                          'property' : 'http://127.0.0.1:5118/db/data/relationship/456/properties/{key}',
                          'properties' : 'http://127.0.0.1:5118/db/data/relationship/456/properties',
                          'type' : 'KNOWS',
                          'extensions' : {
                          },
                          'end' : 'http://127.0.0.1:5118/db/data/node/789'
                        } ]")
                }
            })
            {
                var graphClient = (GraphClient)testHarness.CreateAndConnectGraphClient();

                //Act
                var relationships = graphClient
                                    .ExecuteGetAllRelationshipsGremlin <TestPayload>(gremlinQueryExpected, null)
                                    .ToList();

                //Assert
                Assert.AreEqual(1, relationships.Count());
                Assert.AreEqual(456, relationships.ElementAt(0).Reference.Id);
                Assert.AreEqual(123, relationships.ElementAt(0).StartNodeReference.Id);
                Assert.AreEqual(789, relationships.ElementAt(0).EndNodeReference.Id);
                Assert.AreEqual("KNOWS", relationships.ElementAt(0).TypeKey);
                Assert.AreEqual("Foo", relationships.ElementAt(0).Data.Foo);
                Assert.AreEqual("Bar", relationships.ElementAt(0).Data.Bar);
            }
        }