diff --git a/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs b/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs index 9460a197..25337bab 100644 --- a/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs +++ b/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs @@ -50,6 +50,18 @@ namespace Octokit.Reactive 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 9c17dbf8..1a173d9c 100644 --- a/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs +++ b/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs @@ -102,6 +102,21 @@ namespace Octokit.Reactive 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.Tests.Integration/Clients/RepositoriesClientTests.cs b/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs index b6c935e2..6c40f537 100644 --- a/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs @@ -553,20 +553,20 @@ public class RepositoriesClientTests Assert.True(repositories.Count > 80); } - //[IntegrationTest] - //public async Task ReturnsAllPublicRepositoriesSinceLastSeen() - //{ - // var github = Helper.GetAuthenticatedClient(); + [IntegrationTest] + public async Task ReturnsAllPublicRepositoriesSinceLastSeen() + { + var github = Helper.GetAuthenticatedClient(); - // var request = new PublicRepositoryRequest(32732250); - // var repositories = await github.Repository.GetAllPublic(request); + var request = new PublicRepositoryRequest(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); - //} + 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 68341f58..397eb663 100644 --- a/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/Reactive/ObservableRepositoriesClientTests.cs @@ -28,5 +28,22 @@ namespace Octokit.Tests.Integration Assert.False(repository2.Fork); } } + + public class TheGetAllPublicSinceMethod + { + [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(); + + var client = new ObservableRepositoriesClient(github); + var request = new PublicRepositoryRequest(32732250); + var repositories = await client.GetAllPublic(request).ToArray(); + Assert.NotEmpty(repositories); + 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 0534472b..ed73c0f7 100644 --- a/Octokit.Tests/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests/Clients/RepositoriesClientTests.cs @@ -273,6 +273,37 @@ namespace Octokit.Tests.Clients } } + + public class TheGetAllPublicSinceMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoriesClient(connection); + + client.GetAllPublic(new PublicRepositoryRequest(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(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 044a74d7..d1668b14 100644 --- a/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs @@ -158,6 +158,65 @@ namespace Octokit.Tests.Reactive } } + 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 } }; + IApiResponse> 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 } }; + IApiResponse> secondPageResponse = new ApiResponse> + ( + CreateResponseWithApiInfo(secondPageLinks), + new List + { + new Repository(367), + new Repository(368), + new Repository(369) + }); + + 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.FromResult(firstPageResponse)); + gitHubClient.Connection.Get>(secondPageUrl, null, null) + .Returns(Task.FromResult(secondPageResponse)); + gitHubClient.Connection.Get>(thirdPageUrl, null, null) + .Returns(Task.FromResult(lastPageResponse)); + + var repositoriesClient = new ObservableRepositoriesClient(gitHubClient); + + var results = await repositoriesClient.GetAllPublic(new PublicRepositoryRequest(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] diff --git a/Octokit/Clients/IRepositoriesClient.cs b/Octokit/Clients/IRepositoriesClient.cs index 7172f0f4..e6f07092 100644 --- a/Octokit/Clients/IRepositoriesClient.cs +++ b/Octokit/Clients/IRepositoriesClient.cs @@ -109,6 +109,20 @@ namespace Octokit 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 5de9ceec..479ac89f 100644 --- a/Octokit/Clients/RepositoriesClient.cs +++ b/Octokit/Clients/RepositoriesClient.cs @@ -188,6 +188,24 @@ namespace Octokit 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. ///