Exemplo n.º 1
0
        public async Task ShouldSendCommandAndNotCareAboutResultsAsync()
        {
            // Arrange
            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),
                    MockResponse.Http((int)HttpStatusCode.OK)
                }
            })
            {
                var graphClient = await testHarness.CreateAndConnectGraphClient();

                var raisedEvent = false;

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

                //Act
                var task = graphClient.ExecuteCypherAsync(cypherQuery);
                task.Wait();

                Assert.True(raisedEvent, "Raised OperationCompleted");
            }
        }
Exemplo n.º 2
0
        public async Task DoesntSetHeaders_WhenNotSet()
        {
            const string queryText = "MATCH n SET n.Value = 'value'";

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

            var transactionApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery)
            };


            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.Get(""),
                    MockResponse.NeoRoot20()
                },
                {
                    MockRequest.PostObjectAsJson("/transaction/commit", transactionApiQuery),
                    MockResponse.Http((int)HttpStatusCode.OK)
                }
            })
            {
                var httpClient  = testHarness.GenerateHttpClient(testHarness.BaseUri);
                var graphClient = new GraphClient(new Uri(testHarness.BaseUri), httpClient);
                await graphClient.ConnectAsync();

                httpClient.ClearReceivedCalls();
                await((IRawGraphClient)graphClient).ExecuteCypherAsync(cypherQuery);

                var call           = httpClient.ReceivedCalls().Single();
                var requestMessage = (HttpRequestMessage)call.GetArguments()[0];
                Assert.False(requestMessage.Headers.Any(h => h.Key == "max-execution-time"));
            }
        }
Exemplo n.º 3
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);
            }
        }
Exemplo n.º 4
0
        public async Task SendsCommandWithCorrectTimeout()
        {
            const string queryText = "MATCH n SET n.Value = 'value'";
            const int    expectedMaxExecutionTime = 100;

            var cypherQuery         = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Set, CypherResultFormat.DependsOnEnvironment, "neo4j", maxExecutionTime: expectedMaxExecutionTime);
            var transactionApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery)
            };

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.Get(""),
                    MockResponse.NeoRoot20()
                },
                {
                    MockRequest.PostObjectAsJson("/transaction/commit", transactionApiQuery),
                    MockResponse.Http((int)HttpStatusCode.OK)
                }
            })
            {
                var httpClient  = testHarness.GenerateHttpClient(testHarness.BaseUri);
                var graphClient = new GraphClient(new Uri(testHarness.BaseUri), httpClient);
                await graphClient.ConnectAsync();

                httpClient.ClearReceivedCalls();
                await((IRawGraphClient)graphClient).ExecuteCypherAsync(cypherQuery);

                var call                   = httpClient.ReceivedCalls().Single();
                var requestMessage         = (HttpRequestMessage)call.GetArguments()[0];
                var maxExecutionTimeHeader = requestMessage.Headers.Single(h => h.Key == "max-execution-time");
                Assert.Equal(expectedMaxExecutionTime.ToString(CultureInfo.InvariantCulture), maxExecutionTimeHeader.Value.Single());
            }
        }
