From 01665bce78276b838b2344a354e511eca2aabacd Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Mon, 23 Mar 2015 23:22:47 +1000 Subject: [PATCH 1/4] Add 'since` parameter for public repositories --- .../Clients/IObservableRepositoriesClient.cs | 14 +++++++++- .../Clients/ObservableRepositoriesClient.cs | 15 ++++++++++ Octokit/Clients/IRepositoriesClient.cs | 14 ++++++++++ Octokit/Clients/RepositoriesClient.cs | 19 +++++++++++++ .../Models/Request/PublicRepositoryRequest.cs | 28 +++++++++++++++++++ Octokit/Octokit-Mono.csproj | 1 + Octokit/Octokit-MonoAndroid.csproj | 1 + Octokit/Octokit-Monotouch.csproj | 1 + Octokit/Octokit-Portable.csproj | 1 + Octokit/Octokit-netcore45.csproj | 1 + Octokit/Octokit.csproj | 1 + 11 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 Octokit/Models/Request/PublicRepositoryRequest.cs diff --git a/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs b/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs index 222cea8200..25337bab3c 100644 --- a/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs +++ b/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs @@ -49,7 +49,19 @@ public interface IObservableRepositoriesClient [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Makes a network request")] IObservable GetAllPublic(); - + + /// + /// Retrieves every public since the last repository seen. + /// + /// + /// The default page size on GitHub.com is 30. + /// + /// Search parameters of the last repository seen + /// A of . + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", + Justification = "Makes a network request")] + IObservable GetAllPublic(PublicRepositoryRequest request); + /// /// Retrieves every that belongs to the current user. /// diff --git a/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs b/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs index 9c17dbf800..1a173d9c88 100644 --- a/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs +++ b/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs @@ -102,6 +102,21 @@ public IObservable GetAllPublic() return _connection.GetAndFlattenAllPages(ApiUrls.AllPublicRepositories()); } + /// + /// Retrieves every public since the last repository seen. + /// + /// + /// The default page size on GitHub.com is 30. + /// + /// Search parameters of the last repository seen + /// A of . + public IObservable GetAllPublic(PublicRepositoryRequest request) + { + Ensure.ArgumentNotNull(request, "request"); + + return _connection.GetAndFlattenAllPages(ApiUrls.AllPublicRepositories(), request.ToParametersDictionary()); + } + /// /// Retrieves every that belongs to the current user. /// diff --git a/Octokit/Clients/IRepositoriesClient.cs b/Octokit/Clients/IRepositoriesClient.cs index 7172f0f444..1853359742 100644 --- a/Octokit/Clients/IRepositoriesClient.cs +++ b/Octokit/Clients/IRepositoriesClient.cs @@ -109,6 +109,20 @@ public interface IRepositoriesClient Justification = "Makes a network request")] Task> GetAllPublic(); + + /// + /// Gets all public repositories since the integer ID of the last Repository that you�ve seen. + /// + /// + /// See the API documentation for more information. + /// The default page size on GitHub.com is 30. + /// + /// Search parameters of the last repository seen + /// Thrown if the client is not authenticated. + /// Thrown when a general API error occurs. + /// A of . + Task> GetAllPublic(PublicRepositoryRequest request); + /// /// Gets all repositories owned by the current user. /// diff --git a/Octokit/Clients/RepositoriesClient.cs b/Octokit/Clients/RepositoriesClient.cs index 25deeae7ac..6bb9c6a471 100644 --- a/Octokit/Clients/RepositoriesClient.cs +++ b/Octokit/Clients/RepositoriesClient.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; #if NET_45 using System.Collections.Generic; #endif @@ -187,6 +188,24 @@ public Task> GetAllPublic() return ApiConnection.GetAll(ApiUrls.AllPublicRepositories()); } + /// + /// Gets all public repositories since the integer ID of the last Repository that you�ve seen. + /// + /// + /// See the API documentation for more information. + /// The default page size on GitHub.com is 30. + /// + /// Search parameters of the last repository seen + /// Thrown if the client is not authenticated. + /// Thrown when a general API error occurs. + /// A of . + public Task> GetAllPublic(PublicRepositoryRequest request) + { + Ensure.ArgumentNotNull(request, "request"); + + return ApiConnection.GetAll(ApiUrls.AllPublicRepositories(), request.ToParametersDictionary()); + } + /// /// Gets all repositories owned by the current user. /// diff --git a/Octokit/Models/Request/PublicRepositoryRequest.cs b/Octokit/Models/Request/PublicRepositoryRequest.cs new file mode 100644 index 0000000000..926374a980 --- /dev/null +++ b/Octokit/Models/Request/PublicRepositoryRequest.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Octokit +{ + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class PublicRepositoryRequest : RequestParameters + { + public PublicRepositoryRequest() + { + } + + public long Since { get; set; } + + internal string DebuggerDisplay + { + get + { + return String.Format(CultureInfo.InvariantCulture, "Since: {0} ", Since); + } + } + } +} diff --git a/Octokit/Octokit-Mono.csproj b/Octokit/Octokit-Mono.csproj index 08b522f479..d9f81fc272 100644 --- a/Octokit/Octokit-Mono.csproj +++ b/Octokit/Octokit-Mono.csproj @@ -382,6 +382,7 @@ + \ No newline at end of file diff --git a/Octokit/Octokit-MonoAndroid.csproj b/Octokit/Octokit-MonoAndroid.csproj index 03023e21af..897b2a739b 100644 --- a/Octokit/Octokit-MonoAndroid.csproj +++ b/Octokit/Octokit-MonoAndroid.csproj @@ -394,6 +394,7 @@ + \ No newline at end of file diff --git a/Octokit/Octokit-Monotouch.csproj b/Octokit/Octokit-Monotouch.csproj index 29d7faa3e4..997f94e70d 100644 --- a/Octokit/Octokit-Monotouch.csproj +++ b/Octokit/Octokit-Monotouch.csproj @@ -387,6 +387,7 @@ + diff --git a/Octokit/Octokit-Portable.csproj b/Octokit/Octokit-Portable.csproj index 377001e6d5..55d10491af 100644 --- a/Octokit/Octokit-Portable.csproj +++ b/Octokit/Octokit-Portable.csproj @@ -380,6 +380,7 @@ + diff --git a/Octokit/Octokit-netcore45.csproj b/Octokit/Octokit-netcore45.csproj index 53942c2626..65291e0a0f 100644 --- a/Octokit/Octokit-netcore45.csproj +++ b/Octokit/Octokit-netcore45.csproj @@ -384,6 +384,7 @@ + diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index 98eb49c4a7..fdf8c32ffa 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -83,6 +83,7 @@ + From 818f730a6c669b834679120508f130dafb527426 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Mon, 23 Mar 2015 23:23:08 +1000 Subject: [PATCH 2/4] Add tests --- .../Clients/RepositoriesClientTests.cs | 15 +++++ .../ObservableRepositoriesClientTests.cs | 24 +++++++- .../Clients/RepositoriesClientTests.cs | 31 +++++++++++ .../ObservableRepositoriesClientTests.cs | 55 +++++++++++++++++++ 4 files changed, 124 insertions(+), 1 deletion(-) diff --git a/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs b/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs index cc0bddeb70..0117463a66 100644 --- a/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs @@ -552,6 +552,21 @@ public async Task ReturnsAllPublicRepositories() Assert.True(repositories.Count > 80); } + + [IntegrationTest] + public async Task ReturnsAllPublicRepositoriesSinceLastSeen() + { + var github = Helper.GetAuthenticatedClient(); + + var request = new PublicRepositoryRequest { Since = 32732250 }; + var repositories = await github.Repository.GetAllPublic(request); + + Assert.NotNull(repositories); + Assert.True(repositories.Any()); + Assert.Equal(32732252, repositories[0].Id); + Assert.False(repositories[0].Private); + Assert.Equal("zad19", repositories[0].Name); + } } public class TheGetAllForOrgMethod diff --git a/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs index fe5294b834..3a63339e25 100644 --- a/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs @@ -1,4 +1,5 @@ -using System.Reactive.Linq; +using System.Linq; +using System.Reactive.Linq; using System.Threading.Tasks; using Octokit.Reactive; using Xunit; @@ -27,5 +28,26 @@ public async Task ReturnsSpecifiedRepository() Assert.False(repository2.Fork); } } + + public class TheGetAllPublicSinceMethod + { + [IntegrationTest] + public async Task ReturnsAllPublicReposSinceLastSeen() + { + var github = Helper.GetAuthenticatedClient(); + + var client = new ObservableRepositoriesClient(github); + var request = new PublicRepositoryRequest + { + Since = 32732250 + }; + var repositories = await client.GetAllPublic(request).ToArray(); + Assert.NotNull(repositories); + Assert.True(repositories.Any()); + Assert.Equal(32732252, repositories[0].Id); + Assert.False(repositories[0].Private); + Assert.Equal("zad19", repositories[0].Name); + } + } } } diff --git a/Octokit.Tests/Clients/RepositoriesClientTests.cs b/Octokit.Tests/Clients/RepositoriesClientTests.cs index 0534472bd8..1dcb57877a 100644 --- a/Octokit.Tests/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests/Clients/RepositoriesClientTests.cs @@ -273,6 +273,37 @@ public void RequestsTheCorrectUrlAndReturnsRepositories() } } + + public class TheGetAllPublicSinceMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoriesClient(connection); + + client.GetAllPublic(new PublicRepositoryRequest { Since = 364 }); + + connection.Received() + .GetAll(Arg.Is(u => u.ToString() == "/repositories"), + Arg.Any>()); + } + + [Fact] + public void SendsTheCorrectParameter() + { + var connection = Substitute.For(); + var client = new RepositoriesClient(connection); + + client.GetAllPublic(new PublicRepositoryRequest { Since = 364 }); + + connection.Received() + .GetAll(Arg.Is(u => u.ToString() == "/repositories"), + Arg.Is>(d => d.Count == 1 + && d["since"] == "364")); + } + } + public class TheGetAllForCurrentMethod { [Fact] diff --git a/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs b/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs index 044a74d76a..a69ab0b213 100644 --- a/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs @@ -158,6 +158,61 @@ public async Task StopsMakingNewRequestsWhenTakeIsFulfilled() } } + public class TheGetAllPublicRepositoriesSinceMethod + { + [Fact] + public async Task ReturnsEveryPageOfRepositories() + { + var firstPageUrl = new Uri("/repositories", UriKind.Relative); + var secondPageUrl = new Uri("https://example.com/page/2"); + var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; + var firstPageResponse = new ApiResponse>( + CreateResponseWithApiInfo(firstPageLinks), + new List + { + new Repository(364), + new Repository(365), + new Repository(366) + }); + var thirdPageUrl = new Uri("https://example.com/page/3"); + var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; + var secondPageResponse = new ApiResponse> + ( + CreateResponseWithApiInfo(secondPageLinks), + new List + { + new Repository(367), + new Repository(368), + new Repository(369) + }); + var lastPageResponse = new ApiResponse>( + new Response(), + new List + { + new Repository(370) + }); + var gitHubClient = Substitute.For(); + gitHubClient.Connection.Get>(firstPageUrl, + Arg.Is>(d => d.Count == 1 + && d["since"] == "364"), null) + .Returns(Task.Factory.StartNew>>(() => firstPageResponse)); + gitHubClient.Connection.Get>(secondPageUrl, null, null) + .Returns(Task.Factory.StartNew>>(() => secondPageResponse)); + gitHubClient.Connection.Get>(thirdPageUrl, null, null) + .Returns(Task.Factory.StartNew>>(() => lastPageResponse)); + var repositoriesClient = new ObservableRepositoriesClient(gitHubClient); + + var results = await repositoriesClient.GetAllPublic(new PublicRepositoryRequest { Since = 364 }).ToArray(); + + Assert.Equal(7, results.Length); + gitHubClient.Connection.Received(1).Get>(firstPageUrl, + Arg.Is>(d=>d.Count == 1 + && d["since"] == "364"), null); + gitHubClient.Connection.Received(1).Get>(secondPageUrl, null, null); + gitHubClient.Connection.Received(1).Get>(thirdPageUrl, null, null); + } + } + public class TheGetAllBranchesMethod { [Fact] From ca01a2f2e82323df678c784ec967c0f80f12d284 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Wed, 25 Mar 2015 13:09:46 +1000 Subject: [PATCH 3/4] Update Assert call and mute the test --- .../Reactive/ObservableRepositoriesClientTests.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs index 3a63339e25..6f870c8102 100644 --- a/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs @@ -31,7 +31,7 @@ public async Task ReturnsSpecifiedRepository() public class TheGetAllPublicSinceMethod { - [IntegrationTest] + [IntegrationTest(Skip = "This will take a very long time to return, so will skip it for now.")] public async Task ReturnsAllPublicReposSinceLastSeen() { var github = Helper.GetAuthenticatedClient(); @@ -42,8 +42,7 @@ public async Task ReturnsAllPublicReposSinceLastSeen() Since = 32732250 }; var repositories = await client.GetAllPublic(request).ToArray(); - Assert.NotNull(repositories); - Assert.True(repositories.Any()); + Assert.NotEmpty(repositories); Assert.Equal(32732252, repositories[0].Id); Assert.False(repositories[0].Private); Assert.Equal("zad19", repositories[0].Name); From 68840e317f070ac4b4fccc6705f3b4c11985e0de Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Tue, 7 Apr 2015 07:15:14 +1000 Subject: [PATCH 4/4] Making the `since` parameter required Adding :lipstick: `Task.FromResult` to tests --- .../Clients/RepositoriesClientTests.cs | 2 +- .../ObservableRepositoriesClientTests.cs | 5 +---- .../Clients/RepositoriesClientTests.cs | 4 ++-- .../ObservableRepositoriesClientTests.cs | 18 +++++++++++------- Octokit/Clients/IRepositoriesClient.cs | 2 +- Octokit/Clients/RepositoriesClient.cs | 2 +- .../Models/Request/PublicRepositoryRequest.cs | 5 ++++- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs b/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs index 0117463a66..6c40f537d8 100644 --- a/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs @@ -558,7 +558,7 @@ public async Task ReturnsAllPublicRepositoriesSinceLastSeen() { var github = Helper.GetAuthenticatedClient(); - var request = new PublicRepositoryRequest { Since = 32732250 }; + var request = new PublicRepositoryRequest(32732250); var repositories = await github.Repository.GetAllPublic(request); Assert.NotNull(repositories); diff --git a/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs index 6f870c8102..397eb66390 100644 --- a/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs @@ -37,10 +37,7 @@ public async Task ReturnsAllPublicReposSinceLastSeen() var github = Helper.GetAuthenticatedClient(); var client = new ObservableRepositoriesClient(github); - var request = new PublicRepositoryRequest - { - Since = 32732250 - }; + var request = new PublicRepositoryRequest(32732250); var repositories = await client.GetAllPublic(request).ToArray(); Assert.NotEmpty(repositories); Assert.Equal(32732252, repositories[0].Id); diff --git a/Octokit.Tests/Clients/RepositoriesClientTests.cs b/Octokit.Tests/Clients/RepositoriesClientTests.cs index 1dcb57877a..ed73c0f781 100644 --- a/Octokit.Tests/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests/Clients/RepositoriesClientTests.cs @@ -282,7 +282,7 @@ public void RequestsTheCorrectUrl() var connection = Substitute.For(); var client = new RepositoriesClient(connection); - client.GetAllPublic(new PublicRepositoryRequest { Since = 364 }); + client.GetAllPublic(new PublicRepositoryRequest(364)); connection.Received() .GetAll(Arg.Is(u => u.ToString() == "/repositories"), @@ -295,7 +295,7 @@ public void SendsTheCorrectParameter() var connection = Substitute.For(); var client = new RepositoriesClient(connection); - client.GetAllPublic(new PublicRepositoryRequest { Since = 364 }); + client.GetAllPublic(new PublicRepositoryRequest(364)); connection.Received() .GetAll(Arg.Is(u => u.ToString() == "/repositories"), diff --git a/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs b/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs index a69ab0b213..d1668b14d7 100644 --- a/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs @@ -166,7 +166,7 @@ public async Task ReturnsEveryPageOfRepositories() var firstPageUrl = new Uri("/repositories", UriKind.Relative); var secondPageUrl = new Uri("https://example.com/page/2"); var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; - var firstPageResponse = new ApiResponse>( + IApiResponse> firstPageResponse = new ApiResponse>( CreateResponseWithApiInfo(firstPageLinks), new List { @@ -174,9 +174,10 @@ public async Task ReturnsEveryPageOfRepositories() new Repository(365), new Repository(366) }); + var thirdPageUrl = new Uri("https://example.com/page/3"); var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; - var secondPageResponse = new ApiResponse> + IApiResponse> secondPageResponse = new ApiResponse> ( CreateResponseWithApiInfo(secondPageLinks), new List @@ -185,24 +186,27 @@ public async Task ReturnsEveryPageOfRepositories() new Repository(368), new Repository(369) }); - var lastPageResponse = new ApiResponse>( + + IApiResponse> lastPageResponse = new ApiResponse>( new Response(), new List { new Repository(370) }); + var gitHubClient = Substitute.For(); gitHubClient.Connection.Get>(firstPageUrl, Arg.Is>(d => d.Count == 1 && d["since"] == "364"), null) - .Returns(Task.Factory.StartNew>>(() => firstPageResponse)); + .Returns(Task.FromResult(firstPageResponse)); gitHubClient.Connection.Get>(secondPageUrl, null, null) - .Returns(Task.Factory.StartNew>>(() => secondPageResponse)); + .Returns(Task.FromResult(secondPageResponse)); gitHubClient.Connection.Get>(thirdPageUrl, null, null) - .Returns(Task.Factory.StartNew>>(() => lastPageResponse)); + .Returns(Task.FromResult(lastPageResponse)); + var repositoriesClient = new ObservableRepositoriesClient(gitHubClient); - var results = await repositoriesClient.GetAllPublic(new PublicRepositoryRequest { Since = 364 }).ToArray(); + var results = await repositoriesClient.GetAllPublic(new PublicRepositoryRequest(364)).ToArray(); Assert.Equal(7, results.Length); gitHubClient.Connection.Received(1).Get>(firstPageUrl, diff --git a/Octokit/Clients/IRepositoriesClient.cs b/Octokit/Clients/IRepositoriesClient.cs index 1853359742..e6f0709202 100644 --- a/Octokit/Clients/IRepositoriesClient.cs +++ b/Octokit/Clients/IRepositoriesClient.cs @@ -111,7 +111,7 @@ public interface IRepositoriesClient /// - /// Gets all public repositories since the integer ID of the last Repository that you�ve seen. + /// Gets all public repositories since the integer ID of the last Repository that you've seen. /// /// /// See the API documentation for more information. diff --git a/Octokit/Clients/RepositoriesClient.cs b/Octokit/Clients/RepositoriesClient.cs index 6bb9c6a471..479ac89f35 100644 --- a/Octokit/Clients/RepositoriesClient.cs +++ b/Octokit/Clients/RepositoriesClient.cs @@ -189,7 +189,7 @@ public Task> GetAllPublic() } /// - /// Gets all public repositories since the integer ID of the last Repository that you�ve seen. + /// Gets all public repositories since the integer ID of the last Repository that you've seen. /// /// /// See the API documentation for more information. diff --git a/Octokit/Models/Request/PublicRepositoryRequest.cs b/Octokit/Models/Request/PublicRepositoryRequest.cs index 926374a980..d66fdb528f 100644 --- a/Octokit/Models/Request/PublicRepositoryRequest.cs +++ b/Octokit/Models/Request/PublicRepositoryRequest.cs @@ -11,8 +11,11 @@ namespace Octokit [DebuggerDisplay("{DebuggerDisplay,nq}")] public class PublicRepositoryRequest : RequestParameters { - public PublicRepositoryRequest() + public PublicRepositoryRequest(int since) { + Ensure.ArgumentNotNull(since, "since"); + + Since = since; } public long Since { get; set; }