diff --git a/Octokit.Tests/Http/ConnectionTests.cs b/Octokit.Tests/Http/ConnectionTests.cs index e451c27c..c1f2d925 100644 --- a/Octokit.Tests/Http/ConnectionTests.cs +++ b/Octokit.Tests/Http/ConnectionTests.cs @@ -35,8 +35,10 @@ namespace Octokit.Tests.Http httpClient.Received(1).Send(Arg.Is(req => req.BaseAddress == ExampleUri && - req.Method == HttpMethod.Get && - req.Endpoint == new Uri("/endpoint", UriKind.Relative))); + req.ContentType == null && + req.Body == null && + req.Method == HttpMethod.Get && + req.Endpoint == new Uri("/endpoint", UriKind.Relative))); } [Fact] @@ -57,8 +59,8 @@ namespace Octokit.Tests.Http httpClient.Received(3).Send(Arg.Is(req => req.BaseAddress == ExampleUri && - req.Method == HttpMethod.Get && - req.Endpoint == new Uri("/endpoint", UriKind.Relative))); + req.Method == HttpMethod.Get && + req.Endpoint == new Uri("/endpoint", UriKind.Relative))); } [Fact] @@ -147,9 +149,11 @@ namespace Octokit.Tests.Http httpClient.Received(1).Send(Arg.Is(req => req.BaseAddress == ExampleUri && - req.Method == HttpMethod.Get && - req.Headers["Accept"] == "application/vnd.github.html" && - req.Endpoint == new Uri("/endpoint", UriKind.Relative))); + req.ContentType == null && + req.Body == null && + req.Method == HttpMethod.Get && + req.Headers["Accept"] == "application/vnd.github.html" && + req.Endpoint == new Uri("/endpoint", UriKind.Relative))); } } @@ -172,16 +176,41 @@ namespace Octokit.Tests.Http httpClient.Received(1).Send(Arg.Is(req => req.BaseAddress == ExampleUri && - (string)req.Body == data && - req.Method == HttpVerb.Patch && - req.Endpoint == new Uri("/endpoint", UriKind.Relative))); + (string)req.Body == data && + req.Method == HttpVerb.Patch && + req.Endpoint == new Uri("/endpoint", UriKind.Relative))); + } + } + + public class ThePutAsyncMethod + { + [Fact] + public async Task RunsConfiguredAppWithAppropriateEnv() + { + string data = SimpleJson.SerializeObject(new object()); + var httpClient = Substitute.For(); + IResponse response = new ApiResponse(); + httpClient.Send(Args.Request).Returns(Task.FromResult(response)); + var connection = new Connection("Test Runner", + ExampleUri, + Substitute.For(), + httpClient, + Substitute.For()); + + await connection.PutAsync(new Uri("/endpoint", UriKind.Relative), new object()); + + httpClient.Received(1).Send(Arg.Is(req => + req.BaseAddress == ExampleUri && + (string)req.Body == data && + req.Method == HttpMethod.Put && + req.Endpoint == new Uri("/endpoint", UriKind.Relative))); } } public class ThePostAsyncMethod { [Fact] - public async Task RunsConfiguredAppWithAppropriateEnv() + public async Task SendsProperlyFormattedPostRequest() { string data = SimpleJson.SerializeObject(new object()); var httpClient = Substitute.For(); @@ -197,16 +226,39 @@ namespace Octokit.Tests.Http httpClient.Received(1).Send(Arg.Is(req => req.BaseAddress == ExampleUri && - (string)req.Body == data && - req.Method == HttpMethod.Post && - req.Endpoint == new Uri("/endpoint", UriKind.Relative))); + req.ContentType == "application/x-www-form-urlencoded" && + (string)req.Body == data && + req.Method == HttpMethod.Post && + req.Endpoint == new Uri("/endpoint", UriKind.Relative))); + } + + [Fact] + public async Task WithNoBodySetsNoContentType() + { + var httpClient = Substitute.For(); + IResponse response = new ApiResponse(); + httpClient.Send(Args.Request).Returns(Task.FromResult(response)); + var connection = new Connection("Test Runner", + ExampleUri, + Substitute.For(), + httpClient, + Substitute.For()); + + await connection.PostAsync(new Uri("/endpoint", UriKind.Relative), null); + + httpClient.Received(1).Send(Arg.Is(req => + req.BaseAddress == ExampleUri && + req.ContentType == null && + req.Body == null && + req.Method == HttpMethod.Post && + req.Endpoint == new Uri("/endpoint", UriKind.Relative))); } } public class ThePostRawAsyncMethod { [Fact] - public async Task RunsConfiguredAppWithAppropriateEnv() + public async Task SendsProperlyFormattedPostRequestWithCorrectHeaders() { var httpClient = Substitute.For(); IResponse response = new ApiResponse(); @@ -232,7 +284,7 @@ namespace Octokit.Tests.Http public class TheDeleteAsyncMethod { [Fact] - public async Task RunsConfiguredAppWithAppropriateEnv() + public async Task SendsProperlyFormattedDeleteRequest() { var httpClient = Substitute.For(); IResponse response = new ApiResponse(); @@ -247,8 +299,10 @@ namespace Octokit.Tests.Http httpClient.Received(1).Send(Arg.Is(req => req.BaseAddress == ExampleUri && - req.Method == HttpMethod.Delete && - req.Endpoint == new Uri("/endpoint", UriKind.Relative))); + req.Body == null && + req.ContentType == null && + req.Method == HttpMethod.Delete && + req.Endpoint == new Uri("/endpoint", UriKind.Relative))); } } diff --git a/Octokit.Tests/Http/HttpClientAdapterTests.cs b/Octokit.Tests/Http/HttpClientAdapterTests.cs index 84d224a0..0300dc13 100644 --- a/Octokit.Tests/Http/HttpClientAdapterTests.cs +++ b/Octokit.Tests/Http/HttpClientAdapterTests.cs @@ -28,15 +28,33 @@ namespace Octokit.Tests.Http }; var tester = new HttpClientAdapterTester(); - var responseMessage = tester.BuildRequestMessageTester(request); - - Assert.Equal(2, responseMessage.Headers.Count()); - var firstHeader = responseMessage.Headers.First(); + var requestMessage = tester.BuildRequestMessageTester(request); + + Assert.Equal(2, requestMessage.Headers.Count()); + var firstHeader = requestMessage.Headers.First(); Assert.Equal("foo", firstHeader.Key); Assert.Equal("bar", firstHeader.Value.First()); - var lastHeader = responseMessage.Headers.Last(); + var lastHeader = requestMessage.Headers.Last(); Assert.Equal("blah", lastHeader.Key); Assert.Equal("blase", lastHeader.Value.First()); + Assert.Null(requestMessage.Content); + } + + [Fact] + public void SetsBodyAndContentType() + { + var request = new Request + { + Method = HttpMethod.Post, + Body = "{}", + ContentType = "text/plain" + }; + var tester = new HttpClientAdapterTester(); + + var requestMessage = tester.BuildRequestMessageTester(request); + + Assert.NotNull(requestMessage.Content); + Assert.Equal("text/plain", requestMessage.Content.Headers.ContentType.MediaType); } [Fact] diff --git a/Octokit/Http/Connection.cs b/Octokit/Http/Connection.cs index 007b3e8b..456cdca4 100644 --- a/Octokit/Http/Connection.cs +++ b/Octokit/Http/Connection.cs @@ -99,13 +99,8 @@ namespace Octokit.Http Ensure.ArgumentNotNull(endpoint, "endpoint"); Ensure.ArgumentNotNull(body, "body"); - return await Run(new Request - { - Method = HttpVerb.Patch, - BaseAddress = BaseAddress, - Endpoint = endpoint, - Body = body - }); + + return await SendData(endpoint, HttpVerb.Patch, body); } public async Task> PostAsync(Uri endpoint, object body) @@ -140,18 +135,29 @@ namespace Octokit.Http return await SendData(endpoint, HttpMethod.Put, body); } - async Task> SendData(Uri endpoint, HttpMethod method, object body) + async Task> SendData( + Uri endpoint, + HttpMethod method, + object body, + string contentType = "application/x-www-form-urlencoded" // Per: http://developer.github.com/v3/ + ) { Ensure.ArgumentNotNull(endpoint, "endpoint"); - Ensure.ArgumentNotNull(body, "body"); - - return await Run(new Request + + var request = new Request { Method = method, BaseAddress = BaseAddress, Endpoint = endpoint, - Body = body - }); + }; + + if (body != null) + { + request.Body = body; + request.ContentType = contentType; + } + + return await Run(request); } public async Task DeleteAsync(Uri endpoint) diff --git a/Octokit/Http/HttpClientAdapter.cs b/Octokit/Http/HttpClientAdapter.cs index c2990fbf..a6d5cee2 100644 --- a/Octokit/Http/HttpClientAdapter.cs +++ b/Octokit/Http/HttpClientAdapter.cs @@ -66,7 +66,7 @@ namespace Octokit.Http var body = request.Body as string; if (body != null) { - requestMessage.Content = new StringContent(body, Encoding.UTF8); + requestMessage.Content = new StringContent(body, Encoding.UTF8, request.ContentType); } var bodyStream = request.Body as System.IO.Stream; if (bodyStream != null) diff --git a/Octokit/Http/IRequest.cs b/Octokit/Http/IRequest.cs index f7a3bc06..c923b566 100644 --- a/Octokit/Http/IRequest.cs +++ b/Octokit/Http/IRequest.cs @@ -12,5 +12,6 @@ namespace Octokit.Http Dictionary Parameters { get; } Uri BaseAddress { get; } Uri Endpoint { get; } + string ContentType { get; } } } diff --git a/Octokit/Http/Request.cs b/Octokit/Http/Request.cs index 4573c7a5..1b615efc 100644 --- a/Octokit/Http/Request.cs +++ b/Octokit/Http/Request.cs @@ -18,5 +18,6 @@ namespace Octokit.Http public Dictionary Parameters { get; private set; } public Uri BaseAddress { get; set; } public Uri Endpoint { get; set; } + public string ContentType { get; set; } } }