Exemplo n.º 5
0
                public async Task ReturnsQueryStats_WhenNotInTransaction()
                {
                    var          response  = MockResponse.Json(200, @"{
            'results' : [ {
                'columns' : [ 'id(n)' ],
                'data' : [ {
                    'row' : [ 4 ],
                    'meta' : [ null ]
                } ],
                'stats' : {
                    'contains_updates' : true,
                    'nodes_created' : 1,
                    'nodes_deleted' : 0,
                    'properties_set' : 0,
                    'relationships_created' : 0,
                    'relationship_deleted' : 0,
                    'labels_added' : 0,
                    'labels_removed' : 0,
                    'indexes_added' : 0,
                    'indexes_removed' : 0,
                    'constraints_added' : 0,
                    'constraints_removed' : 0,
                    'contains_system_updates' : false,
                    'system_updates' : 0
                }
            } ],
            'errors' : [ ]
        }
        ");
                    const string queryText = @"MATCH (n) RETURN id(n)";

                    var cypherQuery         = new CypherQuery(queryText, null, CypherResultMode.Set, CypherResultFormat.Rest, "neo4j", includeQueryStats: true);
                    var transactionApiQuery = new CypherStatementList {
                        new CypherTransactionStatement(cypherQuery)
                    };

                    using (var testHarness = new RestTestHarness
                    {
                        { MockRequest.PostObjectAsJson("/transaction/commit", transactionApiQuery), response }
                    })
                    {
                        var graphClient = await testHarness.CreateAndConnectGraphClient();

                        var        completedRaised = false;
                        QueryStats stats           = null;
                        graphClient.OperationCompleted += (o, e) =>
                        {
                            stats           = e.QueryStats;
                            completedRaised = true;
                        };

                        var results = await graphClient.ExecuteGetCypherResultsAsync <int>(cypherQuery);

                        results.First().Should().Be(4);

                        completedRaised.Should().BeTrue();
                        stats.Should().NotBeNull();
                        stats.NodesCreated.Should().Be(1);
                    }
                }
Exemplo n.º 6
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");
            }
        }
Exemplo n.º 7
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();
                }
            }
        }
        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);
                }
            }
        }
Exemplo n.º 9
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();
                }
            }
        }
Exemplo n.º 10
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);
            }
        }
Exemplo n.º 11
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);
            }
        }
Exemplo n.º 12
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);
                }
            }
        }
Exemplo n.º 13
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");
            }
        }
Exemplo n.º 14
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);
            }
        }
Exemplo n.º 15
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"));
            }
        }
Exemplo n.º 16
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);
            }
        }
Exemplo n.º 17
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);
            }
        }
Exemplo n.º 18
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);
            }
        }
Exemplo n.º 19
0
        public void TestTransactionScopeWithComplexDeserialization()
        {
            const string queryText      = @"MATCH (dt:DummyTotal) RETURN dt";
            const string resultColumn   = @"{'columns':['dt'],'data':[{'row':[{'total':1234}]}]}";
            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 results = client.Cypher.Match("(dt:DummyTotal)")
                                  .Return(dt => dt.As <DummyTotal>())
                                  .Results
                                  .ToList();

                    Assert.AreEqual(1, results.Count());
                    Assert.AreEqual(1234, results.First().Total);

                    msTransaction.Complete();
                }

                Assert.IsFalse(client.InTransaction);
            }
        }
        public void TestTransactionScopeWithSimpleDeserialization()
        {
            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 commitRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var msTransaction = new TransactionScope())
                {
                    Assert.IsTrue(client.InTransaction);

                    long total = client.Cypher
                                 .Match("(n)")
                                 .Return(n => n.Count())
                                 .Results
                                 .SingleOrDefault();

                    Assert.AreEqual(1, total);

                    msTransaction.Complete();
                }

                Assert.IsFalse(client.InTransaction);
            }
        }
Exemplo n.º 21
0
        public async Task SendingNullParametersShouldNotRaiseExceptionWhenExecutingCypher()
        {
            const string queryText = @"MATCH (d) RETURN d";

            var cypherQuery         = new CypherQuery(queryText, null, 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();

                // execute cypher with "null" parameters
                await graphClient.ExecuteCypherAsync(cypherQuery);
            }
        }
