diff --git a/Octokit.Tests/Clients/MiscellaneousClientTests.cs b/Octokit.Tests/Clients/MiscellaneousClientTests.cs index ba998b2b..c9d8045e 100644 --- a/Octokit.Tests/Clients/MiscellaneousClientTests.cs +++ b/Octokit.Tests/Clients/MiscellaneousClientTests.cs @@ -14,11 +14,8 @@ namespace Octokit.Tests.Clients [Fact] public async Task RequestsTheEmojiEndpoint() { - var links = new Dictionary(); - var scopes = new List(); IApiResponse response = new ApiResponse(new Response { - ApiInfo = new ApiInfo(links, scopes, scopes, "", new RateLimit(new Dictionary())), Body = "Test" }, "Test"); var connection = Substitute.For(); @@ -42,18 +39,15 @@ namespace Octokit.Tests.Clients [Fact] public async Task RequestsTheEmojiEndpoint() { - var links = new Dictionary(); - var scopes = new List(); IApiResponse> response = new ApiResponse> - (new Response - { - ApiInfo = new ApiInfo(links, scopes, scopes, "", new RateLimit(new Dictionary())) - }, + ( + new Response(), new Dictionary { { "foo", "http://example.com/foo.gif" }, { "bar", "http://example.com/bar.gif" } - }); + } + ); var connection = Substitute.For(); connection.Get>(Args.Uri, null, null).Returns(Task.FromResult(response)); var client = new MiscellaneousClient(connection); diff --git a/Octokit.Tests/Exceptions/RateLimitExceededExceptionTests.cs b/Octokit.Tests/Exceptions/RateLimitExceededExceptionTests.cs index d8995038..2505e231 100644 --- a/Octokit.Tests/Exceptions/RateLimitExceededExceptionTests.cs +++ b/Octokit.Tests/Exceptions/RateLimitExceededExceptionTests.cs @@ -16,11 +16,14 @@ namespace Octokit.Tests.Exceptions [Fact] public void ParsesRateLimitsFromHeaders() { - var response = new Response { StatusCode = HttpStatusCode.Forbidden }; - response.Headers.Add("X-RateLimit-Limit", "100"); - response.Headers.Add("X-RateLimit-Remaining", "42"); - response.Headers.Add("X-RateLimit-Reset", "1372700873"); - response.ApiInfo = CreateApiInfo(response); + var headers = new Dictionary + { + {"X-RateLimit-Limit", "100"}, + {"X-RateLimit-Remaining", "42"}, + {"X-RateLimit-Reset", "1372700873"} + }; + var response = new Response(headers) { StatusCode = HttpStatusCode.Forbidden }; + var exception = new RateLimitExceededException(response); Assert.Equal(HttpStatusCode.Forbidden, exception.StatusCode); @@ -30,7 +33,6 @@ namespace Octokit.Tests.Exceptions "Mon 01 Jul 2013 5:47:53 PM -00:00", "ddd dd MMM yyyy h:mm:ss tt zzz", CultureInfo.InvariantCulture); - Assert.Equal("API Rate Limit exceeded", exception.Message); Assert.Equal(expectedReset, exception.Reset); } @@ -38,11 +40,14 @@ namespace Octokit.Tests.Exceptions [Fact] public void HandlesInvalidHeaderValues() { - var response = new Response { StatusCode = HttpStatusCode.Forbidden }; - response.Headers.Add("X-RateLimit-Limit", "XXX"); - response.Headers.Add("X-RateLimit-Remaining", "XXXX"); - response.Headers.Add("X-RateLimit-Reset", "XXXX"); - response.ApiInfo = CreateApiInfo(response); + var headers = new Dictionary + { + {"X-RateLimit-Limit", "XXX"}, + {"X-RateLimit-Remaining", "XXXX"}, + {"X-RateLimit-Reset", "XXXX"} + }; + var response = new Response(headers) { StatusCode = HttpStatusCode.Forbidden }; + var exception = new RateLimitExceededException(response); Assert.Equal(HttpStatusCode.Forbidden, exception.StatusCode); @@ -58,11 +63,10 @@ namespace Octokit.Tests.Exceptions [Fact] public void HandlesMissingHeaderValues() { - var response = new Response + var response = new Response(new Dictionary()) { StatusCode = HttpStatusCode.Forbidden }; - response.ApiInfo = CreateApiInfo(response); var exception = new RateLimitExceededException(response); Assert.Equal(HttpStatusCode.Forbidden, exception.StatusCode); @@ -79,11 +83,12 @@ namespace Octokit.Tests.Exceptions [Fact] public void CanPopulateObjectFromSerializedData() { - var response = new Response { StatusCode = HttpStatusCode.Forbidden }; - response.Headers.Add("X-RateLimit-Limit", "100"); - response.Headers.Add("X-RateLimit-Remaining", "42"); - response.Headers.Add("X-RateLimit-Reset", "1372700873"); - response.ApiInfo = CreateApiInfo(response); + var headers = new Dictionary{ + {"X-RateLimit-Limit", "100"}, + {"X-RateLimit-Remaining", "42"}, + {"X-RateLimit-Reset", "1372700873"} + }; + var response = new Response(headers) { StatusCode = HttpStatusCode.Forbidden }; var exception = new RateLimitExceededException(response); @@ -106,10 +111,5 @@ namespace Octokit.Tests.Exceptions } #endif } - - static ApiInfo CreateApiInfo(IResponse response) - { - return new ApiInfo(new Dictionary(), new List(), new List(), "etag", new RateLimit(response.Headers) ); - } } } diff --git a/Octokit.Tests/Http/ApiConnectionTests.cs b/Octokit.Tests/Http/ApiConnectionTests.cs index 4b26c27e..9845fd4b 100644 --- a/Octokit.Tests/Http/ApiConnectionTests.cs +++ b/Octokit.Tests/Http/ApiConnectionTests.cs @@ -87,13 +87,8 @@ namespace Octokit.Tests.Http public async Task MakesGetRequestForAllItems() { var getAllUri = new Uri("anything", UriKind.Relative); - var links = new Dictionary(); - var scopes = new List(); IApiResponse> response = new ApiResponse>( - new Response - { - ApiInfo = new ApiInfo(links, scopes, scopes, "etag", new RateLimit(new Dictionary())) - }, + new Response(), new List { new object(), new object() }); var connection = Substitute.For(); connection.Get>(Args.Uri, null, null).Returns(Task.FromResult(response)); diff --git a/Octokit.Tests/Http/ApiInfoParserTests.cs b/Octokit.Tests/Http/ApiInfoParserTests.cs index 20b9792c..5fbb3bf1 100644 --- a/Octokit.Tests/Http/ApiInfoParserTests.cs +++ b/Octokit.Tests/Http/ApiInfoParserTests.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using Octokit.Internal; using Xunit; -using Xunit.Extensions; namespace Octokit.Tests { @@ -14,21 +13,17 @@ namespace Octokit.Tests [Fact] public void ParsesApiInfoFromHeaders() { - var response = new Response + var headers = new Dictionary { - Headers = - { - { "X-Accepted-OAuth-Scopes", "user" }, - { "X-OAuth-Scopes", "user, public_repo, repo, gist" }, - { "X-RateLimit-Limit", "5000" }, - { "X-RateLimit-Remaining", "4997" }, - { "ETag", "5634b0b187fd2e91e3126a75006cc4fa" } - } + { "X-Accepted-OAuth-Scopes", "user" }, + { "X-OAuth-Scopes", "user, public_repo, repo, gist" }, + { "X-RateLimit-Limit", "5000" }, + { "X-RateLimit-Remaining", "4997" }, + { "ETag", "5634b0b187fd2e91e3126a75006cc4fa" } }; - ApiInfoParser.ParseApiHttpHeaders(response); + var apiInfo = ApiInfoParser.ParseResponseHeaders(headers); - var apiInfo = response.ApiInfo; Assert.NotNull(apiInfo); Assert.Equal(new[] { "user" }, apiInfo.AcceptedOauthScopes.ToArray()); Assert.Equal(new[] { "user", "public_repo", "repo", "gist" }, apiInfo.OauthScopes.ToArray()); @@ -40,21 +35,17 @@ namespace Octokit.Tests [Fact] public void BadHeadersAreIgnored() { - var response = new Response + var headers = new Dictionary { - Headers = { - { - "Link", - "; , " + - "; , " + + " { - Headers = { - { - "Link", - "; rel=\"next\", " + - "; rel=\"last\", " + - "; rel=\"first\", " + - "; rel=\"prev\"" - } + "Link", + "; rel=\"next\", " + + "; rel=\"last\", " + + "; rel=\"first\", " + + "; rel=\"prev\"" } }; - ApiInfoParser.ParseApiHttpHeaders(response); + var apiInfo = ApiInfoParser.ParseResponseHeaders(headers); - var apiInfo = response.ApiInfo; Assert.NotNull(apiInfo); Assert.Equal(4, apiInfo.Links.Count); Assert.Contains("next", apiInfo.Links.Keys); diff --git a/Octokit.Tests/Http/ConnectionTests.cs b/Octokit.Tests/Http/ConnectionTests.cs index 81bd6406..30747fdf 100644 --- a/Octokit.Tests/Http/ConnectionTests.cs +++ b/Octokit.Tests/Http/ConnectionTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; @@ -66,14 +67,12 @@ namespace Octokit.Tests.Http public async Task ParsesApiInfoOnResponse() { var httpClient = Substitute.For(); - IResponse response = new Response + var headers = new Dictionary { - Headers = - { - { "X-Accepted-OAuth-Scopes", "user" }, - } + { "X-Accepted-OAuth-Scopes", "user" }, }; - + IResponse response = new Response(headers); + httpClient.Send(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response)); var connection = new Connection(new ProductHeaderValue("OctokitTests"), _exampleUri, diff --git a/Octokit.Tests/Models/ReadOnlyPagedCollectionTests.cs b/Octokit.Tests/Models/ReadOnlyPagedCollectionTests.cs index 8d2a20bc..2618e60c 100644 --- a/Octokit.Tests/Models/ReadOnlyPagedCollectionTests.cs +++ b/Octokit.Tests/Models/ReadOnlyPagedCollectionTests.cs @@ -19,11 +19,9 @@ namespace Octokit.Tests.Models new ApiResponse>(new Response(), new List {new object(), new object()})); var links = new Dictionary {{"next", nextPageUrl}}; var scopes = new List(); - - var response = new ApiResponse>(new Response - { - ApiInfo = new ApiInfo(links, scopes, scopes, "etag", new RateLimit(new Dictionary())) - }, new List()); + var httpResponse = Substitute.For(); + httpResponse.ApiInfo.Returns(new ApiInfo(links, scopes, scopes, "etag", new RateLimit(new Dictionary()))); + var response = new ApiResponse>(httpResponse, new List()); var connection = Substitute.For(); connection.Get>(nextPageUrl, null, null).Returns(nextPageResponse); var pagedCollection = new ReadOnlyPagedCollection( diff --git a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs index f014de55..58909fcd 100644 --- a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs @@ -46,18 +46,19 @@ public class ObservableIssuesClientTests var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { CreateIssue(1), CreateIssue(2), CreateIssue(3) - }); + } + ); var thirdPageUrl = new Uri("https://example.com/page/3"); var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { CreateIssue(4), @@ -67,7 +68,7 @@ public class ObservableIssuesClientTests ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { CreateIssue(7) @@ -106,7 +107,7 @@ public class ObservableIssuesClientTests var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { CreateIssue(1), @@ -118,7 +119,7 @@ public class ObservableIssuesClientTests var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { CreateIssue(4), @@ -128,10 +129,10 @@ public class ObservableIssuesClientTests ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { - CreateIssue(7 ) + CreateIssue(7) } ); var gitHubClient = Substitute.For(); @@ -167,7 +168,7 @@ public class ObservableIssuesClientTests var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { CreateIssue(1), @@ -179,7 +180,7 @@ public class ObservableIssuesClientTests var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { CreateIssue(4), @@ -189,7 +190,7 @@ public class ObservableIssuesClientTests ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { CreateIssue(7) @@ -228,19 +229,19 @@ public class ObservableIssuesClientTests var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { CreateIssue(1), CreateIssue(2), - CreateIssue(3), + CreateIssue(3) } ); var thirdPageUrl = new Uri("https://example.com/page/3"); var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { CreateIssue(4), @@ -250,10 +251,10 @@ public class ObservableIssuesClientTests ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { - CreateIssue(7), + CreateIssue(7) } ); var gitHubClient = Substitute.For(); @@ -344,14 +345,17 @@ public class ObservableIssuesClientTests } } - static ApiInfo CreateApiInfo(IDictionary links) - { - return new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary())); - } - static Issue CreateIssue(int issueNumber) { var serializer = new SimpleJsonSerializer(); return serializer.Deserialize(@"{""number"": """ + issueNumber + @"""}"); } + + static IResponse CreateResponseWithApiInfo(IDictionary links) + { + var apiInfo = new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary())); + var response = Substitute.For(); + response.ApiInfo.Returns(apiInfo); + return response; + } } diff --git a/Octokit.Tests/Reactive/ObservableMilestonesClientTests.cs b/Octokit.Tests/Reactive/ObservableMilestonesClientTests.cs index 1bfe491c..2a6fc711 100644 --- a/Octokit.Tests/Reactive/ObservableMilestonesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableMilestonesClientTests.cs @@ -47,7 +47,7 @@ namespace Octokit.Tests.Reactive var firstPageLinks = new Dictionary {{"next", secondPageUrl}}; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { new Milestone {Number = 1}, @@ -59,7 +59,7 @@ namespace Octokit.Tests.Reactive var secondPageLinks = new Dictionary {{"next", thirdPageUrl}}; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { new Milestone {Number = 4}, @@ -69,7 +69,7 @@ namespace Octokit.Tests.Reactive ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { new Milestone {Number = 7}, @@ -100,7 +100,7 @@ namespace Octokit.Tests.Reactive var firstPageLinks = new Dictionary {{"next", secondPageUrl}}; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { new Milestone {Number = 1}, @@ -112,7 +112,7 @@ namespace Octokit.Tests.Reactive var secondPageLinks = new Dictionary {{"next", thirdPageUrl}}; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { new Milestone {Number = 4}, @@ -122,7 +122,7 @@ namespace Octokit.Tests.Reactive ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { new Milestone {Number = 7}, @@ -241,9 +241,11 @@ namespace Octokit.Tests.Reactive } } - static ApiInfo CreateApiInfo(IDictionary links) + static IResponse CreateResponseWithApiInfo(IDictionary links) { - return new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary())); + var response = Substitute.For(); + response.ApiInfo.Returns(new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary()))); + return response; } } } diff --git a/Octokit.Tests/Reactive/ObservablePullRequestReviewCommentsClientTests.cs b/Octokit.Tests/Reactive/ObservablePullRequestReviewCommentsClientTests.cs index c83cd2fd..10b0343d 100644 --- a/Octokit.Tests/Reactive/ObservablePullRequestReviewCommentsClientTests.cs +++ b/Octokit.Tests/Reactive/ObservablePullRequestReviewCommentsClientTests.cs @@ -12,9 +12,11 @@ namespace Octokit.Tests.Reactive { public class ObservablePullRequestReviewCommentsClientTests { - static ApiInfo CreateApiInfo(IDictionary links) + static IResponse CreateResponseWithApiInfo(IDictionary links) { - return new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary())); + var response = Substitute.For(); + response.ApiInfo.Returns(new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary()))); + return response; } public class TheGetForPullRequestMethod @@ -27,7 +29,7 @@ namespace Octokit.Tests.Reactive var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { new PullRequestReviewComment {Id = 1}, @@ -38,7 +40,7 @@ namespace Octokit.Tests.Reactive var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { new PullRequestReviewComment {Id = 4}, @@ -48,7 +50,7 @@ namespace Octokit.Tests.Reactive ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { new PullRequestReviewComment {Id = 7} @@ -98,7 +100,7 @@ namespace Octokit.Tests.Reactive var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { new PullRequestReviewComment {Id = 1}, @@ -110,7 +112,7 @@ namespace Octokit.Tests.Reactive var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { new PullRequestReviewComment {Id = 4}, @@ -119,7 +121,7 @@ namespace Octokit.Tests.Reactive }); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { new PullRequestReviewComment {Id = 7}, @@ -169,7 +171,7 @@ namespace Octokit.Tests.Reactive var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { new PullRequestReviewComment {Id = 1}, @@ -181,7 +183,7 @@ namespace Octokit.Tests.Reactive var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { new PullRequestReviewComment {Id = 4}, @@ -190,7 +192,7 @@ namespace Octokit.Tests.Reactive }); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { new PullRequestReviewComment {Id = 7}, diff --git a/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs b/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs index e074574c..054a2ffd 100644 --- a/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs +++ b/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs @@ -47,7 +47,7 @@ namespace Octokit.Tests.Reactive var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { new PullRequest {Number = 1}, @@ -59,7 +59,7 @@ namespace Octokit.Tests.Reactive var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { new PullRequest {Number = 4}, @@ -69,7 +69,7 @@ namespace Octokit.Tests.Reactive ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { new PullRequest {Number = 7}, @@ -100,7 +100,7 @@ namespace Octokit.Tests.Reactive var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { new PullRequest {Number = 1}, @@ -112,7 +112,7 @@ namespace Octokit.Tests.Reactive var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { new PullRequest {Number = 4}, @@ -122,7 +122,7 @@ namespace Octokit.Tests.Reactive ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { new PullRequest {Number = 7}, @@ -282,12 +282,7 @@ namespace Octokit.Tests.Reactive var connection = Substitute.For(); IApiResponse> response = new ApiResponse> ( - new Response { ApiInfo = new ApiInfo( - new Dictionary(), - new List(), - new List(), - "", - new RateLimit(new Dictionary()))}, + new Response(), new List { commit } ); connection.Get>(Args.Uri, null, null) @@ -324,9 +319,11 @@ namespace Octokit.Tests.Reactive } } - static ApiInfo CreateApiInfo(IDictionary links) + static IResponse CreateResponseWithApiInfo(IDictionary links) { - return new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary())); + var response = Substitute.For(); + response.ApiInfo.Returns(new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary()))); + return response; } } } diff --git a/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs b/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs index 47f72b0b..21349be3 100644 --- a/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs @@ -49,7 +49,7 @@ namespace Octokit.Tests.Reactive var secondPageUrl = new Uri("https://example.com/page/2"); var firstPageLinks = new Dictionary {{"next", secondPageUrl}}; var firstPageResponse = new ApiResponse>( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { new Repository { Id = 1 }, @@ -60,7 +60,7 @@ namespace Octokit.Tests.Reactive var secondPageLinks = new Dictionary {{"next", thirdPageUrl}}; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { new Repository {Id = 4}, @@ -68,7 +68,7 @@ namespace Octokit.Tests.Reactive new Repository {Id = 6} }); var lastPageResponse = new ApiResponse>( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { new Repository { Id = 7 } @@ -98,7 +98,7 @@ namespace Octokit.Tests.Reactive var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; var firstPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(firstPageLinks) }, + CreateResponseWithApiInfo(firstPageLinks), new List { new Repository {Id = 1}, @@ -110,7 +110,7 @@ namespace Octokit.Tests.Reactive var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; var secondPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(secondPageLinks) }, + CreateResponseWithApiInfo(secondPageLinks), new List { new Repository {Id = 4}, @@ -123,7 +123,7 @@ namespace Octokit.Tests.Reactive var thirdPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(thirdPageLinks) }, + CreateResponseWithApiInfo(thirdPageLinks), new List { new Repository {Id = 7} @@ -131,7 +131,7 @@ namespace Octokit.Tests.Reactive ); var lastPageResponse = new ApiResponse> ( - new Response { ApiInfo = CreateApiInfo(new Dictionary()) }, + new Response(), new List { new Repository {Id = 8} @@ -408,9 +408,11 @@ namespace Octokit.Tests.Reactive } } - static ApiInfo CreateApiInfo(IDictionary links) + static IResponse CreateResponseWithApiInfo(IDictionary links) { - return new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary())); + var response = Substitute.For(); + response.ApiInfo.Returns(new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary()))); + return response; } } } diff --git a/Octokit/Http/ApiInfoParser.cs b/Octokit/Http/ApiInfoParser.cs index be87292f..c0878be9 100644 --- a/Octokit/Http/ApiInfoParser.cs +++ b/Octokit/Http/ApiInfoParser.cs @@ -5,7 +5,7 @@ using System.Text.RegularExpressions; namespace Octokit.Internal { - internal static class ApiInfoParser + public static class ApiInfoParser { const RegexOptions regexOptions = #if NETFX_CORE @@ -17,21 +17,7 @@ namespace Octokit.Internal static readonly Regex _linkRelRegex = new Regex("rel=\"(next|prev|first|last)\"", regexOptions); static readonly Regex _linkUriRegex = new Regex("<(.+)>", regexOptions); - public static void ParseApiHttpHeaders(IResponse response) - { - Ensure.ArgumentNotNull(response, "response"); - - response.ApiInfo = ParseHeaders(response); - } - - static ApiInfo ParseHeaders(IResponse response) - { - Ensure.ArgumentNotNull(response, "response"); - - return ParseResponseHeaders(response.Headers); - } - - static ApiInfo ParseResponseHeaders(IDictionary responseHeaders) + public static ApiInfo ParseResponseHeaders(IDictionary responseHeaders) { Ensure.ArgumentNotNull(responseHeaders, "responseHeaders"); diff --git a/Octokit/Http/ApiResponse.cs b/Octokit/Http/ApiResponse.cs index a71198d6..e68f8a6f 100644 --- a/Octokit/Http/ApiResponse.cs +++ b/Octokit/Http/ApiResponse.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Net; namespace Octokit.Internal @@ -16,9 +17,8 @@ namespace Octokit.Internal var body = response.Body is T ? (T)response.Body : default(T); HttpResponse = response; - Headers = response.Headers; + Headers = new ReadOnlyDictionary(response.Headers); Body = body; - ResponseUri = response.ResponseUri; ApiInfo = response.ApiInfo; StatusCode = response.StatusCode; ContentType = response.ContentType; @@ -26,8 +26,7 @@ namespace Octokit.Internal } public T Body { get; private set; } - public Dictionary Headers { get; private set; } - public Uri ResponseUri { get; set; } + public IReadOnlyDictionary Headers { get; private set; } public ApiInfo ApiInfo { get; set; } public HttpStatusCode StatusCode { get; set; } public IResponse HttpResponse { get; private set; } diff --git a/Octokit/Http/Connection.cs b/Octokit/Http/Connection.cs index b953c446..8875666f 100644 --- a/Octokit/Http/Connection.cs +++ b/Octokit/Http/Connection.cs @@ -432,7 +432,6 @@ namespace Octokit request.Headers.Add("User-Agent", UserAgent); await _authenticator.Apply(request).ConfigureAwait(false); var response = await _httpClient.Send(request, cancellationToken).ConfigureAwait(false); - ApiInfoParser.ParseApiHttpHeaders(response); HandleErrors(response); return response; } diff --git a/Octokit/Http/HttpClientAdapter.cs b/Octokit/Http/HttpClientAdapter.cs index 0ea7f2da..b2540cec 100644 --- a/Octokit/Http/HttpClientAdapter.cs +++ b/Octokit/Http/HttpClientAdapter.cs @@ -88,19 +88,12 @@ namespace Octokit.Internal } } - var response = new Response + return new Response(responseMessage.Headers.ToDictionary(h => h.Key, h => h.Value.First())) { Body = responseBody, StatusCode = responseMessage.StatusCode, - ContentType = contentType + ContentType = contentType, }; - - foreach (var h in responseMessage.Headers) - { - response.Headers.Add(h.Key, h.Value.First()); - } - - return response; } protected virtual HttpRequestMessage BuildRequestMessage(IRequest request) diff --git a/Octokit/Http/IResponse.cs b/Octokit/Http/IResponse.cs index c2e65f72..1cb48260 100644 --- a/Octokit/Http/IResponse.cs +++ b/Octokit/Http/IResponse.cs @@ -18,10 +18,9 @@ namespace Octokit public interface IResponse { object Body { get; } - Dictionary Headers { get; } - Uri ResponseUri { get; set; } - ApiInfo ApiInfo { get; set; } - HttpStatusCode StatusCode { get; set; } - string ContentType { get; set; } + IDictionary Headers { get; } + ApiInfo ApiInfo { get; } + HttpStatusCode StatusCode { get; } + string ContentType { get; } } } diff --git a/Octokit/Http/Response.cs b/Octokit/Http/Response.cs index 397b13fe..dc8437c5 100644 --- a/Octokit/Http/Response.cs +++ b/Octokit/Http/Response.cs @@ -1,20 +1,27 @@ using System; using System.Collections.Generic; using System.Net; +using Octokit.Internal; namespace Octokit.Internal { public class Response : IResponse { - public Response() + public Response() : this(new Dictionary()) { - Headers = new Dictionary(); + } + + public Response(IDictionary headers) + { + Ensure.ArgumentNotNull(headers, "headers"); + + Headers = headers; + ApiInfo = ApiInfoParser.ParseResponseHeaders(headers); } public object Body { get; set; } - public Dictionary Headers { get; private set; } - public Uri ResponseUri { get; set; } - public ApiInfo ApiInfo { get; set; } + public IDictionary Headers { get; private set; } + public ApiInfo ApiInfo { get; private set; } public HttpStatusCode StatusCode { get; set; } public string ContentType { get; set; } }