From 3d97346672872570113ad163edc4bad6491208d0 Mon Sep 17 00:00:00 2001 From: Alexander Efremov Date: Sat, 18 Jun 2016 05:02:28 +0700 Subject: [PATCH] Add repositoryId overloads to methods on I(Observable)RepositoryDeployKeysClient (#1351) --- .../IObservableRepositoryDeployKeysClient.cs | 60 ++++++- .../ObservableRepositoryDeployKeysClient.cs | 85 ++++++++- .../RepositoryDeployKeysClientTests.cs | 113 ++++++++++++ .../RepositoryDeployKeysClientTests.cs | 117 ++++++++++--- ...servableRepositoryDeployKeysClientTests.cs | 164 +++++++++++++++--- .../Clients/IRepositoryDeployKeysClient.cs | 54 +++++- Octokit/Clients/RepositoryDeployKeysClient.cs | 79 ++++++++- 7 files changed, 608 insertions(+), 64 deletions(-) diff --git a/Octokit.Reactive/Clients/IObservableRepositoryDeployKeysClient.cs b/Octokit.Reactive/Clients/IObservableRepositoryDeployKeysClient.cs index 56b0b51b..6ecf4db2 100644 --- a/Octokit.Reactive/Clients/IObservableRepositoryDeployKeysClient.cs +++ b/Octokit.Reactive/Clients/IObservableRepositoryDeployKeysClient.cs @@ -4,6 +4,12 @@ using System.Reactive; namespace Octokit.Reactive { + /// + /// A client for GitHub's Repository Deploy Keys API. + /// + /// + /// See the Deploy Keys API documentation for more information. + /// public interface IObservableRepositoryDeployKeysClient { /// @@ -18,6 +24,17 @@ namespace Octokit.Reactive [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")] IObservable Get(string owner, string name, int number); + /// + /// Get a single deploy key by number for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The id of the deploy key. + [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")] + IObservable Get(int repositoryId, int number); + /// /// Get all deploy keys for a repository. /// @@ -28,6 +45,15 @@ namespace Octokit.Reactive /// The name of the repository. IObservable GetAll(string owner, string name); + /// + /// Get all deploy keys for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + IObservable GetAll(int repositoryId); + /// /// Get all deploy keys for a repository. /// @@ -39,6 +65,16 @@ namespace Octokit.Reactive /// Options for changing the API response IObservable GetAll(string owner, string name, ApiOptions options); + /// + /// Get all deploy keys for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// Options for changing the API response + IObservable GetAll(int repositoryId, ApiOptions options); + /// /// Creates a new deploy key for a repository. /// @@ -48,9 +84,18 @@ namespace Octokit.Reactive /// The owner of the repository. /// The name of the repository. /// The deploy key to create for the repository. - /// IObservable Create(string owner, string name, NewDeployKey newDeployKey); + /// + /// Creates a new deploy key for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The deploy key to create for the repository. + IObservable Create(int repositoryId, NewDeployKey newDeployKey); + /// /// Deletes a deploy key from a repository. /// @@ -60,7 +105,16 @@ namespace Octokit.Reactive /// The owner of the repository. /// The name of the repository. /// The id of the deploy key to delete. - /// IObservable Delete(string owner, string name, int number); + + /// + /// Deletes a deploy key from a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The id of the deploy key to delete. + IObservable Delete(int repositoryId, int number); } -} +} \ No newline at end of file diff --git a/Octokit.Reactive/Clients/ObservableRepositoryDeployKeysClient.cs b/Octokit.Reactive/Clients/ObservableRepositoryDeployKeysClient.cs index 182460b1..c8a2f180 100644 --- a/Octokit.Reactive/Clients/ObservableRepositoryDeployKeysClient.cs +++ b/Octokit.Reactive/Clients/ObservableRepositoryDeployKeysClient.cs @@ -5,6 +5,12 @@ using Octokit.Reactive.Internal; namespace Octokit.Reactive { + /// + /// A client for GitHub's Repository Deploy Keys API. + /// + /// + /// See the Deploy Keys API documentation for more information. + /// public class ObservableRepositoryDeployKeysClient : IObservableRepositoryDeployKeysClient { readonly IRepositoryDeployKeysClient _client; @@ -35,6 +41,19 @@ namespace Octokit.Reactive return _client.Get(owner, name, number).ToObservable(); } + /// + /// Get a single deploy key by number for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The id of the deploy key. + public IObservable Get(int repositoryId, int number) + { + return _client.Get(repositoryId, number).ToObservable(); + } + /// /// Get all deploy keys for a repository. /// @@ -51,6 +70,18 @@ namespace Octokit.Reactive return GetAll(owner, name, ApiOptions.None); } + /// + /// Get all deploy keys for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + public IObservable GetAll(int repositoryId) + { + return GetAll(repositoryId, ApiOptions.None); + } + /// /// Get all deploy keys for a repository. /// @@ -69,6 +100,21 @@ namespace Octokit.Reactive return _connection.GetAndFlattenAllPages(ApiUrls.RepositoryDeployKeys(owner, name), options); } + /// + /// Get all deploy keys for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// Options for changing the API response + public IObservable GetAll(int repositoryId, ApiOptions options) + { + Ensure.ArgumentNotNull(options, "options"); + + return _connection.GetAndFlattenAllPages(ApiUrls.RepositoryDeployKeys(repositoryId), options); + } + /// /// Creates a new deploy key for a repository. /// @@ -78,7 +124,6 @@ namespace Octokit.Reactive /// The owner of the repository. /// The name of the repository. /// The deploy key to create for the repository. - /// public IObservable Create(string owner, string name, NewDeployKey newDeployKey) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); @@ -95,6 +140,28 @@ namespace Octokit.Reactive return _client.Create(owner, name, newDeployKey).ToObservable(); } + /// + /// Creates a new deploy key for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The deploy key to create for the repository. + public IObservable Create(int repositoryId, NewDeployKey newDeployKey) + { + Ensure.ArgumentNotNull(newDeployKey, "newDeployKey"); + + + if (string.IsNullOrWhiteSpace(newDeployKey.Title)) + throw new ArgumentException("The new deploy key's title must not be null."); + + if (string.IsNullOrWhiteSpace(newDeployKey.Key)) + throw new ArgumentException("The new deploy key's key must not be null."); + + return _client.Create(repositoryId, newDeployKey).ToObservable(); + } + /// /// Deletes a deploy key from a repository. /// @@ -104,7 +171,6 @@ namespace Octokit.Reactive /// The owner of the repository. /// The name of the repository. /// The id of the deploy key to delete. - /// public IObservable Delete(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); @@ -112,5 +178,18 @@ namespace Octokit.Reactive return _client.Delete(owner, name, number).ToObservable(); } + + /// + /// Deletes a deploy key from a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The id of the deploy key to delete. + public IObservable Delete(int repositoryId, int number) + { + return _client.Delete(repositoryId, number).ToObservable(); + } } -} +} \ No newline at end of file diff --git a/Octokit.Tests.Integration/Clients/RepositoryDeployKeysClientTests.cs b/Octokit.Tests.Integration/Clients/RepositoryDeployKeysClientTests.cs index 6e10606f..b9e29ae4 100644 --- a/Octokit.Tests.Integration/Clients/RepositoryDeployKeysClientTests.cs +++ b/Octokit.Tests.Integration/Clients/RepositoryDeployKeysClientTests.cs @@ -37,6 +37,21 @@ public class RepositoryDeployKeysClientTests : IDisposable Assert.Equal(_keyTitle, deployKeyResult.Title); } + [IntegrationTest(Skip = "see https://github.com/octokit/octokit.net/issues/533 for investigating this failing test")] + public async Task CanCreateADeployKeyWithRepositoryId() + { + var deployKey = new NewDeployKey + { + Key = _key, + Title = _keyTitle + }; + + var deployKeyResult = await _fixture.Create(_context.Repository.Id, deployKey); + Assert.NotNull(deployKeyResult); + Assert.Equal(_key, deployKeyResult.Key); + Assert.Equal(_keyTitle, deployKeyResult.Title); + } + [IntegrationTest(Skip = "See https://github.com/octokit/octokit.net/issues/1003 for investigating this failing test")] public async Task CanRetrieveAllDeployKeys() { @@ -57,6 +72,26 @@ public class RepositoryDeployKeysClientTests : IDisposable Assert.Equal(_keyTitle, deployKeys[0].Title); } + [IntegrationTest(Skip = "See https://github.com/octokit/octokit.net/issues/1003 for investigating this failing test")] + public async Task CanRetrieveAllDeployKeysWithRepositoryId() + { + var deployKeys = await _fixture.GetAll(_context.RepositoryOwner, _context.RepositoryName); + Assert.Equal(0, deployKeys.Count); + + var deployKey = new NewDeployKey + { + Key = _key, + Title = _keyTitle + }; + + await _fixture.Create(_context.Repository.Id, deployKey); + + deployKeys = await _fixture.GetAll(_context.Repository.Id); + Assert.Equal(1, deployKeys.Count); + Assert.Equal(_key, deployKeys[0].Key); + Assert.Equal(_keyTitle, deployKeys[0].Title); + } + [IntegrationTest(Skip = "See https://github.com/octokit/octokit.net/issues/1003 for investigating this failing test")] public async Task ReturnsCorrectCountOfDeployKeysWithoutStart() { @@ -166,6 +201,46 @@ public class RepositoryDeployKeysClientTests : IDisposable Assert.NotEqual(firstPage[0].Id, secondPage[0].Id); } + [IntegrationTest(Skip = "See https://github.com/octokit/octokit.net/issues/1003 for investigating this failing test")] + public async Task ReturnsDistinctResultsBasedOnStartPageWithRepositoryId() + { + var list = new List(); + var deployKeysCount = 5; + for (int i = 0; i < deployKeysCount; i++) + { + var item = new NewDeployKey + { + Key = "ssh-rsa A" + i, // here we should genereate ssh-key some how + Title = "KeyTitle" + i + }; + list.Add(item); + } + + foreach (var key in list) + { + await _fixture.Create(_context.Repository.Id, key); + } + + var startOptions = new ApiOptions + { + PageSize = 2, + PageCount = 1 + }; + + var firstPage = await _fixture.GetAll(_context.Repository.Id, startOptions); + + var skipStartOptions = new ApiOptions + { + PageSize = 2, + PageCount = 1, + StartPage = 2 + }; + + var secondPage = await _fixture.GetAll(_context.Repository.Id, skipStartOptions); + + Assert.NotEqual(firstPage[0].Id, secondPage[0].Id); + } + [IntegrationTest(Skip = "see https://github.com/octokit/octokit.net/issues/533 for the resolution to this failing test")] public async Task CanRetrieveADeployKey() { @@ -183,6 +258,23 @@ public class RepositoryDeployKeysClientTests : IDisposable Assert.Equal(_keyTitle, deployKey.Title); } + [IntegrationTest(Skip = "see https://github.com/octokit/octokit.net/issues/533 for the resolution to this failing test")] + public async Task CanRetrieveADeployKeyWithRepositoryId() + { + var newDeployKey = new NewDeployKey + { + Key = _key, + Title = _keyTitle + }; + var deployKeyResult = await _fixture.Create(_context.Repository.Id, newDeployKey); + + var deployKey = await _fixture.Get(_context.Repository.Id, deployKeyResult.Id); + Assert.NotNull(deployKey); + Assert.Equal(deployKeyResult.Id, deployKey.Id); + Assert.Equal(_key, deployKey.Key); + Assert.Equal(_keyTitle, deployKey.Title); + } + [IntegrationTest(Skip = "see https://github.com/octokit/octokit.net/issues/533 for the resolution to this failing test")] public async Task CanRemoveADeployKey() { @@ -204,6 +296,27 @@ public class RepositoryDeployKeysClientTests : IDisposable Assert.Equal(0, deployKeys.Count); } + [IntegrationTest(Skip = "see https://github.com/octokit/octokit.net/issues/533 for the resolution to this failing test")] + public async Task CanRemoveADeployKeyWithRepositoryId() + { + var newDeployKey = new NewDeployKey + { + Key = _key, + Title = _keyTitle + }; + + await _fixture.Create(_context.Repository.Id, newDeployKey); + + var deployKeys = await _fixture.GetAll(_context.Repository.Id); + Assert.Equal(1, deployKeys.Count); + Assert.Equal(_key, deployKeys[0].Key); + Assert.Equal(_keyTitle, deployKeys[0].Title); + + await _fixture.Delete(_context.Repository.Id, deployKeys[0].Id); + deployKeys = await _fixture.GetAll(_context.Repository.Id); + Assert.Equal(0, deployKeys.Count); + } + public void Dispose() { _context.Dispose(); diff --git a/Octokit.Tests/Clients/RepositoryDeployKeysClientTests.cs b/Octokit.Tests/Clients/RepositoryDeployKeysClientTests.cs index 59c28f36..accce4c7 100644 --- a/Octokit.Tests/Clients/RepositoryDeployKeysClientTests.cs +++ b/Octokit.Tests/Clients/RepositoryDeployKeysClientTests.cs @@ -23,24 +23,36 @@ namespace Octokit.Tests.Clients public class TheGetMethod { [Fact] - public void GetsADeployKey() + public async Task RequestsCorrectUrl() { var apiConnection = Substitute.For(); var deployKeysClient = new RepositoryDeployKeysClient(apiConnection); - deployKeysClient.Get("user", "repo", 42); + await deployKeysClient.Get("user", "repo", 42); apiConnection.Received().Get(Arg.Is(u => u.ToString() == "repos/user/repo/keys/42")); } + [Fact] + public async Task RequestsCorrectUrlWithRepositoryId() + { + var apiConnection = Substitute.For(); + var deployKeysClient = new RepositoryDeployKeysClient(apiConnection); + + await deployKeysClient.Get(1, 42); + + apiConnection.Received().Get(Arg.Is(u => u.ToString() == "repositories/1/keys/42")); + } + [Fact] public async Task EnsureNonNullArguments() { var deployKeysClient = new RepositoryDeployKeysClient(Substitute.For()); await Assert.ThrowsAsync(() => deployKeysClient.Get(null, "repo", 1)); - await Assert.ThrowsAsync(() => deployKeysClient.Get("", "repo", 1)); await Assert.ThrowsAsync(() => deployKeysClient.Get("user", null, 1)); + + await Assert.ThrowsAsync(() => deployKeysClient.Get("", "repo", 1)); await Assert.ThrowsAsync(() => deployKeysClient.Get("user", "", 1)); } } @@ -48,18 +60,29 @@ namespace Octokit.Tests.Clients public class TheGetAllMethod { [Fact] - public void GetsAListOfDeployKeys() + public async Task RequestsCorrectUrl() { var apiConnection = Substitute.For(); var deployKeysClient = new RepositoryDeployKeysClient(apiConnection); - deployKeysClient.GetAll("user", "repo"); + await deployKeysClient.GetAll("user", "repo"); apiConnection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/user/repo/keys"), Args.ApiOptions); } [Fact] - public void GetsAListOfDeployKeysWithApiOptions() + public async Task RequestsCorrectUrlWithRepositoryId() + { + var apiConnection = Substitute.For(); + var deployKeysClient = new RepositoryDeployKeysClient(apiConnection); + + await deployKeysClient.GetAll(1); + + apiConnection.Received().GetAll(Arg.Is(u => u.ToString() == "repositories/1/keys"), Args.ApiOptions); + } + + [Fact] + public async Task RequestsCorrectUrlWithApiOptions() { var connection = Substitute.For(); var client = new RepositoryDeployKeysClient(connection); @@ -71,49 +94,81 @@ namespace Octokit.Tests.Clients StartPage = 1 }; - client.GetAll("user", "repo", options); + await client.GetAll("user", "repo", options); connection.Received(1) .GetAll(Arg.Is(u => u.ToString() == "repos/user/repo/keys"), options); } + [Fact] + public async Task RequestsCorrectUrlWithRepositoryIdWithApiOptions() + { + var connection = Substitute.For(); + var client = new RepositoryDeployKeysClient(connection); + + var options = new ApiOptions + { + PageCount = 1, + PageSize = 1, + StartPage = 1 + }; + + await client.GetAll(1, options); + + connection.Received(1) + .GetAll(Arg.Is(u => u.ToString() == "repositories/1/keys"), + options); + } + [Fact] public async Task EnsuresNonNullArguments() { var deployKeysClient = new RepositoryDeployKeysClient(Substitute.For()); - await Assert.ThrowsAsync(() => deployKeysClient.GetAll(null, null)); await Assert.ThrowsAsync(() => deployKeysClient.GetAll(null, "repo")); await Assert.ThrowsAsync(() => deployKeysClient.GetAll("user", null)); - - await Assert.ThrowsAsync(() => deployKeysClient.GetAll(null, null, null)); - - await Assert.ThrowsAsync(() => deployKeysClient.GetAll(null, null, ApiOptions.None)); - await Assert.ThrowsAsync(() => deployKeysClient.GetAll(null, "repo", null)); - await Assert.ThrowsAsync(() => deployKeysClient.GetAll("user", null, null)); - await Assert.ThrowsAsync(() => deployKeysClient.GetAll(null, "repo", ApiOptions.None)); await Assert.ThrowsAsync(() => deployKeysClient.GetAll("user", null, ApiOptions.None)); await Assert.ThrowsAsync(() => deployKeysClient.GetAll("user", "repo", null)); + await Assert.ThrowsAsync(() => deployKeysClient.GetAll(1, null)); + await Assert.ThrowsAsync(() => deployKeysClient.GetAll("user", "")); await Assert.ThrowsAsync(() => deployKeysClient.GetAll("", "repo")); + await Assert.ThrowsAsync(() => deployKeysClient.GetAll("", "repo", ApiOptions.None)); + await Assert.ThrowsAsync(() => deployKeysClient.GetAll("user", "", ApiOptions.None)); } } public class TheCreateMethod { [Fact] - public void SendsCreateToCorrectUrl() + public void CreatesCorrectUrl() { var apiConnection = Substitute.For(); var deployKeysClient = new RepositoryDeployKeysClient(apiConnection); - deployKeysClient.Create("user", "repo", new NewDeployKey { Key = "ABC123", Title = "user@repo" }); + var newDeployKey = new NewDeployKey { Key = "ABC123", Title = "user@repo" }; + + deployKeysClient.Create("user", "repo", newDeployKey); apiConnection.Received().Post(Arg.Is(u => u.ToString() == "repos/user/repo/keys"), - Args.NewDeployKey); + newDeployKey); + } + + [Fact] + public void CreatesCorrectUrlWithRepositoryId() + { + var apiConnection = Substitute.For(); + var deployKeysClient = new RepositoryDeployKeysClient(apiConnection); + + var newDeployKey = new NewDeployKey { Key = "ABC123", Title = "user@repo" }; + + deployKeysClient.Create(1, newDeployKey); + + apiConnection.Received().Post(Arg.Is(u => u.ToString() == "repositories/1/keys"), + newDeployKey); } [Fact] @@ -122,10 +177,14 @@ namespace Octokit.Tests.Clients var deployKeysClient = new RepositoryDeployKeysClient(Substitute.For()); await Assert.ThrowsAsync(() => deployKeysClient.Create(null, "repo", new NewDeployKey())); - await Assert.ThrowsAsync(() => deployKeysClient.Create("", "repo", new NewDeployKey())); await Assert.ThrowsAsync(() => deployKeysClient.Create("user", null, new NewDeployKey())); - await Assert.ThrowsAsync(() => deployKeysClient.Create("user", "", new NewDeployKey())); await Assert.ThrowsAsync(() => deployKeysClient.Create("user", "repo", null)); + + await Assert.ThrowsAsync(() => deployKeysClient.Create(1, null)); + + await Assert.ThrowsAsync(() => deployKeysClient.Create("", "repo", new NewDeployKey())); + await Assert.ThrowsAsync(() => deployKeysClient.Create("user", "", new NewDeployKey())); + await Assert.ThrowsAsync(() => deployKeysClient.Create("user", "repo", new NewDeployKey())); await Assert.ThrowsAsync(() => deployKeysClient.Create("user", "repo", new NewDeployKey { Key = "ABC123" })); await Assert.ThrowsAsync(() => deployKeysClient.Create("user", "repo", new NewDeployKey { Title = "user@repo" })); @@ -135,24 +194,36 @@ namespace Octokit.Tests.Clients public class TheDeleteMethod { [Fact] - public void DeletesCorrectUrl() + public async Task DeletesCorrectUrl() { var apiConnection = Substitute.For(); var deployKeysClient = new RepositoryDeployKeysClient(apiConnection); - deployKeysClient.Delete("user", "repo", 42); + await deployKeysClient.Delete("user", "repo", 42); apiConnection.Received().Delete(Arg.Is(u => u.ToString() == "repos/user/repo/keys/42")); } + [Fact] + public async Task DeletesCorrectUrlWithRepositoryId() + { + var apiConnection = Substitute.For(); + var deployKeysClient = new RepositoryDeployKeysClient(apiConnection); + + await deployKeysClient.Delete(1, 42); + + apiConnection.Received().Delete(Arg.Is(u => u.ToString() == "repositories/1/keys/42")); + } + [Fact] public async Task EnsuresNonNullArguments() { var deployKeysClient = new RepositoryDeployKeysClient(Substitute.For()); await Assert.ThrowsAsync(() => deployKeysClient.Delete(null, "repo", 1)); - await Assert.ThrowsAsync(() => deployKeysClient.Delete("", "repo", 1)); await Assert.ThrowsAsync(() => deployKeysClient.Delete("user", null, 1)); + + await Assert.ThrowsAsync(() => deployKeysClient.Delete("", "repo", 1)); await Assert.ThrowsAsync(() => deployKeysClient.Delete("user", "", 1)); } } diff --git a/Octokit.Tests/Reactive/ObservableRepositoryDeployKeysClientTests.cs b/Octokit.Tests/Reactive/ObservableRepositoryDeployKeysClientTests.cs index 08cb24a1..f0d553fe 100644 --- a/Octokit.Tests/Reactive/ObservableRepositoryDeployKeysClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableRepositoryDeployKeysClientTests.cs @@ -20,14 +20,25 @@ namespace Octokit.Tests.Reactive public class TheGetMethod { [Fact] - public void CallsIntoClient() + public void RequestsCorrectUrl() { - var githubClient = Substitute.For(); - var deployKeysClient = new ObservableRepositoryDeployKeysClient(githubClient); + var gitHubClient = Substitute.For(); + var deployKeysClient = new ObservableRepositoryDeployKeysClient(gitHubClient); deployKeysClient.Get("user", "repo", 42); - githubClient.Repository.DeployKeys.Received(1).Get("user", "repo", 42); + gitHubClient.Repository.DeployKeys.Received(1).Get("user", "repo", 42); + } + + [Fact] + public void RequestsCorrectUrlWithRepositoryId() + { + var gitHubClient = Substitute.For(); + var deployKeysClient = new ObservableRepositoryDeployKeysClient(gitHubClient); + + deployKeysClient.Get(1, 42); + + gitHubClient.Repository.DeployKeys.Received(1).Get(1, 42); } [Fact] @@ -35,29 +46,30 @@ namespace Octokit.Tests.Reactive { var deployKeysClient = new ObservableRepositoryDeployKeysClient(Substitute.For()); - Assert.Throws(() => deployKeysClient.Get(null, "repo", 42)); - Assert.Throws(() => deployKeysClient.Get("", "repo", 42)); - Assert.Throws(() => deployKeysClient.Get("user", null, 42)); - Assert.Throws(() => deployKeysClient.Get("user", "", 42)); + Assert.Throws(() => deployKeysClient.Get(null, "repo", 1)); + Assert.Throws(() => deployKeysClient.Get("user", null, 1)); + + Assert.Throws(() => deployKeysClient.Get("", "repo", 1)); + Assert.Throws(() => deployKeysClient.Get("user", "", 1)); } } public class TheGetAllMethod { [Fact] - public void CallsIntoClient() + public void RequestsCorrectUrl() { - var githubClient = Substitute.For(); - var deployKeysClient = new ObservableRepositoryDeployKeysClient(githubClient); + var gitHubClient = Substitute.For(); + var deployKeysClient = new ObservableRepositoryDeployKeysClient(gitHubClient); deployKeysClient.GetAll("user", "repo"); - githubClient.Connection.Received(1).Get>( + gitHubClient.Connection.Received(1).Get>( new Uri("repos/user/repo/keys", UriKind.Relative), Arg.Is>(dictionary => dictionary.Count == 0), null); } [Fact] - public void GetsCorrectUrlWithApiOptions() + public void RequestsCorrectUrlWithApiOptions() { var gitHubClient = Substitute.For(); var deployKeysClient = new ObservableRepositoryDeployKeysClient(gitHubClient); @@ -102,42 +114,96 @@ namespace Octokit.Tests.Reactive null); } + [Fact] + public void RequestsCorrectUrlWithRepositoryIdWithApiOptions() + { + var gitHubClient = Substitute.For(); + var deployKeysClient = new ObservableRepositoryDeployKeysClient(gitHubClient); + var expectedUrl = "repositories/1/keys"; + + // all properties are setted => only 2 options (StartPage, PageSize) in dictionary + var options = new ApiOptions + { + StartPage = 1, + PageCount = 1, + PageSize = 1 + }; + + deployKeysClient.GetAll(1, options); + gitHubClient.Connection.Received(1) + .Get>(Arg.Is(u => u.ToString() == expectedUrl), + Arg.Is>(dictionary => dictionary.Count == 2), + null); + + // StartPage is setted => only 1 option (StartPage) in dictionary + options = new ApiOptions + { + StartPage = 1 + }; + + deployKeysClient.GetAll(1, options); + gitHubClient.Connection.Received(1) + .Get>(Arg.Is(u => u.ToString() == expectedUrl), + Arg.Is>(dictionary => dictionary.Count == 1), + null); + + // PageCount is setted => none of options in dictionary + options = new ApiOptions + { + PageCount = 1 + }; + + deployKeysClient.GetAll(1, options); + gitHubClient.Connection.Received(1) + .Get>(Arg.Is(u => u.ToString() == expectedUrl), + Arg.Is>(dictionary => dictionary.Count == 0), + null); + } + [Fact] public void EnsuresNonNullArguments() { var deployKeysClient = new ObservableRepositoryDeployKeysClient(Substitute.For()); - Assert.Throws(() => deployKeysClient.GetAll(null, null)); Assert.Throws(() => deployKeysClient.GetAll(null, "repo")); Assert.Throws(() => deployKeysClient.GetAll("user", null)); - - Assert.Throws(() => deployKeysClient.GetAll(null, null, null)); - - Assert.Throws(() => deployKeysClient.GetAll(null, null, ApiOptions.None)); - Assert.Throws(() => deployKeysClient.GetAll(null, "repo", null)); - Assert.Throws(() => deployKeysClient.GetAll("user", null, null)); - Assert.Throws(() => deployKeysClient.GetAll(null, "repo", ApiOptions.None)); Assert.Throws(() => deployKeysClient.GetAll("user", null, ApiOptions.None)); Assert.Throws(() => deployKeysClient.GetAll("user", "repo", null)); + Assert.Throws(() => deployKeysClient.GetAll(1, null)); + Assert.Throws(() => deployKeysClient.GetAll("user", "")); Assert.Throws(() => deployKeysClient.GetAll("", "repo")); + Assert.Throws(() => deployKeysClient.GetAll("", "repo", ApiOptions.None)); + Assert.Throws(() => deployKeysClient.GetAll("user", "", ApiOptions.None)); } } public class TheCreateMethod { [Fact] - public void CallsIntoClient() + public void CreatesCorrectUrl() { - var githubClient = Substitute.For(); - var deployKeysClient = new ObservableRepositoryDeployKeysClient(githubClient); + var gitHubClient = Substitute.For(); + var deployKeysClient = new ObservableRepositoryDeployKeysClient(gitHubClient); var data = new NewDeployKey { Key = "ABC123", Title = "user@repo" }; deployKeysClient.Create("user", "repo", data); - githubClient.Repository.DeployKeys.Received(1).Create("user", "repo", data); + gitHubClient.Repository.DeployKeys.Received(1).Create("user", "repo", data); + } + + [Fact] + public void CreatesCorrectUrlWithRepositoryId() + { + var gitHubClient = Substitute.For(); + var deployKeysClient = new ObservableRepositoryDeployKeysClient(gitHubClient); + var data = new NewDeployKey { Key = "ABC123", Title = "user@repo" }; + + deployKeysClient.Create(1, data); + + gitHubClient.Repository.DeployKeys.Received(1).Create(1, data); } [Fact] @@ -146,12 +212,54 @@ namespace Octokit.Tests.Reactive var deployKeysClient = new ObservableRepositoryDeployKeysClient(Substitute.For()); Assert.Throws(() => deployKeysClient.Create(null, "repo", new NewDeployKey())); - Assert.Throws(() => deployKeysClient.Create("", "repo", new NewDeployKey())); Assert.Throws(() => deployKeysClient.Create("user", null, new NewDeployKey())); - Assert.Throws(() => deployKeysClient.Create("user", "", new NewDeployKey())); Assert.Throws(() => deployKeysClient.Create("user", "repo", null)); - Assert.Throws(() => deployKeysClient.Create("user", "repo", new NewDeployKey { Title = "user@repo" })); + + Assert.Throws(() => deployKeysClient.Create(1, null)); + + Assert.Throws(() => deployKeysClient.Create("", "repo", new NewDeployKey())); + Assert.Throws(() => deployKeysClient.Create("user", "", new NewDeployKey())); + + Assert.Throws(() => deployKeysClient.Create("user", "repo", new NewDeployKey())); Assert.Throws(() => deployKeysClient.Create("user", "repo", new NewDeployKey { Key = "ABC123" })); + Assert.Throws(() => deployKeysClient.Create("user", "repo", new NewDeployKey { Title = "user@repo" })); + } + } + + public class TheDeleteMethod + { + [Fact] + public void CreatesCorrectUrl() + { + var gitHubClient = Substitute.For(); + var deployKeysClient = new ObservableRepositoryDeployKeysClient(gitHubClient); + + deployKeysClient.Delete("user", "repo", 42); + + gitHubClient.Repository.DeployKeys.Received(1).Delete("user", "repo", 42); + } + + [Fact] + public void CreatesCorrectUrlWithRepositoryId() + { + var gitHubClient = Substitute.For(); + var deployKeysClient = new ObservableRepositoryDeployKeysClient(gitHubClient); + + deployKeysClient.Delete(1, 42); + + gitHubClient.Repository.DeployKeys.Received(1).Delete(1, 42); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var deployKeysClient = new ObservableRepositoryDeployKeysClient(Substitute.For()); + + Assert.Throws(() => deployKeysClient.Delete(null, "repo", 1)); + Assert.Throws(() => deployKeysClient.Delete("user", null, 1)); + + Assert.Throws(() => deployKeysClient.Delete("", "repo", 1)); + Assert.Throws(() => deployKeysClient.Delete("user", "", 1)); } } } diff --git a/Octokit/Clients/IRepositoryDeployKeysClient.cs b/Octokit/Clients/IRepositoryDeployKeysClient.cs index 9eb2a0e4..0bf8f283 100644 --- a/Octokit/Clients/IRepositoryDeployKeysClient.cs +++ b/Octokit/Clients/IRepositoryDeployKeysClient.cs @@ -24,6 +24,17 @@ namespace Octokit [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")] Task Get(string owner, string name, int number); + /// + /// Get a single deploy key by number for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The id of the deploy key. + [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")] + Task Get(int repositoryId, int number); + /// /// Get all deploy keys for a repository. /// @@ -34,6 +45,15 @@ namespace Octokit /// The name of the repository. Task> GetAll(string owner, string name); + /// + /// Get all deploy keys for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + Task> GetAll(int repositoryId); + /// /// Get all deploy keys for a repository. /// @@ -45,6 +65,16 @@ namespace Octokit /// Options for changing the API response Task> GetAll(string owner, string name, ApiOptions options); + /// + /// Get all deploy keys for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// Options for changing the API response + Task> GetAll(int repositoryId, ApiOptions options); + /// /// Creates a new deploy key for a repository. /// @@ -54,9 +84,18 @@ namespace Octokit /// The owner of the repository. /// The name of the repository. /// The deploy key to create for the repository. - /// Task Create(string owner, string name, NewDeployKey newDeployKey); + /// + /// Creates a new deploy key for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The deploy key to create for the repository. + Task Create(int repositoryId, NewDeployKey newDeployKey); + /// /// Deletes a deploy key from a repository. /// @@ -66,7 +105,16 @@ namespace Octokit /// The owner of the repository. /// The name of the repository. /// The id of the deploy key to delete. - /// Task Delete(string owner, string name, int number); + + /// + /// Deletes a deploy key from a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The id of the deploy key to delete. + Task Delete(int repositoryId, int number); } -} +} \ No newline at end of file diff --git a/Octokit/Clients/RepositoryDeployKeysClient.cs b/Octokit/Clients/RepositoryDeployKeysClient.cs index 78f1ddd8..9dd14917 100644 --- a/Octokit/Clients/RepositoryDeployKeysClient.cs +++ b/Octokit/Clients/RepositoryDeployKeysClient.cs @@ -40,6 +40,19 @@ namespace Octokit return ApiConnection.Get(ApiUrls.RepositoryDeployKey(owner, name, number)); } + /// + /// Get a single deploy key by number for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The id of the deploy key. + public Task Get(int repositoryId, int number) + { + return ApiConnection.Get(ApiUrls.RepositoryDeployKey(repositoryId, number)); + } + /// /// Get all deploy keys for a repository. /// @@ -56,6 +69,18 @@ namespace Octokit return GetAll(owner, name, ApiOptions.None); } + /// + /// Get all deploy keys for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + public Task> GetAll(int repositoryId) + { + return GetAll(repositoryId, ApiOptions.None); + } + /// /// Get all deploy keys for a repository. /// @@ -74,6 +99,21 @@ namespace Octokit return ApiConnection.GetAll(ApiUrls.RepositoryDeployKeys(owner, name), options); } + /// + /// Get all deploy keys for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// Options for changing the API response + public Task> GetAll(int repositoryId, ApiOptions options) + { + Ensure.ArgumentNotNull(options, "options"); + + return ApiConnection.GetAll(ApiUrls.RepositoryDeployKeys(repositoryId), options); + } + /// /// Creates a new deploy key for a repository. /// @@ -83,7 +123,6 @@ namespace Octokit /// The owner of the repository. /// The name of the repository. /// The deploy key to create for the repository. - /// public Task Create(string owner, string name, NewDeployKey newDeployKey) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); @@ -99,6 +138,27 @@ namespace Octokit return ApiConnection.Post(ApiUrls.RepositoryDeployKeys(owner, name), newDeployKey); } + /// + /// Creates a new deploy key for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The deploy key to create for the repository. + public Task Create(int repositoryId, NewDeployKey newDeployKey) + { + Ensure.ArgumentNotNull(newDeployKey, "newDeployKey"); + + if (string.IsNullOrWhiteSpace(newDeployKey.Title)) + throw new ArgumentException("The new deploy key's title must not be null."); + + if (string.IsNullOrWhiteSpace(newDeployKey.Key)) + throw new ArgumentException("The new deploy key's key must not be null."); + + return ApiConnection.Post(ApiUrls.RepositoryDeployKeys(repositoryId), newDeployKey); + } + /// /// Deletes a deploy key from a repository. /// @@ -108,14 +168,25 @@ namespace Octokit /// The owner of the repository. /// The name of the repository. /// The id of the deploy key to delete. - /// public Task Delete(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); - Ensure.ArgumentNotNull(number, "number"); return ApiConnection.Delete(ApiUrls.RepositoryDeployKey(owner, name, number)); } + + /// + /// Deletes a deploy key from a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The ID of the repository. + /// The id of the deploy key to delete. + public Task Delete(int repositoryId, int number) + { + return ApiConnection.Delete(ApiUrls.RepositoryDeployKey(repositoryId, number)); + } } -} +} \ No newline at end of file