Exemplo n.º 22
0
        public async Task GraphClientFactoryUseCase()
        {
            const string queryText = @"RETURN d";

            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.Get("/"), MockResponse.NeoRoot20() },
                { MockRequest.PostObjectAsJson("/transaction/commit", cypherApiQuery), new MockResponse {
                      StatusCode = HttpStatusCode.OK
                  } }
            })
            {
                var httpClient = testHarness.GenerateHttpClient(testHarness.BaseUri);

                var executeConfiguration = new ExecutionConfiguration
                {
                    HttpClient       = httpClient,
                    UserAgent        = $"Neo4jClient/{typeof(NeoServerConfiguration).Assembly.GetName().Version}",
                    UseJsonStreaming = true,
                    JsonConverters   = GraphClient.DefaultJsonConverters
                };

                var configuration = await NeoServerConfiguration.GetConfigurationAsync(new Uri(testHarness.BaseUri), null, null, null, null, executeConfiguration);

                var factory = new GraphClientFactory(configuration);

                using (var client = await factory.CreateAsync(httpClient))
                {
                    await client.Cypher.Return <object>("d").ExecuteWithoutResultsAsync();
                }
            }
        }
        public void TestTransactionScopeWithSimpleDeserialization()
        {
            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 commitRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var msTransaction = new TransactionScope())
                {
                    Assert.IsTrue(client.InTransaction);

                    long total = client.Cypher
                        .Match("(n)")
                        .Return(n => n.Count())
                        .Results
                        .SingleOrDefault();

                    Assert.AreEqual(1, total);

                    msTransaction.Complete();
                }

                Assert.IsFalse(client.InTransaction);
            }
        }
        public void NestedTransactionWithTransactionScopeQueryFirst()
        {
            const string queryTextMsTransaction = @"MATCH (n) RETURN count(n)";
            const string queryTextTx = @"MATCH (t) RETURN count(t)";
            const string resultColumn = @"{'columns':['count(n)'], 'data':[{'row':[1]}]}";
            var cypherQueryMsTx = new CypherQuery(queryTextMsTransaction, new Dictionary<string, object>(), CypherResultMode.Projection);
            var cypherQueryMsTxStatement = new CypherStatementList { new CypherTransactionStatement(cypherQueryMsTx, false) };
            var cypherQueryTx = new CypherQuery(queryTextTx, new Dictionary<string, object>(), CypherResultMode.Projection);
            var cypherQueryTxStatement = new CypherStatementList { new CypherTransactionStatement(cypherQueryTx, false) };
            var deleteRequest = MockRequest.Delete("/transaction/1");
            var commitRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");
            var commitRequestTx = MockRequest.PostJson("/transaction/2/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherQueryMsTxStatement),
                    MockResponse.Json(201, GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                },
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherQueryTxStatement),
                    MockResponse.Json(201, GenerateInitTransactionResponse(2, resultColumn), "http://foo/db/data/transaction/2")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                },
                {
                    commitRequestTx, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                },
                {
                    deleteRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            }.ShouldNotBeCalled(commitRequest))
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var msTransaction = new TransactionScope())
                {
                    Assert.IsTrue(client.InTransaction);

                    long totalMsTx = client.Cypher
                        .Match("(n)")
                        .Return(n => n.Count())
                        .Results
                        .SingleOrDefault();
                    Assert.AreEqual(1, totalMsTx);

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

                        Assert.AreEqual(1, total);

                        // should not be called
                        tx.Commit();
                    }
                }
            }
        }
        public void AsyncRequestsInTransactionShouldBeExecutedInOrder()
        {
            const string queryTextBase = @"MATCH (n) RETURN {0} as Total";
            const string resultColumnBase = @"{{'columns':['Total'], 'data':[{{'row':[{0}]}}]}}";
            const int asyncRequests = 15;

            var queries = new CypherQuery[asyncRequests];
            var apiQueries = new CypherStatementList[asyncRequests];
            var responses = new MockResponse[asyncRequests];
            var testHarness = new RestHarnessWithCounter();

            for (int i = 0; i < asyncRequests; i++)
            {
                queries[i] = new CypherQuery(string.Format(queryTextBase, i), new Dictionary<string, object>(),
                    CypherResultMode.Projection);
                apiQueries[i] = new CypherStatementList {new CypherTransactionStatement(queries[i], false)};
                responses[i] = MockResponse.Json(200,
                    @"{'results':[" + string.Format(resultColumnBase, i) + @"], 'errors':[] }");
                if (i > 0)
                {
                    testHarness.Add(MockRequest.PostObjectAsJson("/transaction/1", apiQueries[i]), responses[i]);
                }
            }

            testHarness.Add(
                MockRequest.PostObjectAsJson("/transaction", apiQueries[0]),
                MockResponse.Json(201, GenerateInitTransactionResponse(1, string.Format(resultColumnBase, 0)),
                    "http://foo/db/data/transaction/1")
                );
            testHarness.Add(
                MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}"),
                MockResponse.Json(200, @"{'results':[], 'errors':[] }")
            );
            try
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                var rawClient = (IRawGraphClient)client;
                var tasks = new Task[asyncRequests];
                using (var tran = client.BeginTransaction())
                {
                    for (int i = 0; i < asyncRequests; i++)
                    {
                        int tmpResult = i;
                        tasks[i] = rawClient.ExecuteGetCypherResultsAsync<DummyTotal>(queries[i]).ContinueWith(task =>
                        {
                            Assert.AreEqual(tmpResult, task.Result.Single().Total);
                        });
                    }

                    Task.WaitAll(tasks);
                    tran.Commit();
                }
            }
            finally
            {
                testHarness.Dispose();
            }

            // check that we have a total order
            Assert.AreEqual(asyncRequests, testHarness.Queue.Count);
            int lastElement = -1;
            for (int i = 0; i < asyncRequests; i++)
            {
                int headItem;
                Assert.IsTrue(testHarness.Queue.TryDequeue(out headItem));
                Assert.Greater(headItem, lastElement);
                lastElement = headItem;
            }
        }
        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, GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                var rawClient = (IRawGraphClient) client;
                using (var tran = client.BeginTransaction())
                {
                    var totalObj = rawClient.ExecuteGetCypherResultsAsync<DummyTotal>(cypherQuery).Result.Single();
                    Assert.AreEqual(1, totalObj.Total);
                    tran.Commit();
                }

            }
        }
        public void 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, 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();
                }

            }
        }
        public void TestTransactionScopeWithComplexDeserialization()
        {
            const string queryText = @"MATCH (dt:DummyTotal) RETURN dt";
            const string resultColumn = @"{'columns':['dt'],'data':[{'row':[{'total':1234}]}]}";
            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 results = client.Cypher.Match("(dt:DummyTotal)")
                        .Return(dt => dt.As<DummyTotal>())
                        .Results
                        .ToList();

                    Assert.AreEqual(1, results.Count());
                    Assert.AreEqual(1234, results.First().Total);

                    msTransaction.Complete();
                }

                Assert.IsFalse(client.InTransaction);
            }
        }
        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);
            }
        }
        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);
                    var ex = Assert.Throws<InvalidOperationException>(() => tran.Commit());
                    Assert.AreEqual("Cannot commit unless all tasks have been completed", ex.Message);
                }

            }
        }
