diff --git a/Octokit.Reactive/Clients/IObservableReferencesClient.cs b/Octokit.Reactive/Clients/IObservableReferencesClient.cs index a1ff6dc1..5a178778 100644 --- a/Octokit.Reactive/Clients/IObservableReferencesClient.cs +++ b/Octokit.Reactive/Clients/IObservableReferencesClient.cs @@ -50,6 +50,18 @@ namespace Octokit.Reactive /// IObservable GetAll(string owner, string name); + /// + /// Gets all references for a given repository + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The owner of the repository + /// The name of the repository + /// Options for changing the API response + /// + IObservable GetAll(string owner, string name, ApiOptions options); + /// /// Gets all references for a given repository /// @@ -60,6 +72,17 @@ namespace Octokit.Reactive /// IObservable GetAll(long repositoryId); + /// + /// Gets all references for a given repository + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The Id of the repository + /// Options for changing the API response + /// + IObservable GetAll(long repositoryId, ApiOptions options); + /// /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" /// @@ -72,6 +95,19 @@ namespace Octokit.Reactive /// IObservable GetAllForSubNamespace(string owner, string name, string subNamespace); + /// + /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The owner of the repository + /// The name of the repository + /// The sub-namespace to get references for + /// Options for changing the API response + /// + IObservable GetAllForSubNamespace(string owner, string name, string subNamespace, ApiOptions options); + /// /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" /// @@ -83,6 +119,18 @@ namespace Octokit.Reactive /// IObservable GetAllForSubNamespace(long repositoryId, string subNamespace); + /// + /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The Id of the repository + /// The sub-namespace to get references for + /// Options for changing the API response + /// + IObservable GetAllForSubNamespace(long repositoryId, string subNamespace, ApiOptions options); + /// /// Creates a reference for a given repository /// diff --git a/Octokit.Reactive/Clients/ObservableReferencesClient.cs b/Octokit.Reactive/Clients/ObservableReferencesClient.cs index c694c237..bb16a5d3 100644 --- a/Octokit.Reactive/Clients/ObservableReferencesClient.cs +++ b/Octokit.Reactive/Clients/ObservableReferencesClient.cs @@ -69,11 +69,27 @@ namespace Octokit.Reactive /// The name of the repository /// public IObservable GetAll(string owner, string name) + { + return GetAll(owner, name, ApiOptions.None); + } + + /// + /// Gets all references for a given repository + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The owner of the repository + /// The name of the repository + /// Options for changing the API response + /// + public IObservable GetAll(string owner, string name, ApiOptions options) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); + Ensure.ArgumentNotNull(options, "options"); - return _connection.GetAndFlattenAllPages(ApiUrls.Reference(owner, name)); + return _connection.GetAndFlattenAllPages(ApiUrls.Reference(owner, name), options); } /// @@ -86,7 +102,23 @@ namespace Octokit.Reactive /// public IObservable GetAll(long repositoryId) { - return _connection.GetAndFlattenAllPages(ApiUrls.Reference(repositoryId)); + return GetAll(repositoryId, ApiOptions.None); + } + + /// + /// Gets all references for a given repository + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The Id of the repository + /// Options for changing the API response + /// + public IObservable GetAll(long repositoryId, ApiOptions options) + { + Ensure.ArgumentNotNull(options, "options"); + + return _connection.GetAndFlattenAllPages(ApiUrls.Reference(repositoryId), options); } /// @@ -100,12 +132,29 @@ namespace Octokit.Reactive /// The sub-namespace to get references for /// public IObservable GetAllForSubNamespace(string owner, string name, string subNamespace) + { + return GetAllForSubNamespace(owner, name, subNamespace, ApiOptions.None); + } + + /// + /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The owner of the repository + /// The name of the repository + /// The sub-namespace to get references for + /// Options for changing the API response + /// + public IObservable GetAllForSubNamespace(string owner, string name, string subNamespace, ApiOptions options) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(subNamespace, "subNamespace"); + Ensure.ArgumentNotNull(options, "options"); - return _connection.GetAndFlattenAllPages(ApiUrls.Reference(owner, name, subNamespace)); + return _connection.GetAndFlattenAllPages(ApiUrls.Reference(owner, name, subNamespace), options); } /// @@ -119,9 +168,25 @@ namespace Octokit.Reactive /// public IObservable GetAllForSubNamespace(long repositoryId, string subNamespace) { - Ensure.ArgumentNotNullOrEmptyString(subNamespace, "subNamespace"); + return GetAllForSubNamespace(repositoryId, subNamespace, ApiOptions.None); + } - return _connection.GetAndFlattenAllPages(ApiUrls.Reference(repositoryId, subNamespace)); + /// + /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The Id of the repository + /// The sub-namespace to get references for + /// Options for changing the API response + /// + public IObservable GetAllForSubNamespace(long repositoryId, string subNamespace, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(subNamespace, "subNamespace"); + Ensure.ArgumentNotNull(options, "options"); + + return _connection.GetAndFlattenAllPages(ApiUrls.Reference(repositoryId, subNamespace), options); } /// diff --git a/Octokit.Tests.Integration/Clients/ReferencesClientTests.cs b/Octokit.Tests.Integration/Clients/ReferencesClientTests.cs index 7c396f90..35299d20 100644 --- a/Octokit.Tests.Integration/Clients/ReferencesClientTests.cs +++ b/Octokit.Tests.Integration/Clients/ReferencesClientTests.cs @@ -63,6 +63,57 @@ public class ReferencesClientTests : IDisposable Assert.NotEmpty(list); } + [IntegrationTest] + public async Task ReturnsCorrectCountOfReferencesWithStart() + { + var options = new ApiOptions + { + PageSize = 5, + PageCount = 1, + StartPage = 2 + }; + + var references = await _fixture.GetAll("octokit", "octokit.net", options); + + Assert.Equal(5, references.Count); + } + + [IntegrationTest] + public async Task ReturnsCorrectCountOfReferencesWithoutStart() + { + var options = new ApiOptions + { + PageSize = 5, + PageCount = 1 + }; + + var references = await _fixture.GetAll("octokit", "octokit.net", options); + + Assert.Equal(5, references.Count); + } + + [IntegrationTest] + public async Task ReturnsDistinctReferencesBasedOnStartPage() + { + var startOptions = new ApiOptions + { + PageSize = 5, + PageCount = 1 + }; + + var skipStartOptions = new ApiOptions + { + PageSize = 5, + PageCount = 1, + StartPage = 2 + }; + + var firstRefsPage = await _fixture.GetAll("octokit", "octokit.net", startOptions); + var secondRefsPage = await _fixture.GetAll("octokit", "octokit.net", skipStartOptions); + + Assert.False(firstRefsPage.Any(x => secondRefsPage.Contains(x))); + } + [IntegrationTest(Skip = "This is paging for a long long time")] public async Task CanGetListOfReferencesWithRepositoryId() { @@ -70,6 +121,57 @@ public class ReferencesClientTests : IDisposable Assert.NotEmpty(list); } + [IntegrationTest] + public async Task ReturnsCorrectCountOfReferencesWithRepositoryIdWithStart() + { + var options = new ApiOptions + { + PageSize = 5, + PageCount = 1, + StartPage = 2 + }; + + var references = await _fixture.GetAll(7528679, options); + + Assert.Equal(5, references.Count); + } + + [IntegrationTest] + public async Task ReturnsCorrectCountOfReferencesWithRepositoryIdWithoutStart() + { + var options = new ApiOptions + { + PageSize = 5, + PageCount = 1 + }; + + var references = await _fixture.GetAll(7528679, options); + + Assert.Equal(5, references.Count); + } + + [IntegrationTest] + public async Task ReturnsDistinctReferencesWithRepositoryIdBasedOnStartPage() + { + var startOptions = new ApiOptions + { + PageSize = 5, + PageCount = 1 + }; + + var skipStartOptions = new ApiOptions + { + PageSize = 5, + PageCount = 1, + StartPage = 2 + }; + + var firstRefsPage = await _fixture.GetAll(7528679, startOptions); + var secondRefsPage = await _fixture.GetAll(7528679, skipStartOptions); + + Assert.False(firstRefsPage.Any(x => secondRefsPage.Contains(x))); + } + [IntegrationTest] public async Task CanGetListOfReferencesInNamespace() { @@ -77,6 +179,57 @@ public class ReferencesClientTests : IDisposable Assert.NotEmpty(list); } + [IntegrationTest] + public async Task ReturnsCorrectCountOfReferencesInNamespaceWithStart() + { + var options = new ApiOptions + { + PageSize = 5, + PageCount = 1, + StartPage = 2 + }; + + var references = await _fixture.GetAllForSubNamespace("octokit", "octokit.net", "heads", options); + + Assert.Equal(5, references.Count); + } + + [IntegrationTest] + public async Task ReturnsCorrectCountOfReferencesInNamespaceWithoutStart() + { + var options = new ApiOptions + { + PageSize = 5, + PageCount = 1 + }; + + var references = await _fixture.GetAllForSubNamespace("octokit", "octokit.net", "heads", options); + + Assert.Equal(5, references.Count); + } + + [IntegrationTest] + public async Task ReturnsDistinctReferencesInNamespaceBasedOnStartPage() + { + var startOptions = new ApiOptions + { + PageSize = 5, + PageCount = 1 + }; + + var skipStartOptions = new ApiOptions + { + PageSize = 5, + PageCount = 1, + StartPage = 2 + }; + + var firstRefsPage = await _fixture.GetAllForSubNamespace("octokit", "octokit.net", "heads", startOptions); + var secondRefsPage = await _fixture.GetAllForSubNamespace("octokit", "octokit.net", "heads", skipStartOptions); + + Assert.False(firstRefsPage.Any(x => secondRefsPage.Contains(x))); + } + [IntegrationTest] public async Task CanGetListOfReferencesInNamespaceWithRepositoryId() { @@ -84,6 +237,57 @@ public class ReferencesClientTests : IDisposable Assert.NotEmpty(list); } + [IntegrationTest] + public async Task ReturnsCorrectCountOfReferencesInNamespaceWithRepositoryIdWithStart() + { + var options = new ApiOptions + { + PageSize = 5, + PageCount = 1, + StartPage = 2 + }; + + var references = await _fixture.GetAllForSubNamespace(7528679, "heads", options); + + Assert.Equal(5, references.Count); + } + + [IntegrationTest] + public async Task ReturnsCorrectCountOfReferencesInNamespaceWithRepositoryIdWithoutStart() + { + var options = new ApiOptions + { + PageSize = 5, + PageCount = 1 + }; + + var references = await _fixture.GetAllForSubNamespace(7528679, "heads", options); + + Assert.Equal(5, references.Count); + } + + [IntegrationTest] + public async Task ReturnsDistinctReferencesInNamespaceWithRepositoryIdBasedOnStartPage() + { + var startOptions = new ApiOptions + { + PageSize = 5, + PageCount = 1 + }; + + var skipStartOptions = new ApiOptions + { + PageSize = 5, + PageCount = 1, + StartPage = 2 + }; + + var firstRefsPage = await _fixture.GetAllForSubNamespace(7528679, "heads", startOptions); + var secondRefsPage = await _fixture.GetAllForSubNamespace(7528679, "heads", skipStartOptions); + + Assert.False(firstRefsPage.Any(x => secondRefsPage.Contains(x))); + } + [IntegrationTest] public async Task CanGetErrorForInvalidNamespace() { diff --git a/Octokit.Tests/Clients/ReferencesClientTests.cs b/Octokit.Tests/Clients/ReferencesClientTests.cs index 99b8e14d..782004f6 100644 --- a/Octokit.Tests/Clients/ReferencesClientTests.cs +++ b/Octokit.Tests/Clients/ReferencesClientTests.cs @@ -69,8 +69,18 @@ namespace Octokit.Tests.Clients await Assert.ThrowsAsync(() => client.GetAll(null, "name")); await Assert.ThrowsAsync(() => client.GetAll("owner", null)); + await Assert.ThrowsAsync(() => client.GetAll(null, "name", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAll("owner", null, ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAll("owner", "name", null)); + + await Assert.ThrowsAsync(() => client.GetAll(1, null)); + + await Assert.ThrowsAsync(() => client.GetAll("", "name")); await Assert.ThrowsAsync(() => client.GetAll("owner", "")); + + await Assert.ThrowsAsync(() => client.GetAll("", "name", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAll("owner", "", ApiOptions.None)); } [Fact] @@ -81,7 +91,7 @@ namespace Octokit.Tests.Clients await client.GetAll("owner", "repo"); - connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/owner/repo/git/refs")); + connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/owner/repo/git/refs"), Args.ApiOptions); } [Fact] @@ -92,7 +102,7 @@ namespace Octokit.Tests.Clients await client.GetAll(1); - connection.Received().GetAll(Arg.Is(u => u.ToString() == "repositories/1/git/refs")); + connection.Received().GetAll(Arg.Is(u => u.ToString() == "repositories/1/git/refs"), Args.ApiOptions); } } @@ -107,13 +117,26 @@ namespace Octokit.Tests.Clients await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("owner", null, "heads")); await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("owner", "name", null)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace(null, "name", "heads", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("owner", null, "heads", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("owner", "name", null, ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("owner", "name", "heads", null)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace(1, null)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace(1, null, ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace(1, "subnamespace", null)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("", "name", "heads")); await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("owner", "", "heads")); await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("owner", "name", "")); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("", "name", "heads", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("owner", "", "heads", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace("owner", "name", "", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace(1, "")); + await Assert.ThrowsAsync(() => client.GetAllForSubNamespace(1, "", ApiOptions.None)); } [Fact] @@ -124,7 +147,7 @@ namespace Octokit.Tests.Clients await client.GetAllForSubNamespace("owner", "repo", "heads"); - connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/owner/repo/git/refs/heads")); + connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/owner/repo/git/refs/heads"), Args.ApiOptions); } [Fact] @@ -135,7 +158,7 @@ namespace Octokit.Tests.Clients await client.GetAllForSubNamespace(1, "heads"); - connection.Received().GetAll(Arg.Is(u => u.ToString() == "repositories/1/git/refs/heads")); + connection.Received().GetAll(Arg.Is(u => u.ToString() == "repositories/1/git/refs/heads"), Args.ApiOptions); } } diff --git a/Octokit/Clients/IReferencesClient.cs b/Octokit/Clients/IReferencesClient.cs index a8beee87..93497b19 100644 --- a/Octokit/Clients/IReferencesClient.cs +++ b/Octokit/Clients/IReferencesClient.cs @@ -48,9 +48,20 @@ namespace Octokit /// The owner of the repository /// The name of the repository /// - [ExcludeFromPaginationApiOptionsConventionTest("TODO: Implement pagination for this method")] Task> GetAll(string owner, string name); + /// + /// Gets all references for a given repository + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The owner of the repository + /// The name of the repository + /// Options for changing the API response + /// + Task> GetAll(string owner, string name, ApiOptions options); + /// /// Gets all references for a given repository /// @@ -59,9 +70,19 @@ namespace Octokit /// /// The Id of the repository /// - [ExcludeFromPaginationApiOptionsConventionTest("TODO: Implement pagination for this method")] Task> GetAll(long repositoryId); + /// + /// Gets all references for a given repository + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The Id of the repository + /// Options for changing the API response + /// + Task> GetAll(long repositoryId, ApiOptions options); + /// /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" /// @@ -72,9 +93,21 @@ namespace Octokit /// The name of the repository /// The sub-namespace to get references for /// - [ExcludeFromPaginationApiOptionsConventionTest("TODO: Implement pagination for this method")] Task> GetAllForSubNamespace(string owner, string name, string subNamespace); + /// + /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The owner of the repository + /// The name of the repository + /// The sub-namespace to get references for + /// Options for changing the API response + /// + Task> GetAllForSubNamespace(string owner, string name, string subNamespace, ApiOptions options); + /// /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" /// @@ -84,9 +117,20 @@ namespace Octokit /// The Id of the repository /// The sub-namespace to get references for /// - [ExcludeFromPaginationApiOptionsConventionTest("TODO: Implement pagination for this method")] Task> GetAllForSubNamespace(long repositoryId, string subNamespace); + /// + /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The Id of the repository + /// The sub-namespace to get references for + /// Options for changing the API response + /// + Task> GetAllForSubNamespace(long repositoryId, string subNamespace, ApiOptions options); + /// /// Creates a reference for a given repository /// diff --git a/Octokit/Clients/ReferencesClient.cs b/Octokit/Clients/ReferencesClient.cs index 5beec70e..b26df045 100644 --- a/Octokit/Clients/ReferencesClient.cs +++ b/Octokit/Clients/ReferencesClient.cs @@ -65,11 +65,27 @@ namespace Octokit /// The name of the repository /// public Task> GetAll(string owner, string name) + { + return GetAll(owner, name, ApiOptions.None); + } + + /// + /// Gets all references for a given repository + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The owner of the repository + /// The name of the repository + /// Options for changing the API response + /// + public Task> GetAll(string owner, string name, ApiOptions options) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); + Ensure.ArgumentNotNull(options, "options"); - return ApiConnection.GetAll(ApiUrls.Reference(owner, name)); + return ApiConnection.GetAll(ApiUrls.Reference(owner, name), options); } /// @@ -82,7 +98,23 @@ namespace Octokit /// public Task> GetAll(long repositoryId) { - return ApiConnection.GetAll(ApiUrls.Reference(repositoryId)); + return GetAll(repositoryId, ApiOptions.None); + } + + /// + /// Gets all references for a given repository + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The Id of the repository + /// Options for changing the API response + /// + public Task> GetAll(long repositoryId, ApiOptions options) + { + Ensure.ArgumentNotNull(options, "options"); + + return ApiConnection.GetAll(ApiUrls.Reference(repositoryId), options); } /// @@ -96,14 +128,31 @@ namespace Octokit /// The sub-namespace to get references for /// public Task> GetAllForSubNamespace(string owner, string name, string subNamespace) + { + return GetAllForSubNamespace(owner, name, subNamespace, ApiOptions.None); + } + + /// + /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The owner of the repository + /// The name of the repository + /// The sub-namespace to get references for + /// Options for changing the API response + /// + public Task> GetAllForSubNamespace(string owner, string name, string subNamespace, ApiOptions options) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(subNamespace, "subNamespace"); + Ensure.ArgumentNotNull(options, "options"); // TODO: Handle 404 when subNamespace cannot be found - return ApiConnection.GetAll(ApiUrls.Reference(owner, name, subNamespace)); + return ApiConnection.GetAll(ApiUrls.Reference(owner, name, subNamespace), options); } /// @@ -116,12 +165,28 @@ namespace Octokit /// The sub-namespace to get references for /// public Task> GetAllForSubNamespace(long repositoryId, string subNamespace) + { + return GetAllForSubNamespace(repositoryId, subNamespace, ApiOptions.None); + } + + /// + /// Gets references for a given repository by sub-namespace, i.e. "tags" or "heads" + /// + /// + /// http://developer.github.com/v3/git/refs/#get-all-references + /// + /// The Id of the repository + /// The sub-namespace to get references for + /// Options for changing the API response + /// + public Task> GetAllForSubNamespace(long repositoryId, string subNamespace, ApiOptions options) { Ensure.ArgumentNotNullOrEmptyString(subNamespace, "subNamespace"); + Ensure.ArgumentNotNull(options, "options"); // TODO: Handle 404 when subNamespace cannot be found - return ApiConnection.GetAll(ApiUrls.Reference(repositoryId, subNamespace)); + return ApiConnection.GetAll(ApiUrls.Reference(repositoryId, subNamespace), options); } ///