public void SendRequestAsync_NullInvoker_Throws()
        {
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(new HttpRequestMessage[0]);

            Assert.ThrowsArgumentNull(
                () => requestItem.SendRequestAsync(null, CancellationToken.None).Wait(),
                "invoker");
        }
        public void SendRequestAsync_ReturnsChangeSetResponse()
        {
            HttpRequestMessage[] requests = new HttpRequestMessage[]
                {
                    new HttpRequestMessage(HttpMethod.Get, "http://example.com"),
                    new HttpRequestMessage(HttpMethod.Post, "http://example.com")
                };
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(requests);

            Mock<HttpMessageInvoker> invoker = new Mock<HttpMessageInvoker>(new HttpServer());
            invoker.Setup(i => i.SendAsync(It.IsAny<HttpRequestMessage>(), CancellationToken.None))
                .Returns(() =>
                {
                    return Task.FromResult(new HttpResponseMessage());
                });

            var response = requestItem.SendRequestAsync(invoker.Object, CancellationToken.None).Result;

            var changesetResponse = Assert.IsType<ChangeSetResponseItem>(response);
            Assert.Equal(2, changesetResponse.Responses.Count());
        }
        private async Task ExecuteChangeSet(
            ChangeSetRequestItem changeSet,
            IList<ODataBatchResponseItem> responses,
            CancellationToken cancellation)
        {
            ChangeSetResponseItem changeSetResponse;

            // Create a new ShoppingContext instance, associate it with each of the requests, start a new
            // transaction, execute the changeset and then commit or rollback the transaction depending on
            // whether the responses were all successful or not.
            using (ShoppingContext context = new ShoppingContext())
            {
                foreach (HttpRequestMessage request in changeSet.Requests)
                {
                    request.SetContext(context);
                }

                using (DbContextTransaction transaction = context.Database.BeginTransaction())
                {
                    changeSetResponse = (ChangeSetResponseItem)await changeSet.SendRequestAsync(Invoker, cancellation);
                    responses.Add(changeSetResponse);

                    if (changeSetResponse.Responses.All(r => r.IsSuccessStatusCode))
                    {
                        transaction.Commit();
                    }
                    else
                    {
                        transaction.Rollback();
                    }
                }
            }
        }
        public void SendRequestAsync_DisposesResponseInCaseOfException()
        {
            List<MockHttpResponseMessage> responses = new List<MockHttpResponseMessage>();
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(new HttpRequestMessage[]
            {
                new HttpRequestMessage(HttpMethod.Get, "http://example.com"),
                new HttpRequestMessage(HttpMethod.Post, "http://example.com"),
                new HttpRequestMessage(HttpMethod.Put, "http://example.com")
            });
            Mock<HttpMessageInvoker> invoker = new Mock<HttpMessageInvoker>(new HttpServer());
            invoker.Setup(i => i.SendAsync(It.IsAny<HttpRequestMessage>(), CancellationToken.None))
                .Returns<HttpRequestMessage, CancellationToken>((req, cancel) =>
                {
                    if (req.Method == HttpMethod.Put)
                    {
                        throw new InvalidOperationException();
                    }
                    var response = new MockHttpResponseMessage();
                    responses.Add(response);
                    return Task.FromResult<HttpResponseMessage>(response);
                });

            Assert.Throws<InvalidOperationException>(
                () => requestItem.SendRequestAsync(invoker.Object, CancellationToken.None).Result);

            Assert.Equal(2, responses.Count);
            foreach (var response in responses)
            {
                Assert.True(response.IsDisposed);
            }
        }
        public void SendRequestAsync_ReturnsSingleErrorResponse()
        {
            HttpRequestMessage[] requests = new HttpRequestMessage[]
                {
                    new HttpRequestMessage(HttpMethod.Get, "http://example.com"),
                    new HttpRequestMessage(HttpMethod.Post, "http://example.com"),
                    new HttpRequestMessage(HttpMethod.Put, "http://example.com")
                };
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(requests);

            Mock<HttpMessageInvoker> invoker = new Mock<HttpMessageInvoker>(new HttpServer());
            invoker.Setup(i => i.SendAsync(It.IsAny<HttpRequestMessage>(), CancellationToken.None))
                .Returns<HttpRequestMessage, CancellationToken>((req, c) =>
                {
                    if (req.Method == HttpMethod.Post)
                    {
                        return Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest));
                    }
                    return Task.FromResult(new HttpResponseMessage());
                });

            var response = requestItem.SendRequestAsync(invoker.Object, CancellationToken.None).Result;

            var changesetResponse = Assert.IsType<ChangeSetResponseItem>(response);
            Assert.Equal(1, changesetResponse.Responses.Count());
            Assert.Equal(HttpStatusCode.BadRequest, changesetResponse.Responses.First().StatusCode);
        }