Exemplo n.º 31
0
        public async Task ShouldDeserializeTableStructureWithRelationships()
        {
            // Arrange
            const string queryText   = @"
                START x = node($p0)
                MATCH x-[r]->n
                RETURN x AS Fooness, 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' : [ [ {
                                'start' : 'http://foo/db/data/node/0',
                                'data' : {
                                    'Bar' : 'bar',
                                    'Baz' : 'baz'
                                },
                                'property' : 'http://foo/db/data/relationship/0/properties/{key}',
                                'self' : 'http://foo/db/data/relationship/0',
                                'properties' : 'http://foo/db/data/relationship/0/properties',
                                'type' : 'HAS_REFERENCE_DATA',
                                'extensions' : {
                                },
                                'end' : 'http://foo/db/data/node/1'
                                }, 'HOSTS', 'foo', 44321 ], [ {
                                'start' : 'http://foo/db/data/node/1',
                                'data' : {
                                    'Bar' : 'bar',
                                    'Baz' : 'baz'
                                },
                                'property' : 'http://foo/db/data/relationship/1/properties/{key}',
                                'self' : 'http://foo/db/data/relationship/1',
                                'properties' : 'http://foo/db/data/relationship/1/properties',
                                'type' : 'HAS_REFERENCE_DATA',
                                'extensions' : {
                                },
                                'end' : 'http://foo/db/data/node/1'
                                }, 'LIKES', 'bar', 44311 ], [ {
                                'start' : 'http://foo/db/data/node/2',
                                'data' : {
                                    'Bar' : 'bar',
                                    'Baz' : 'baz'
                                },
                                'property' : 'http://foo/db/data/relationship/2/properties/{key}',
                                'self' : 'http://foo/db/data/relationship/2',
                                'properties' : 'http://foo/db/data/relationship/2/properties',
                                'type' : 'HAS_REFERENCE_DATA',
                                'extensions' : {
                                },
                                'end' : 'http://foo/db/data/node/1'
                                }, 'HOSTS', 'baz', 42586 ] ],
                                'columns' : [ 'Fooness', 'RelationshipType', 'Name', 'UniqueId' ]
                            }")
                }
            })
            {
                var graphClient = await testHarness.CreateAndConnectGraphClient();

                //Act
                //Act
                var results = await graphClient.ExecuteGetCypherResultsAsync <ResultWithRelationshipDto>(cypherQuery);

                //Assert
                Assert.IsAssignableFrom <IEnumerable <ResultWithRelationshipDto> >(results);

                var resultsArray = results.ToArray();
                Assert.Equal(3, resultsArray.Count());

                var firstResult = resultsArray[0];
                Assert.Equal(0, firstResult.Fooness.Reference.Id);
                Assert.Equal("bar", firstResult.Fooness.Data.Bar);
                Assert.Equal("baz", firstResult.Fooness.Data.Baz);
                Assert.Equal("HOSTS", firstResult.RelationshipType);
                Assert.Equal("foo", firstResult.Name);
                Assert.Equal(44321, firstResult.UniqueId);

                var secondResult = resultsArray[1];
                Assert.Equal(1, secondResult.Fooness.Reference.Id);
                Assert.Equal("bar", secondResult.Fooness.Data.Bar);
                Assert.Equal("baz", secondResult.Fooness.Data.Baz);
                Assert.Equal("LIKES", secondResult.RelationshipType);
                Assert.Equal("bar", secondResult.Name);
                Assert.Equal(44311, secondResult.UniqueId);

                var thirdResult = resultsArray[2];
                Assert.Equal(2, thirdResult.Fooness.Reference.Id);
                Assert.Equal("bar", thirdResult.Fooness.Data.Bar);
                Assert.Equal("baz", thirdResult.Fooness.Data.Baz);
                Assert.Equal("HOSTS", thirdResult.RelationshipType);
                Assert.Equal("baz", thirdResult.Name);
                Assert.Equal(42586, thirdResult.UniqueId);
            }
        }
        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);
                }
            }
        }
Exemplo n.º 33
0
        public async Task ShouldDeserializeArrayOfNodesInPropertyAsResultOfCollectFunctionInCypherQuery()
        {
            // Arrange
            var cypherQuery = new CypherQuery(
                @"START root=node(0) MATCH root-[:HAS_COMPANIES]->()-[:HAS_COMPANY]->company, company--foo RETURN company, collect(foo) as Bar",
                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.OK, @"{
  'columns' : [ 'ColumnA', 'ColumnBFromCollect' ],
  'data' : [ [ {
    'paged_traverse' : 'http://localhost:8000/db/data/node/358/paged/traverse/{returnType}{?pageSize,leaseTime}',
    'outgoing_relationships' : 'http://localhost:8000/db/data/node/358/relationships/out',
    'data' : {
      'Bar' : 'BHP',
      'Baz' : '1'
    },
    'all_typed_relationships' : 'http://localhost:8000/db/data/node/358/relationships/all/{-list|&|types}',
    'traverse' : 'http://localhost:8000/db/data/node/358/traverse/{returnType}',
    'self' : 'http://localhost:8000/db/data/node/358',
    'property' : 'http://localhost:8000/db/data/node/358/properties/{key}',
    'all_relationships' : 'http://localhost:8000/db/data/node/358/relationships/all',
    'outgoing_typed_relationships' : 'http://localhost:8000/db/data/node/358/relationships/out/{-list|&|types}',
    'properties' : 'http://localhost:8000/db/data/node/358/properties',
    'incoming_relationships' : 'http://localhost:8000/db/data/node/358/relationships/in',
    'incoming_typed_relationships' : 'http://localhost:8000/db/data/node/358/relationships/in/{-list|&|types}',
    'extensions' : {
    },
    'create_relationship' : 'http://localhost:8000/db/data/node/358/relationships'
  }, [ {
    'paged_traverse' : 'http://localhost:8000/db/data/node/362/paged/traverse/{returnType}{?pageSize,leaseTime}',
    'outgoing_relationships' : 'http://localhost:8000/db/data/node/362/relationships/out',
    'data' : {
      'OpportunityType' : 'Board',
      'Description' : 'Foo'
    },
    'all_typed_relationships' : 'http://localhost:8000/db/data/node/362/relationships/all/{-list|&|types}',
    'traverse' : 'http://localhost:8000/db/data/node/362/traverse/{returnType}',
    'self' : 'http://localhost:8000/db/data/node/362',
    'property' : 'http://localhost:8000/db/data/node/362/properties/{key}',
    'all_relationships' : 'http://localhost:8000/db/data/node/362/relationships/all',
    'outgoing_typed_relationships' : 'http://localhost:8000/db/data/node/362/relationships/out/{-list|&|types}',
    'properties' : 'http://localhost:8000/db/data/node/362/properties',
    'incoming_relationships' : 'http://localhost:8000/db/data/node/362/relationships/in',
    'incoming_typed_relationships' : 'http://localhost:8000/db/data/node/362/relationships/in/{-list|&|types}',
    'extensions' : {
    },
    'create_relationship' : 'http://localhost:8000/db/data/node/362/relationships'
  }, {
    'paged_traverse' : 'http://localhost:8000/db/data/node/359/paged/traverse/{returnType}{?pageSize,leaseTime}',
    'outgoing_relationships' : 'http://localhost:8000/db/data/node/359/relationships/out',
    'data' : {
      'OpportunityType' : 'Executive',
      'Description' : 'Bar'
    },
    'all_typed_relationships' : 'http://localhost:8000/db/data/node/359/relationships/all/{-list|&|types}',
    'traverse' : 'http://localhost:8000/db/data/node/359/traverse/{returnType}',
    'self' : 'http://localhost:8000/db/data/node/359',
    'property' : 'http://localhost:8000/db/data/node/359/properties/{key}',
    'all_relationships' : 'http://localhost:8000/db/data/node/359/relationships/all',
    'outgoing_typed_relationships' : 'http://localhost:8000/db/data/node/359/relationships/out/{-list|&|types}',
    'properties' : 'http://localhost:8000/db/data/node/359/properties',
    'incoming_relationships' : 'http://localhost:8000/db/data/node/359/relationships/in',
    'incoming_typed_relationships' : 'http://localhost:8000/db/data/node/359/relationships/in/{-list|&|types}',
    'extensions' : {
    },
    'create_relationship' : 'http://localhost:8000/db/data/node/359/relationships'
  } ] ] ]
}")
                }
            })
            {
                var graphClient = await testHarness.CreateAndConnectGraphClient();

                //Act
                var results = await graphClient.ExecuteGetCypherResultsAsync <CollectResult>(cypherQuery);

                //Assert
                Assert.IsAssignableFrom <IEnumerable <CollectResult> >(results);

                var resultsArray = results.ToArray();
                Assert.Equal(1, resultsArray.Count());

                var firstResult = resultsArray[0];
                Assert.Equal(358, firstResult.ColumnA.Reference.Id);
                Assert.Equal("BHP", firstResult.ColumnA.Data.Bar);
                Assert.Equal("1", firstResult.ColumnA.Data.Baz);

                var collectedResults = firstResult.ColumnBFromCollect.ToArray();
                Assert.Equal(2, collectedResults.Count());

                var firstCollectedResult = collectedResults[0];
                Assert.Equal(362, firstCollectedResult.Reference.Id);
                Assert.Equal("Board", firstCollectedResult.Data.OpportunityType);
                Assert.Equal("Foo", firstCollectedResult.Data.Description);

                var secondCollectedResult = collectedResults[1];
                Assert.Equal(359, secondCollectedResult.Reference.Id);
                Assert.Equal("Executive", secondCollectedResult.Data.OpportunityType);
                Assert.Equal("Bar", secondCollectedResult.Data.Description);
            }
        }
Exemplo n.º 34
0
        public void AsyncRequestsInTransactionShouldBeExecutedInOrder()
        {
            const string queryTextBase    = @"MATCH (n) RETURN {0} as Total";
            const string resultColumnBase = @"{{'columns':['Total'], 'data':[{{'row':[{0}]}}]}}";
            const int    asyncRequests    = 15;

            var queries     = new CypherQuery[asyncRequests];
            var apiQueries  = new CypherStatementList[asyncRequests];
            var responses   = new MockResponse[asyncRequests];
            var testHarness = new RestHarnessWithCounter();

            for (int i = 0; i < asyncRequests; i++)
            {
                queries[i] = new CypherQuery(string.Format(queryTextBase, i), new Dictionary <string, object>(),
                                             CypherResultMode.Projection);
                apiQueries[i] = new CypherStatementList {
                    new CypherTransactionStatement(queries[i], false)
                };
                responses[i] = MockResponse.Json(200,
                                                 @"{'results':[" + string.Format(resultColumnBase, i) + @"], 'errors':[] }");
                if (i > 0)
                {
                    testHarness.Add(MockRequest.PostObjectAsJson("/transaction/1", apiQueries[i]), responses[i]);
                }
            }

            testHarness.Add(
                MockRequest.PostObjectAsJson("/transaction", apiQueries[0]),
                MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, string.Format(resultColumnBase, 0)),
                                  "http://foo/db/data/transaction/1")
                );
            testHarness.Add(
                MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}"),
                MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                );
            try
            {
                var client    = testHarness.CreateAndConnectTransactionalGraphClient();
                var rawClient = (IRawGraphClient)client;
                var tasks     = new Task[asyncRequests];
                using (var tran = client.BeginTransaction())
                {
                    for (int i = 0; i < asyncRequests; i++)
                    {
                        int tmpResult = i;
                        tasks[i] = rawClient.ExecuteGetCypherResultsAsync <DummyTotal>(queries[i]).ContinueWith(task =>
                        {
                            Assert.AreEqual(tmpResult, task.Result.Single().Total);
                        });
                    }

                    Task.WaitAll(tasks);
                    tran.Commit();
                }
            }
            finally
            {
                testHarness.Dispose();
            }

            // check that we have a total order
            Assert.AreEqual(asyncRequests, testHarness.Queue.Count);
            int lastElement = -1;

            for (int i = 0; i < asyncRequests; i++)
            {
                int headItem;
                Assert.IsTrue(testHarness.Queue.TryDequeue(out headItem));
                Assert.Greater(headItem, lastElement);
                lastElement = headItem;
            }
        }