From 896814a4276302c5ed7cd43daf7faf24e64d435d Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Sun, 5 Jun 2016 08:21:14 +1000 Subject: [PATCH 01/11] Add GPG Keys API preview header --- Octokit/Helpers/AcceptHeaders.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Octokit/Helpers/AcceptHeaders.cs b/Octokit/Helpers/AcceptHeaders.cs index 7e158e8285..c488404972 100644 --- a/Octokit/Helpers/AcceptHeaders.cs +++ b/Octokit/Helpers/AcceptHeaders.cs @@ -1,4 +1,6 @@ -namespace Octokit +using System.Diagnostics.CodeAnalysis; + +namespace Octokit { public static class AcceptHeaders { @@ -23,5 +25,8 @@ public static class AcceptHeaders public const string MigrationsApiPreview = " application/vnd.github.wyandotte-preview+json"; public const string OrganizationPermissionsPreview = "application/vnd.github.ironman-preview+json"; + + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + public const string GpgKeysPreview = "application/vnd.github.cryptographer-preview+sha"; } } From df5d5b144f2a27caab4c0356e530d23d0d9cdd9c Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Sun, 5 Jun 2016 10:48:51 +1000 Subject: [PATCH 02/11] Add UserGpgKeysClient --- Octokit/Clients/IUserGpgKeysClient.cs | 71 +++++++++++++++++++++ Octokit/Clients/UserGpgKeysClient.cs | 88 +++++++++++++++++++++++++++ Octokit/Helpers/ApiUrls.cs | 23 +++++++ Octokit/Models/Request/NewGpgKey.cs | 34 +++++++++++ Octokit/Models/Response/GpgKey.cs | 27 ++++++++ Octokit/Octokit-Mono.csproj | 4 ++ Octokit/Octokit-MonoAndroid.csproj | 4 ++ Octokit/Octokit-Monotouch.csproj | 4 ++ Octokit/Octokit-Portable.csproj | 4 ++ Octokit/Octokit-netcore45.csproj | 4 ++ Octokit/Octokit.csproj | 4 ++ 11 files changed, 267 insertions(+) create mode 100644 Octokit/Clients/IUserGpgKeysClient.cs create mode 100644 Octokit/Clients/UserGpgKeysClient.cs create mode 100644 Octokit/Models/Request/NewGpgKey.cs create mode 100644 Octokit/Models/Response/GpgKey.cs diff --git a/Octokit/Clients/IUserGpgKeysClient.cs b/Octokit/Clients/IUserGpgKeysClient.cs new file mode 100644 index 0000000000..57c4005349 --- /dev/null +++ b/Octokit/Clients/IUserGpgKeysClient.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's UserUser GPG Keys API. + /// + /// + /// See the User GPG Keys documentation for more information. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + public interface IUserGpgKeysClient + { + /// + /// Gets all GPG keys for the authenticated user. + /// + /// + /// See the API documentation for more information. + /// + /// A of s for the current user. + Task> GetAllForCurrent(); + + /// + /// Gets all GPG keys for the authenticated user. + /// + /// Options for changing the API response + /// + /// See the API documentation for more information. + /// + /// A of s for the current user. + Task> GetAllForCurrent(ApiOptions options); + + /// + /// View extended details of the for the specified id. + /// + /// The ID of the GPG key + /// + /// See the API documentation for more information. + /// + /// The for the specified ID. + [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", + Justification = "Method makes a network request")] + Task Get(int id); + + /// + /// Creates a new for the authenticated user. + /// + /// The new GPG key to add. + /// + /// See the API documentation for more information. + /// + /// The newly created . + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + Task Create(NewGpgKey newGpgKey); + + /// + /// Deletes the GPG key for the specified ID. + /// + /// The ID of the GPG key to delete. + /// + /// See the API documentation for more information. + /// + /// + Task Delete(int id); + } +} diff --git a/Octokit/Clients/UserGpgKeysClient.cs b/Octokit/Clients/UserGpgKeysClient.cs new file mode 100644 index 0000000000..f7a940e6c2 --- /dev/null +++ b/Octokit/Clients/UserGpgKeysClient.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's UserUser GPG Keys API. + /// + /// + /// See the User GPG Keys documentation for more information. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + public class UserGpgKeysClient : ApiClient, IUserGpgKeysClient + { + /// + /// Instatiates a new GitHub User GPG Keys API client. + /// + /// The API connection. + public UserGpgKeysClient(IApiConnection apiConnection) : base(apiConnection) + { + } + + /// + /// Gets all GPG keys for the authenticated user. + /// + /// + /// See the API documentation for more information. + /// + /// A of s for the current user. + public Task> GetAllForCurrent() + { + return GetAllForCurrent(ApiOptions.None); + } + + /// + /// Gets all GPG keys for the authenticated user. + /// + /// Options for changing the API response + /// + /// See the API documentation for more information. + /// + /// A of s for the current user. + public Task> GetAllForCurrent(ApiOptions options) + { + return ApiConnection.GetAll(ApiUrls.GpgKeys(), null, AcceptHeaders.GpgKeysPreview, options); + } + + /// + /// View extended details of the for the specified id. + /// + /// The ID of the GPG key + /// + /// See the API documentation for more information. + /// + /// The for the specified ID. + public Task Get(int id) + { + return ApiConnection.Get(ApiUrls.GpgKeys(id), null, AcceptHeaders.GpgKeysPreview); + } + + /// + /// Creates a new for the authenticated user. + /// + /// The new GPG key to add. + /// + /// See the API documentation for more information. + /// + /// The newly created . + public Task Create(NewGpgKey newGpgKey) + { + return ApiConnection.Post(ApiUrls.GpgKeys(), newGpgKey); + } + + /// + /// Deletes the GPG key for the specified ID. + /// + /// The ID of the GPG key to delete. + /// + /// See the API documentation for more information. + /// + /// + public Task Delete(int id) + { + return ApiConnection.Delete(ApiUrls.GpgKeys(id)); + } + } +} \ No newline at end of file diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index c6af35f219..7640ac6abb 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; namespace Octokit { @@ -10,6 +11,7 @@ public static partial class ApiUrls static readonly Uri _currentUserRepositoriesUrl = new Uri("user/repos", UriKind.Relative); static readonly Uri _currentUserOrganizationsUrl = new Uri("user/orgs", UriKind.Relative); static readonly Uri _currentUserSshKeys = new Uri("user/keys", UriKind.Relative); + static readonly Uri _currentUserGpgKeys = new Uri("user/gpg_keys", UriKind.Relative); static readonly Uri _currentUserStars = new Uri("user/starred", UriKind.Relative); static readonly Uri _currentUserWatched = new Uri("user/subscriptions", UriKind.Relative); static readonly Uri _currentUserEmailsEndpoint = new Uri("user/emails", UriKind.Relative); @@ -2146,6 +2148,27 @@ public static Uri Events(int repositoryId) return "repositories/{0}/events".FormatUri(repositoryId); } + /// + /// Returns the that returns all the GPG Keys for the authenticated user. + /// + /// The that returns all the GPG Keys for the authenticated user. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + public static Uri GpgKeys() + { + return _currentUserGpgKeys; + } + + /// + /// Returns the that returns the GPG Key for the authenticated user for the specified ID. + /// + /// The that returns the GPG Key for the authenticated user for the specified ID. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + public static Uri GpgKeys(int id) + { + return "user/gpg_keys/{0}".FormatUri(id); + } + /// /// Returns the for the specified issue. /// diff --git a/Octokit/Models/Request/NewGpgKey.cs b/Octokit/Models/Request/NewGpgKey.cs new file mode 100644 index 0000000000..428779b79d --- /dev/null +++ b/Octokit/Models/Request/NewGpgKey.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Octokit +{ + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + [DebuggerDisplay("{DebuggerDisplay,nq")] + public class NewGpgKey + { + public NewGpgKey() + { + } + + public NewGpgKey(string publicKey) + { + Ensure.ArgumentNotNullOrEmptyString(publicKey, "publicKey"); + + ArmoredPublicKey = publicKey; + } + + public string ArmoredPublicKey { get; set; } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "ArmoredPublicKey: {0}", ArmoredPublicKey); } + } + } +} diff --git a/Octokit/Models/Response/GpgKey.cs b/Octokit/Models/Response/GpgKey.cs new file mode 100644 index 0000000000..e7d6b9faae --- /dev/null +++ b/Octokit/Models/Response/GpgKey.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Octokit.Internal; + +namespace Octokit +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + public class GpgKey + { + public int Id { get; protected set; } + public int? PrimaryKeyId { get; protected set; } + public string KeyId { get; protected set; } + public string PublicKey { get; protected set; } + public IReadOnlyList Emails { get; protected set; } + public IReadOnlyList Subkeys { get; protected set; } + public bool CanSign { get; protected set; } + [Parameter(Key = "can_encrypt_comms")] + public bool CanEncryptCommunications { get; protected set; } + public bool CanEncryptStorage { get; protected set; } + public bool CanCertify { get; protected set; } + public DateTimeOffset CreatedAt { get; protected set; } + public DateTimeOffset? ExpiresAt { get; protected set; } + } +} diff --git a/Octokit/Octokit-Mono.csproj b/Octokit/Octokit-Mono.csproj index bb98c8a898..048f221873 100644 --- a/Octokit/Octokit-Mono.csproj +++ b/Octokit/Octokit-Mono.csproj @@ -467,6 +467,10 @@ + + + + \ No newline at end of file diff --git a/Octokit/Octokit-MonoAndroid.csproj b/Octokit/Octokit-MonoAndroid.csproj index cf0aa9e720..f9b8844ab2 100644 --- a/Octokit/Octokit-MonoAndroid.csproj +++ b/Octokit/Octokit-MonoAndroid.csproj @@ -478,6 +478,10 @@ + + + + \ No newline at end of file diff --git a/Octokit/Octokit-Monotouch.csproj b/Octokit/Octokit-Monotouch.csproj index cbb7347e06..b0ac11dfdc 100644 --- a/Octokit/Octokit-Monotouch.csproj +++ b/Octokit/Octokit-Monotouch.csproj @@ -474,6 +474,10 @@ + + + + diff --git a/Octokit/Octokit-Portable.csproj b/Octokit/Octokit-Portable.csproj index d5cc1c6eaf..66c9177cb0 100644 --- a/Octokit/Octokit-Portable.csproj +++ b/Octokit/Octokit-Portable.csproj @@ -464,6 +464,10 @@ + + + + diff --git a/Octokit/Octokit-netcore45.csproj b/Octokit/Octokit-netcore45.csproj index b6714a9baa..9b94327e74 100644 --- a/Octokit/Octokit-netcore45.csproj +++ b/Octokit/Octokit-netcore45.csproj @@ -471,6 +471,10 @@ + + + + diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index 24dad5da12..41b3dd0c52 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -58,6 +58,7 @@ Properties\SolutionInfo.cs + @@ -93,6 +94,7 @@ + @@ -120,6 +122,7 @@ + @@ -173,6 +176,7 @@ + From 0bbf3d2b40fb1f8ea637ae5c3a21d6da5ec04664 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Sun, 5 Jun 2016 11:17:35 +1000 Subject: [PATCH 03/11] Forgot to pass the preview accept header --- Octokit/Clients/UserGpgKeysClient.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Octokit/Clients/UserGpgKeysClient.cs b/Octokit/Clients/UserGpgKeysClient.cs index f7a940e6c2..5feeac2fd1 100644 --- a/Octokit/Clients/UserGpgKeysClient.cs +++ b/Octokit/Clients/UserGpgKeysClient.cs @@ -43,6 +43,8 @@ public Task> GetAllForCurrent() /// A of s for the current user. public Task> GetAllForCurrent(ApiOptions options) { + Ensure.ArgumentNotNull(options, "options"); + return ApiConnection.GetAll(ApiUrls.GpgKeys(), null, AcceptHeaders.GpgKeysPreview, options); } @@ -69,7 +71,9 @@ public Task Get(int id) /// The newly created . public Task Create(NewGpgKey newGpgKey) { - return ApiConnection.Post(ApiUrls.GpgKeys(), newGpgKey); + Ensure.ArgumentNotNull(newGpgKey, "newGpgKey"); + + return ApiConnection.Post(ApiUrls.GpgKeys(), newGpgKey, AcceptHeaders.GpgKeysPreview); } /// @@ -82,7 +86,7 @@ public Task Create(NewGpgKey newGpgKey) /// public Task Delete(int id) { - return ApiConnection.Delete(ApiUrls.GpgKeys(id)); + return ApiConnection.Delete(ApiUrls.GpgKeys(id), null, AcceptHeaders.GpgKeysPreview); } } } \ No newline at end of file From 06700b21f562e5f883382472d57077448824ba12 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Sun, 5 Jun 2016 11:53:01 +1000 Subject: [PATCH 04/11] Add unit tests --- .../Clients/UserGpgKeysClientTests.cs | 118 ++++++++++++++++++ Octokit.Tests/OctoKit.Tests-NetCore45.csproj | 1 + Octokit.Tests/Octokit.Tests-Portable.csproj | 1 + Octokit.Tests/Octokit.Tests.csproj | 1 + 4 files changed, 121 insertions(+) create mode 100644 Octokit.Tests/Clients/UserGpgKeysClientTests.cs diff --git a/Octokit.Tests/Clients/UserGpgKeysClientTests.cs b/Octokit.Tests/Clients/UserGpgKeysClientTests.cs new file mode 100644 index 0000000000..4e5d49ae27 --- /dev/null +++ b/Octokit.Tests/Clients/UserGpgKeysClientTests.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NSubstitute; +using Xunit; + +namespace Octokit.Tests.Clients +{ + public class UserGpgKeysClientTests + { + public class TheGetAllForCurrentMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new UserGpgKeysClient(connection); + + var expectedUri = ApiUrls.GpgKeys().ToString(); + client.GetAllForCurrent(); + + connection.Received().GetAll( + Arg.Is(u => u.ToString() == expectedUri), + Arg.Any>(), + Arg.Is(s => s == AcceptHeaders.GpgKeysPreview), + Arg.Any()); + } + } + + public class TheGetMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new UserGpgKeysClient(connection); + + var expectedUri = ApiUrls.GpgKeys(1).ToString(); + client.Get(1); + + connection.Received().Get( + Arg.Is(u => u.ToString() == expectedUri), + Arg.Any>(), + Arg.Is(s => s == AcceptHeaders.GpgKeysPreview)); + } + } + + public class TheCreateMethod + { + [Fact] + public async Task EnsuresNonNullArgument() + { + var client = new UserGpgKeysClient(Substitute.For()); + await Assert.ThrowsAsync(() => client.Create(null)); + } + + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new UserGpgKeysClient(connection); + + var expectedUri = ApiUrls.GpgKeys().ToString(); + client.Create(new NewGpgKey("ABCDEFG")); + + connection.Received().Post( + Arg.Is(u => u.ToString() == expectedUri), + Arg.Any(), + Arg.Is(s => s == AcceptHeaders.GpgKeysPreview)); + } + + [Fact] + public void PassesRequestObject() + { + var connection = Substitute.For(); + var client = new UserGpgKeysClient(connection); + + var expectedUri = ApiUrls.GpgKeys().ToString(); + client.Create(new NewGpgKey("ABCDEFG")); + + connection.Received().Post( + Arg.Any(), + Arg.Is(a => + a.ArmoredPublicKey == "ABCDEFG"), + Arg.Any()); + } + } + + public class TheDeleteMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new UserGpgKeysClient(connection); + + var expectedUri = ApiUrls.GpgKeys(1).ToString(); + client.Delete(1); + + connection.Received().Delete( + Arg.Is(u => u.ToString() == expectedUri), + Arg.Any(), + Arg.Is(s => s == AcceptHeaders.GpgKeysPreview)); + } + } + + public class TheCtor + { + [Fact] + public void EnsuresNonNullArgument() + { + Assert.Throws(() => new UserGpgKeysClient(null)); + } + } + } +} diff --git a/Octokit.Tests/OctoKit.Tests-NetCore45.csproj b/Octokit.Tests/OctoKit.Tests-NetCore45.csproj index c6f5566f49..7748e894c7 100644 --- a/Octokit.Tests/OctoKit.Tests-NetCore45.csproj +++ b/Octokit.Tests/OctoKit.Tests-NetCore45.csproj @@ -104,6 +104,7 @@ + diff --git a/Octokit.Tests/Octokit.Tests-Portable.csproj b/Octokit.Tests/Octokit.Tests-Portable.csproj index e79ed5b755..7efabfefca 100644 --- a/Octokit.Tests/Octokit.Tests-Portable.csproj +++ b/Octokit.Tests/Octokit.Tests-Portable.csproj @@ -113,6 +113,7 @@ + diff --git a/Octokit.Tests/Octokit.Tests.csproj b/Octokit.Tests/Octokit.Tests.csproj index 3482430140..ba9a8aad8c 100644 --- a/Octokit.Tests/Octokit.Tests.csproj +++ b/Octokit.Tests/Octokit.Tests.csproj @@ -131,6 +131,7 @@ + From 3ad22b5d9da1ff6e6d3b6776b939d9d4622942c7 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Sun, 5 Jun 2016 15:09:13 +1000 Subject: [PATCH 05/11] Add ObservableUserGpgKeysClient and fixes to satisfy convention tests --- .../Clients/IObservableUserGpgKeysClient.cs | 71 +++++++++++++ .../Clients/IObservableUsersClient.cs | 9 ++ .../Clients/ObservableUserGpgKeysClient.cs | 99 +++++++++++++++++++ .../Clients/ObservableUsersClient.cs | 11 +++ Octokit.Reactive/Octokit.Reactive-Mono.csproj | 4 +- .../Octokit.Reactive-MonoAndroid.csproj | 4 +- .../Octokit.Reactive-Monotouch.csproj | 4 +- Octokit.Reactive/Octokit.Reactive.csproj | 2 + .../Clients/UserGpgKeysClientTests.cs | 19 ++-- Octokit/Clients/IUsersClient.cs | 3 + Octokit/Clients/UsersClient.cs | 10 ++ Octokit/Models/Request/NewGpgKey.cs | 2 +- Octokit/Models/Response/GpgKey.cs | 8 ++ 13 files changed, 233 insertions(+), 13 deletions(-) create mode 100644 Octokit.Reactive/Clients/IObservableUserGpgKeysClient.cs create mode 100644 Octokit.Reactive/Clients/ObservableUserGpgKeysClient.cs diff --git a/Octokit.Reactive/Clients/IObservableUserGpgKeysClient.cs b/Octokit.Reactive/Clients/IObservableUserGpgKeysClient.cs new file mode 100644 index 0000000000..bd3ce36061 --- /dev/null +++ b/Octokit.Reactive/Clients/IObservableUserGpgKeysClient.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reactive; +using System.Text; +using System.Threading.Tasks; + +namespace Octokit.Reactive +{ + /// + /// A client for GitHub's UserUser GPG Keys API. + /// + /// + /// See the User GPG Keys documentation for more information. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + public interface IObservableUserGpgKeysClient + { + /// + /// Gets all GPG keys for the authenticated user. + /// + /// + /// See the API documentation for more information. + /// + /// A of s for the current user. + IObservable GetAllForCurrent(); + + /// + /// Gets all GPG keys for the authenticated user. + /// + /// Options for changing the API response + /// + /// See the API documentation for more information. + /// + /// A of s for the current user. + IObservable GetAllForCurrent(ApiOptions options); + + /// + /// View extended details of the for the specified id. + /// + /// The ID of the GPG key + /// + /// See the API documentation for more information. + /// + /// The for the specified ID. + [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")] + IObservable Get(int id); + + /// + /// Creates a new for the authenticated user. + /// + /// The new GPG key to add. + /// + /// See the API documentation for more information. + /// + /// The newly created . + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + IObservable Create(NewGpgKey newGpgKey); + + /// + /// Deletes the GPG key for the specified ID. + /// + /// The ID of the GPG key to delete. + /// + /// See the API documentation for more information. + /// + /// + IObservable Delete(int id); + } +} diff --git a/Octokit.Reactive/Clients/IObservableUsersClient.cs b/Octokit.Reactive/Clients/IObservableUsersClient.cs index 6672974aea..faa0d5029e 100644 --- a/Octokit.Reactive/Clients/IObservableUsersClient.cs +++ b/Octokit.Reactive/Clients/IObservableUsersClient.cs @@ -52,6 +52,15 @@ public interface IObservableUsersClient /// IObservableUserKeysClient Keys { get; } + /// + /// A client for GitHub's UserUser GPG Keys API. + /// + /// + /// See the User GPG Keys documentation for more information. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + IObservableUserGpgKeysClient GpgKeys { get; } + /// /// A client for GitHub's User Administration API /// diff --git a/Octokit.Reactive/Clients/ObservableUserGpgKeysClient.cs b/Octokit.Reactive/Clients/ObservableUserGpgKeysClient.cs new file mode 100644 index 0000000000..5031b560c6 --- /dev/null +++ b/Octokit.Reactive/Clients/ObservableUserGpgKeysClient.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reactive; +using System.Reactive.Linq; +using System.Reactive.Threading.Tasks; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using Octokit.Reactive.Internal; + +namespace Octokit.Reactive +{ + /// + /// A client for GitHub's UserUser GPG Keys API. + /// + /// + /// See the User GPG Keys documentation for more information. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + public class ObservableUserGpgKeysClient : IObservableUserGpgKeysClient + { + readonly IUserGpgKeysClient _client; + + public ObservableUserGpgKeysClient(IGitHubClient client) + { + Ensure.ArgumentNotNull(client, "client"); + + _client = client.User.GpgKeys; + } + + /// + /// Gets all GPG keys for the authenticated user. + /// + /// + /// See the API documentation for more information. + /// + /// A of s for the current user. + public IObservable GetAllForCurrent() + { + return GetAllForCurrent(ApiOptions.None); + } + + /// + /// Gets all GPG keys for the authenticated user. + /// + /// Options for changing the API response + /// + /// See the API documentation for more information. + /// + /// A of s for the current user. + public IObservable GetAllForCurrent(ApiOptions options) + { + return _client.GetAllForCurrent(options).ToObservable().SelectMany(k => k); + } + + /// + /// View extended details of the for the specified id. + /// + /// The ID of the GPG key + /// + /// See the API documentation for more information. + /// + /// The for the specified ID. + public IObservable Get(int id) + { + return _client.Get(id).ToObservable(); + } + + /// + /// Creates a new for the authenticated user. + /// + /// The new GPG key to add. + /// + /// See the API documentation for more information. + /// + /// The newly created . + public IObservable Create(NewGpgKey newGpgKey) + { + Ensure.ArgumentNotNull(newGpgKey, "newGpgKey"); + + return _client.Create(newGpgKey).ToObservable(); + } + + /// + /// Deletes the GPG key for the specified ID. + /// + /// The ID of the GPG key to delete. + /// + /// See the API documentation for more information. + /// + /// + public IObservable Delete(int id) + { + return _client.Delete(id).ToObservable(); + } + } +} diff --git a/Octokit.Reactive/Clients/ObservableUsersClient.cs b/Octokit.Reactive/Clients/ObservableUsersClient.cs index 7db13d3e32..e5ba4f943c 100644 --- a/Octokit.Reactive/Clients/ObservableUsersClient.cs +++ b/Octokit.Reactive/Clients/ObservableUsersClient.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Reactive.Threading.Tasks; namespace Octokit.Reactive @@ -16,6 +17,7 @@ public ObservableUsersClient(IGitHubClient client) Followers = new ObservableFollowersClient(client); Email = new ObservableUserEmailsClient(client); Keys = new ObservableUserKeysClient(client); + GpgKeys = new ObservableUserGpgKeysClient(client); Administration = new ObservableUserAdministrationClient(client); } @@ -77,6 +79,15 @@ public IObservable Update(UserUpdate user) /// public IObservableUserKeysClient Keys { get; private set; } + /// + /// A client for GitHub's UserUser GPG Keys API. + /// + /// + /// See the User GPG Keys documentation for more information. + /// + public IObservableUserGpgKeysClient GpgKeys { get; private set; } + + /// /// A client for GitHub's User Administration API /// diff --git a/Octokit.Reactive/Octokit.Reactive-Mono.csproj b/Octokit.Reactive/Octokit.Reactive-Mono.csproj index 9601cc8d7c..1144a6749b 100644 --- a/Octokit.Reactive/Octokit.Reactive-Mono.csproj +++ b/Octokit.Reactive/Octokit.Reactive-Mono.csproj @@ -180,6 +180,8 @@ + + @@ -188,4 +190,4 @@ Octokit-Mono - + \ No newline at end of file diff --git a/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj b/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj index bf75c3bf3b..40d5e7c561 100644 --- a/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj +++ b/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj @@ -188,6 +188,8 @@ + + @@ -196,4 +198,4 @@ Octokit-MonoAndroid - + \ No newline at end of file diff --git a/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj b/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj index 065807bc88..b8c011cc61 100644 --- a/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj +++ b/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj @@ -184,6 +184,8 @@ + + @@ -192,4 +194,4 @@ Octokit-Monotouch - + \ No newline at end of file diff --git a/Octokit.Reactive/Octokit.Reactive.csproj b/Octokit.Reactive/Octokit.Reactive.csproj index 920aefbe9c..be972db340 100644 --- a/Octokit.Reactive/Octokit.Reactive.csproj +++ b/Octokit.Reactive/Octokit.Reactive.csproj @@ -98,6 +98,7 @@ + @@ -179,6 +180,7 @@ + diff --git a/Octokit.Tests/Clients/UserGpgKeysClientTests.cs b/Octokit.Tests/Clients/UserGpgKeysClientTests.cs index 4e5d49ae27..73fe4df7d6 100644 --- a/Octokit.Tests/Clients/UserGpgKeysClientTests.cs +++ b/Octokit.Tests/Clients/UserGpgKeysClientTests.cs @@ -10,6 +10,16 @@ namespace Octokit.Tests.Clients { public class UserGpgKeysClientTests { + + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new UserGpgKeysClient(null)); + } + } + public class TheGetAllForCurrentMethod { [Fact] @@ -105,14 +115,5 @@ public void RequestsTheCorrectUrl() Arg.Is(s => s == AcceptHeaders.GpgKeysPreview)); } } - - public class TheCtor - { - [Fact] - public void EnsuresNonNullArgument() - { - Assert.Throws(() => new UserGpgKeysClient(null)); - } - } } } diff --git a/Octokit/Clients/IUsersClient.cs b/Octokit/Clients/IUsersClient.cs index d08b41c67c..046441aefd 100644 --- a/Octokit/Clients/IUsersClient.cs +++ b/Octokit/Clients/IUsersClient.cs @@ -27,6 +27,9 @@ public interface IUsersClient /// IUserKeysClient Keys { get; } + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + IUserGpgKeysClient GpgKeys { get; } + /// /// Returns the user specified by the login. /// diff --git a/Octokit/Clients/UsersClient.cs b/Octokit/Clients/UsersClient.cs index 4e835142cc..e041615a75 100644 --- a/Octokit/Clients/UsersClient.cs +++ b/Octokit/Clients/UsersClient.cs @@ -22,6 +22,8 @@ public UsersClient(IApiConnection apiConnection) : base(apiConnection) Email = new UserEmailsClient(apiConnection); Followers = new FollowersClient(apiConnection); Keys = new UserKeysClient(apiConnection); + GpgKeys = new UserGpgKeysClient(apiConnection); + Administration = new UserAdministrationClient(apiConnection); } @@ -41,6 +43,14 @@ public UsersClient(IApiConnection apiConnection) : base(apiConnection) /// public IUserKeysClient Keys { get; private set; } + /// + /// A client for GitHub's UserUser GPG Keys API. + /// + /// + /// See the User GPG Keys documentation for more information. + /// + public IUserGpgKeysClient GpgKeys { get; private set; } + /// /// Returns the user specified by the login. /// diff --git a/Octokit/Models/Request/NewGpgKey.cs b/Octokit/Models/Request/NewGpgKey.cs index 428779b79d..13d4773619 100644 --- a/Octokit/Models/Request/NewGpgKey.cs +++ b/Octokit/Models/Request/NewGpgKey.cs @@ -10,7 +10,7 @@ namespace Octokit { [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] - [DebuggerDisplay("{DebuggerDisplay,nq")] + [DebuggerDisplay("{DebuggerDisplay,nq}")] public class NewGpgKey { public NewGpgKey() diff --git a/Octokit/Models/Response/GpgKey.cs b/Octokit/Models/Response/GpgKey.cs index e7d6b9faae..616d91c532 100644 --- a/Octokit/Models/Response/GpgKey.cs +++ b/Octokit/Models/Response/GpgKey.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -8,6 +10,7 @@ namespace Octokit { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] + [DebuggerDisplay("{DebuggerDisplay,nq}")] public class GpgKey { public int Id { get; protected set; } @@ -23,5 +26,10 @@ public class GpgKey public bool CanCertify { get; protected set; } public DateTimeOffset CreatedAt { get; protected set; } public DateTimeOffset? ExpiresAt { get; protected set; } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "Id: {0} Key: {1}", Id, PublicKey); } + } } } From 7171535d8d202d8103e2f831ac9f9dc56a96ae49 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Sun, 5 Jun 2016 17:45:42 +1000 Subject: [PATCH 06/11] Add integration tests for UserGpgKeysClient --- .../Clients/UserGpgKeysClientTests.cs | 103 ++++++++++++++++++ .../Helpers/GithubClientExtensions.cs | 28 +++++ .../Helpers/GpgKeyContext.cs | 39 +++++++ .../Octokit.Tests.Integration.csproj | 2 + Octokit/Clients/UserGpgKeysClient.cs | 2 +- 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs create mode 100644 Octokit.Tests.Integration/Helpers/GpgKeyContext.cs diff --git a/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs b/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs new file mode 100644 index 0000000000..f1929798db --- /dev/null +++ b/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Octokit.Tests.Integration.Helpers; +using Xunit; + +namespace Octokit.Tests.Integration.Clients +{ + public class UserGpgKeysClientTests + { + // Create a key + readonly string knownKeyId = "E88402D2E127A23A"; + readonly string knownPublicKey = "xsBNBFdTvCUBCADOaVtPoJTQOgMIVYEpI8uT60LA/kDqw/1OKn7ftKjAtxNVSgjQi/ZqZp8XKjTg2u6l4c/aPjER2BGTg90xCcbmpwq/kkQuHR4DK7dOlEOoTzDDESEFv6XXlXGCnxN8AD8YNvSO+Sy4+35ihuKUBAHDxmOl7ZAMH0STo10KuW82/DhfT3cCJNqmID7H+CW1H6IhwutPKt8XsVq2FQg2RMx+uX1KqkuBAd7b30KJ93SJqzgq5CC3DticaC0/WdZnxmYD01UvMAS6o/REs+SICdsyTxgBx/X8SIXuX2TD9PG/O2785JI5/xvBd4jU6bBH/4oWoHr3e/lyNqb1+GSeTFX3ABEBAAE="; + + readonly string publicKey = @" +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: BCPG C# v1.6.1.0 + +mQENBFdTvCUBCADOaVtPoJTQOgMIVYEpI8uT60LA/kDqw/1OKn7ftKjAtxNVSgjQ +i/ZqZp8XKjTg2u6l4c/aPjER2BGTg90xCcbmpwq/kkQuHR4DK7dOlEOoTzDDESEF +v6XXlXGCnxN8AD8YNvSO+Sy4+35ihuKUBAHDxmOl7ZAMH0STo10KuW82/DhfT3cC +JNqmID7H+CW1H6IhwutPKt8XsVq2FQg2RMx+uX1KqkuBAd7b30KJ93SJqzgq5CC3 +DticaC0/WdZnxmYD01UvMAS6o/REs+SICdsyTxgBx/X8SIXuX2TD9PG/O2785JI5 +/xvBd4jU6bBH/4oWoHr3e/lyNqb1+GSeTFX3ABEBAAG0AIkBHAQQAQIABgUCV1O8 +JQAKCRDohALS4SeiOs/QB/9PMeFNdPkB1xfBm3qvTErqvhTcQspPibucYefG6JHL +vhm6iCOVBeCuPS4P/T8RTzb0qJaTdZZWcwZ9UjRVqF/RKwdMJTBKBHRegc5hRjLH +Koxk0zXosk+CapIR6eVhHe4IzpVVxZOvunsFOclIh+qHx9UzJhz9wSO/XBn/6Rzr +DGzE9fpK1JRKC0I3PuiDCNuZvojXeUsT/zuHYsz00wnA2Em7CmcWWng3nPUSHvBB +GUJ7YE7NvYXqT09PdhoZnf9p1wOugiuG6CLzWf8stlNV3mZptpP+sCGcz/UVffRO +VO/+BCBsaoT4g1FFOmJhbBAD3G72yslBnUJmqKP/39pi +=O7Yi +-----END PGP PUBLIC KEY BLOCK----- +"; + + [IntegrationTest] + public async Task CanGetAllForCurrentUser() + { + var github = Helper.GetBasicAuthClient(); + + using (var context = await github.CreateGpgKeyContext()) + { + var keys = await github.User.GpgKeys.GetAllForCurrent(); + Assert.NotEmpty(keys); + + var first = keys[0]; + Assert.NotNull(first.Id); + Assert.NotNull(first.KeyId); + Assert.NotNull(first.PublicKey); + Assert.Null(first.PrimaryKeyId); + Assert.Empty(first.Subkeys); + } + } + + [IntegrationTest] + public async Task CanGetKeyById() + { + var github = Helper.GetBasicAuthClient(); + using (var context = await github.CreateGpgKeyContext()) + { + var key = await github.User.GpgKeys.Get(context.GpgKeyId); + + Assert.Equal(context.GpgKeyId, key.Id); + Assert.Equal(context.KeyId, key.KeyId); + Assert.Equal(context.PublicKeyData, key.PublicKey); + } + } + + [IntegrationTest] + public async Task CanCreateAndDeleteKey() + { + var github = Helper.GetBasicAuthClient(); + + var key = await github.User.GpgKeys.Create(new NewGpgKey(publicKey)); + Assert.NotNull(key); + Assert.Equal(knownPublicKey, key.PublicKey); + Assert.Equal(knownKeyId, key.KeyId); + + // Delete the key + await github.User.GpgKeys.Delete(key.Id); + + // Verify key no longer exists + var keys = await github.User.GpgKeys.GetAllForCurrent(); + Assert.False(keys.Any(k => k.KeyId == knownKeyId && k.PublicKey == knownPublicKey)); + } + + [IntegrationTest] + public async Task CanNotCreateSameKeyTwice() + { + var github = Helper.GetBasicAuthClient(); + + var key = await github.User.GpgKeys.Create(new NewGpgKey(publicKey)); + Assert.NotNull(key); + + Assert.ThrowsAsync(async () => await github.User.GpgKeys.Create(new NewGpgKey(publicKey))); + + await github.User.GpgKeys.Delete(key.Id); + var keys = await github.User.GpgKeys.GetAllForCurrent(); + Assert.False(keys.Any(k => k.KeyId == knownKeyId && k.PublicKey == knownPublicKey)); + } + } +} diff --git a/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs b/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs index 18604004ee..ef5e2857d1 100644 --- a/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs +++ b/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs @@ -50,5 +50,33 @@ internal static async Task CreatePublicKeyContext(this IGitHub return new PublicKeyContext(client.Connection, key); } + + internal static async Task CreateGpgKeyContext(this IGitHubClient client) + { + // Create a key + string publicKey = @" +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: BCPG C# v1.6.1.0 + +mQENBFdTvCUBCADOaVtPoJTQOgMIVYEpI8uT60LA/kDqw/1OKn7ftKjAtxNVSgjQ +i/ZqZp8XKjTg2u6l4c/aPjER2BGTg90xCcbmpwq/kkQuHR4DK7dOlEOoTzDDESEF +v6XXlXGCnxN8AD8YNvSO+Sy4+35ihuKUBAHDxmOl7ZAMH0STo10KuW82/DhfT3cC +JNqmID7H+CW1H6IhwutPKt8XsVq2FQg2RMx+uX1KqkuBAd7b30KJ93SJqzgq5CC3 +DticaC0/WdZnxmYD01UvMAS6o/REs+SICdsyTxgBx/X8SIXuX2TD9PG/O2785JI5 +/xvBd4jU6bBH/4oWoHr3e/lyNqb1+GSeTFX3ABEBAAG0AIkBHAQQAQIABgUCV1O8 +JQAKCRDohALS4SeiOs/QB/9PMeFNdPkB1xfBm3qvTErqvhTcQspPibucYefG6JHL +vhm6iCOVBeCuPS4P/T8RTzb0qJaTdZZWcwZ9UjRVqF/RKwdMJTBKBHRegc5hRjLH +Koxk0zXosk+CapIR6eVhHe4IzpVVxZOvunsFOclIh+qHx9UzJhz9wSO/XBn/6Rzr +DGzE9fpK1JRKC0I3PuiDCNuZvojXeUsT/zuHYsz00wnA2Em7CmcWWng3nPUSHvBB +GUJ7YE7NvYXqT09PdhoZnf9p1wOugiuG6CLzWf8stlNV3mZptpP+sCGcz/UVffRO +VO/+BCBsaoT4g1FFOmJhbBAD3G72yslBnUJmqKP/39pi +=O7Yi +-----END PGP PUBLIC KEY BLOCK----- +"; + + var key = await client.User.GpgKeys.Create(new NewGpgKey(publicKey)); + + return new GpgKeyContext(key); + } } } \ No newline at end of file diff --git a/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs b/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs new file mode 100644 index 0000000000..58b2a15d60 --- /dev/null +++ b/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Octokit.Tests.Integration.Helpers +{ + public class GpgKeyContext : IDisposable + { + internal GpgKeyContext(GpgKey key) + { + Key = key; + GpgKeyId = key.Id; + KeyId = key.KeyId; + PublicKeyData = key.PublicKey; + } + + + internal int GpgKeyId { get; set; } + internal string KeyId { get; set; } + internal string PublicKeyData { get; set; } + + internal GpgKey Key { get; set; } + + public void Dispose() + { + if (Key != null) + { + var api = Helper.GetBasicAuthClient(); + try + { + api.User.GpgKeys.Delete(Key.Id).Wait(TimeSpan.FromSeconds(15)); + } + catch { } + } + } + } +} diff --git a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj index afe0511eb7..366d5b28b2 100644 --- a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj +++ b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj @@ -112,12 +112,14 @@ + + diff --git a/Octokit/Clients/UserGpgKeysClient.cs b/Octokit/Clients/UserGpgKeysClient.cs index 5feeac2fd1..14ba7cd4e4 100644 --- a/Octokit/Clients/UserGpgKeysClient.cs +++ b/Octokit/Clients/UserGpgKeysClient.cs @@ -86,7 +86,7 @@ public Task Create(NewGpgKey newGpgKey) /// public Task Delete(int id) { - return ApiConnection.Delete(ApiUrls.GpgKeys(id), null, AcceptHeaders.GpgKeysPreview); + return ApiConnection.Delete(ApiUrls.GpgKeys(id), new object(), AcceptHeaders.GpgKeysPreview); } } } \ No newline at end of file From df9ffd9b0d0f53f363056a3ee39f5084b7b2524e Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Sun, 5 Jun 2016 21:29:49 +1000 Subject: [PATCH 07/11] Add unit and integration tests for ObservableUserGpgKeysClient --- .../Clients/UserGpgKeysClientTests.cs | 1 - .../ObservableGithubClientExtensions.cs | 28 ++++++ .../Octokit.Tests.Integration.csproj | 1 + .../ObservableUserGpgKeysClientTests.cs | 95 +++++++++++++++++++ Octokit.Tests/Octokit.Tests.csproj | 1 + .../ObservableUserGpgKeysClientTests.cs | 79 +++++++++++++++ 6 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs create mode 100644 Octokit.Tests/Reactive/ObservableUserGpgKeysClientTests.cs diff --git a/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs b/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs index f1929798db..60ab3e1eb5 100644 --- a/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs +++ b/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs @@ -10,7 +10,6 @@ namespace Octokit.Tests.Integration.Clients { public class UserGpgKeysClientTests { - // Create a key readonly string knownKeyId = "E88402D2E127A23A"; readonly string knownPublicKey = "xsBNBFdTvCUBCADOaVtPoJTQOgMIVYEpI8uT60LA/kDqw/1OKn7ftKjAtxNVSgjQi/ZqZp8XKjTg2u6l4c/aPjER2BGTg90xCcbmpwq/kkQuHR4DK7dOlEOoTzDDESEFv6XXlXGCnxN8AD8YNvSO+Sy4+35ihuKUBAHDxmOl7ZAMH0STo10KuW82/DhfT3cCJNqmID7H+CW1H6IhwutPKt8XsVq2FQg2RMx+uX1KqkuBAd7b30KJ93SJqzgq5CC3DticaC0/WdZnxmYD01UvMAS6o/REs+SICdsyTxgBx/X8SIXuX2TD9PG/O2785JI5/xvBd4jU6bBH/4oWoHr3e/lyNqb1+GSeTFX3ABEBAAE="; diff --git a/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs b/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs index 12ab85f23b..0d2dcf4e95 100644 --- a/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs +++ b/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs @@ -52,5 +52,33 @@ internal static async Task CreatePublicKeyContext(this IObserv return new PublicKeyContext(client.Connection, key); } + + internal static async Task CreateGpgKeyContext(this IObservableGitHubClient client) + { + // Create a key + string publicKey = @" +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: BCPG C# v1.6.1.0 + +mQENBFdTvCUBCADOaVtPoJTQOgMIVYEpI8uT60LA/kDqw/1OKn7ftKjAtxNVSgjQ +i/ZqZp8XKjTg2u6l4c/aPjER2BGTg90xCcbmpwq/kkQuHR4DK7dOlEOoTzDDESEF +v6XXlXGCnxN8AD8YNvSO+Sy4+35ihuKUBAHDxmOl7ZAMH0STo10KuW82/DhfT3cC +JNqmID7H+CW1H6IhwutPKt8XsVq2FQg2RMx+uX1KqkuBAd7b30KJ93SJqzgq5CC3 +DticaC0/WdZnxmYD01UvMAS6o/REs+SICdsyTxgBx/X8SIXuX2TD9PG/O2785JI5 +/xvBd4jU6bBH/4oWoHr3e/lyNqb1+GSeTFX3ABEBAAG0AIkBHAQQAQIABgUCV1O8 +JQAKCRDohALS4SeiOs/QB/9PMeFNdPkB1xfBm3qvTErqvhTcQspPibucYefG6JHL +vhm6iCOVBeCuPS4P/T8RTzb0qJaTdZZWcwZ9UjRVqF/RKwdMJTBKBHRegc5hRjLH +Koxk0zXosk+CapIR6eVhHe4IzpVVxZOvunsFOclIh+qHx9UzJhz9wSO/XBn/6Rzr +DGzE9fpK1JRKC0I3PuiDCNuZvojXeUsT/zuHYsz00wnA2Em7CmcWWng3nPUSHvBB +GUJ7YE7NvYXqT09PdhoZnf9p1wOugiuG6CLzWf8stlNV3mZptpP+sCGcz/UVffRO +VO/+BCBsaoT4g1FFOmJhbBAD3G72yslBnUJmqKP/39pi +=O7Yi +-----END PGP PUBLIC KEY BLOCK----- +"; + + var key = await client.User.GpgKeys.Create(new NewGpgKey(publicKey)); + + return new GpgKeyContext(key); + } } } \ No newline at end of file diff --git a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj index 366d5b28b2..6748e03498 100644 --- a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj +++ b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj @@ -168,6 +168,7 @@ + diff --git a/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs new file mode 100644 index 0000000000..c24d756d0e --- /dev/null +++ b/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive.Linq; +using System.Text; +using System.Threading.Tasks; +using Octokit.Reactive; +using Octokit.Tests.Integration.Helpers; +using Xunit; + +namespace Octokit.Tests.Integration.Reactive +{ + public class ObservableUserGpgKeysClientTests + { + readonly string knownKeyId = "E88402D2E127A23A"; + readonly string knownPublicKey = "xsBNBFdTvCUBCADOaVtPoJTQOgMIVYEpI8uT60LA/kDqw/1OKn7ftKjAtxNVSgjQi/ZqZp8XKjTg2u6l4c/aPjER2BGTg90xCcbmpwq/kkQuHR4DK7dOlEOoTzDDESEFv6XXlXGCnxN8AD8YNvSO+Sy4+35ihuKUBAHDxmOl7ZAMH0STo10KuW82/DhfT3cCJNqmID7H+CW1H6IhwutPKt8XsVq2FQg2RMx+uX1KqkuBAd7b30KJ93SJqzgq5CC3DticaC0/WdZnxmYD01UvMAS6o/REs+SICdsyTxgBx/X8SIXuX2TD9PG/O2785JI5/xvBd4jU6bBH/4oWoHr3e/lyNqb1+GSeTFX3ABEBAAE="; + + readonly IObservableGitHubClient _gitHubClient; + + public ObservableUserGpgKeysClientTests() + { + _gitHubClient = new ObservableGitHubClient(Helper.GetBasicAuthClient()); + } + + [IntegrationTest] + public async Task CanGetAllForCurrentUser() + { + using (var context = _gitHubClient.CreateGpgKeyContext()) + { + var observable = _gitHubClient.User.GpgKeys.GetAllForCurrent(); + var keys = await observable.ToList(); + + Assert.NotEmpty(keys); + + var first = keys[0]; + Assert.NotNull(first.Id); + Assert.Null(first.PrimaryKeyId); + Assert.NotNull(first.KeyId); + Assert.NotNull(first.PublicKey); + Assert.Empty(first.Subkeys); + } + } + + [IntegrationTest] + public async Task CanGetKeyById() + { + using (var context = await _gitHubClient.CreateGpgKeyContext()) + { + var observable = _gitHubClient.User.GpgKeys.Get(context.GpgKeyId); + var key = await observable; + + Assert.Equal(knownKeyId, key.KeyId); + Assert.Equal(knownPublicKey, key.PublicKey); + } + } + + [IntegrationTest] + public async Task CanCreateAndDeleteKey() + { + string publicKey = @" +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: BCPG C# v1.6.1.0 + +mQENBFdTvCUBCADOaVtPoJTQOgMIVYEpI8uT60LA/kDqw/1OKn7ftKjAtxNVSgjQ +i/ZqZp8XKjTg2u6l4c/aPjER2BGTg90xCcbmpwq/kkQuHR4DK7dOlEOoTzDDESEF +v6XXlXGCnxN8AD8YNvSO+Sy4+35ihuKUBAHDxmOl7ZAMH0STo10KuW82/DhfT3cC +JNqmID7H+CW1H6IhwutPKt8XsVq2FQg2RMx+uX1KqkuBAd7b30KJ93SJqzgq5CC3 +DticaC0/WdZnxmYD01UvMAS6o/REs+SICdsyTxgBx/X8SIXuX2TD9PG/O2785JI5 +/xvBd4jU6bBH/4oWoHr3e/lyNqb1+GSeTFX3ABEBAAG0AIkBHAQQAQIABgUCV1O8 +JQAKCRDohALS4SeiOs/QB/9PMeFNdPkB1xfBm3qvTErqvhTcQspPibucYefG6JHL +vhm6iCOVBeCuPS4P/T8RTzb0qJaTdZZWcwZ9UjRVqF/RKwdMJTBKBHRegc5hRjLH +Koxk0zXosk+CapIR6eVhHe4IzpVVxZOvunsFOclIh+qHx9UzJhz9wSO/XBn/6Rzr +DGzE9fpK1JRKC0I3PuiDCNuZvojXeUsT/zuHYsz00wnA2Em7CmcWWng3nPUSHvBB +GUJ7YE7NvYXqT09PdhoZnf9p1wOugiuG6CLzWf8stlNV3mZptpP+sCGcz/UVffRO +VO/+BCBsaoT4g1FFOmJhbBAD3G72yslBnUJmqKP/39pi +=O7Yi +-----END PGP PUBLIC KEY BLOCK----- +"; + // Create a key + var observable = _gitHubClient.User.GpgKeys.Create(new NewGpgKey(publicKey)); + var key = await observable; + + Assert.NotNull(key); + Assert.Equal(knownKeyId, key.KeyId); + Assert.Equal(knownPublicKey, key.PublicKey); + + // Delete the key + await _gitHubClient.User.GpgKeys.Delete(key.Id); + + // Verify key no longer exists + var keys = await _gitHubClient.User.GpgKeys.GetAllForCurrent().ToList(); + Assert.False(keys.Any(k => k.KeyId == knownKeyId && k.PublicKey == knownPublicKey)); + } + } +} diff --git a/Octokit.Tests/Octokit.Tests.csproj b/Octokit.Tests/Octokit.Tests.csproj index ba9a8aad8c..ab7cfb9874 100644 --- a/Octokit.Tests/Octokit.Tests.csproj +++ b/Octokit.Tests/Octokit.Tests.csproj @@ -238,6 +238,7 @@ + diff --git a/Octokit.Tests/Reactive/ObservableUserGpgKeysClientTests.cs b/Octokit.Tests/Reactive/ObservableUserGpgKeysClientTests.cs new file mode 100644 index 0000000000..ca2cc0b630 --- /dev/null +++ b/Octokit.Tests/Reactive/ObservableUserGpgKeysClientTests.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NSubstitute; +using Octokit.Reactive; +using Xunit; + +namespace Octokit.Tests.Reactive +{ + public class ObservableUserGpgKeysClientTests + { + public class TheGetAllForCurrentMethod + { + [Fact] + public void CallsIntoClient() + { + var githubClient = Substitute.For(); + var client = new ObservableUserGpgKeysClient(githubClient); + + client.GetAllForCurrent(); + + githubClient.User.GpgKeys.Received().GetAllForCurrent(Arg.Any()); + } + } + + public class TheGetMethod + { + [Fact] + public void CallsIntoClient() + { + var githubClient = Substitute.For(); + var client = new ObservableUserGpgKeysClient(githubClient); + + client.Get(1); + + githubClient.User.GpgKeys.Received().Get(1); + } + } + + public class TheCreateMethod + { + [Fact] + public void CallsIntoClient() + { + var githubClient = Substitute.For(); + var client = new ObservableUserGpgKeysClient(githubClient); + + client.Create(new NewGpgKey("ABCDEFG")); + + githubClient.User.GpgKeys.Received().Create(Arg.Is(k => k.ArmoredPublicKey == "ABCDEFG")); + } + } + + public class TheDeleteMethod + { + [Fact] + public void CallsIntoClient() + { + var githubClient = Substitute.For(); + var client = new ObservableUserGpgKeysClient(githubClient); + + client.Delete(1); + + githubClient.User.GpgKeys.Received().Delete(1); + } + } + + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new ObservableUserGpgKeysClient(null)); + } + } + } +} From 77b04efbdd3fda0e37ec1ed3771ee4da60f5c9c1 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Mon, 6 Jun 2016 23:25:40 +1000 Subject: [PATCH 08/11] Fixes as per PR review comments --- .../Clients/IObservableUsersClient.cs | 2 +- .../Clients/ObservableUserGpgKeysClient.cs | 2 +- .../Clients/ObservableUsersClient.cs | 5 ++--- .../Clients/UserGpgKeysClientTests.cs | 18 ++++++++--------- .../Helpers/GithubClientExtensions.cs | 2 +- .../Helpers/GpgKeyContext.cs | 2 +- .../ObservableGithubClientExtensions.cs | 2 +- .../ObservableUserGpgKeysClientTests.cs | 10 +++++----- .../Clients/UserGpgKeysClientTests.cs | 20 +++++++++---------- .../ObservableUserGpgKeysClientTests.cs | 8 ++++---- Octokit/Clients/IUsersClient.cs | 2 +- Octokit/Clients/UsersClient.cs | 4 ++-- 12 files changed, 38 insertions(+), 39 deletions(-) diff --git a/Octokit.Reactive/Clients/IObservableUsersClient.cs b/Octokit.Reactive/Clients/IObservableUsersClient.cs index faa0d5029e..6c23a45982 100644 --- a/Octokit.Reactive/Clients/IObservableUsersClient.cs +++ b/Octokit.Reactive/Clients/IObservableUsersClient.cs @@ -59,7 +59,7 @@ public interface IObservableUsersClient /// See the User GPG Keys documentation for more information. /// [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] - IObservableUserGpgKeysClient GpgKeys { get; } + IObservableUserGpgKeysClient GpgKey { get; } /// /// A client for GitHub's User Administration API diff --git a/Octokit.Reactive/Clients/ObservableUserGpgKeysClient.cs b/Octokit.Reactive/Clients/ObservableUserGpgKeysClient.cs index 5031b560c6..6f635fb6af 100644 --- a/Octokit.Reactive/Clients/ObservableUserGpgKeysClient.cs +++ b/Octokit.Reactive/Clients/ObservableUserGpgKeysClient.cs @@ -27,7 +27,7 @@ public ObservableUserGpgKeysClient(IGitHubClient client) { Ensure.ArgumentNotNull(client, "client"); - _client = client.User.GpgKeys; + _client = client.User.GpgKey; } /// diff --git a/Octokit.Reactive/Clients/ObservableUsersClient.cs b/Octokit.Reactive/Clients/ObservableUsersClient.cs index e5ba4f943c..30891c4d6d 100644 --- a/Octokit.Reactive/Clients/ObservableUsersClient.cs +++ b/Octokit.Reactive/Clients/ObservableUsersClient.cs @@ -17,7 +17,7 @@ public ObservableUsersClient(IGitHubClient client) Followers = new ObservableFollowersClient(client); Email = new ObservableUserEmailsClient(client); Keys = new ObservableUserKeysClient(client); - GpgKeys = new ObservableUserGpgKeysClient(client); + GpgKey = new ObservableUserGpgKeysClient(client); Administration = new ObservableUserAdministrationClient(client); } @@ -85,8 +85,7 @@ public IObservable Update(UserUpdate user) /// /// See the User GPG Keys documentation for more information. /// - public IObservableUserGpgKeysClient GpgKeys { get; private set; } - + public IObservableUserGpgKeysClient GpgKey { get; private set; } /// /// A client for GitHub's User Administration API diff --git a/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs b/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs index 60ab3e1eb5..30e1860456 100644 --- a/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs +++ b/Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs @@ -40,7 +40,7 @@ public async Task CanGetAllForCurrentUser() using (var context = await github.CreateGpgKeyContext()) { - var keys = await github.User.GpgKeys.GetAllForCurrent(); + var keys = await github.User.GpgKey.GetAllForCurrent(); Assert.NotEmpty(keys); var first = keys[0]; @@ -58,7 +58,7 @@ public async Task CanGetKeyById() var github = Helper.GetBasicAuthClient(); using (var context = await github.CreateGpgKeyContext()) { - var key = await github.User.GpgKeys.Get(context.GpgKeyId); + var key = await github.User.GpgKey.Get(context.GpgKeyId); Assert.Equal(context.GpgKeyId, key.Id); Assert.Equal(context.KeyId, key.KeyId); @@ -71,16 +71,16 @@ public async Task CanCreateAndDeleteKey() { var github = Helper.GetBasicAuthClient(); - var key = await github.User.GpgKeys.Create(new NewGpgKey(publicKey)); + var key = await github.User.GpgKey.Create(new NewGpgKey(publicKey)); Assert.NotNull(key); Assert.Equal(knownPublicKey, key.PublicKey); Assert.Equal(knownKeyId, key.KeyId); // Delete the key - await github.User.GpgKeys.Delete(key.Id); + await github.User.GpgKey.Delete(key.Id); // Verify key no longer exists - var keys = await github.User.GpgKeys.GetAllForCurrent(); + var keys = await github.User.GpgKey.GetAllForCurrent(); Assert.False(keys.Any(k => k.KeyId == knownKeyId && k.PublicKey == knownPublicKey)); } @@ -89,13 +89,13 @@ public async Task CanNotCreateSameKeyTwice() { var github = Helper.GetBasicAuthClient(); - var key = await github.User.GpgKeys.Create(new NewGpgKey(publicKey)); + var key = await github.User.GpgKey.Create(new NewGpgKey(publicKey)); Assert.NotNull(key); - Assert.ThrowsAsync(async () => await github.User.GpgKeys.Create(new NewGpgKey(publicKey))); + Assert.ThrowsAsync(async () => await github.User.GpgKey.Create(new NewGpgKey(publicKey))); - await github.User.GpgKeys.Delete(key.Id); - var keys = await github.User.GpgKeys.GetAllForCurrent(); + await github.User.GpgKey.Delete(key.Id); + var keys = await github.User.GpgKey.GetAllForCurrent(); Assert.False(keys.Any(k => k.KeyId == knownKeyId && k.PublicKey == knownPublicKey)); } } diff --git a/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs b/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs index ef5e2857d1..2aa0c72615 100644 --- a/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs +++ b/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs @@ -74,7 +74,7 @@ internal static async Task CreateGpgKeyContext(this IGitHubClient -----END PGP PUBLIC KEY BLOCK----- "; - var key = await client.User.GpgKeys.Create(new NewGpgKey(publicKey)); + var key = await client.User.GpgKey.Create(new NewGpgKey(publicKey)); return new GpgKeyContext(key); } diff --git a/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs b/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs index 58b2a15d60..4260151adf 100644 --- a/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs +++ b/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs @@ -30,7 +30,7 @@ public void Dispose() var api = Helper.GetBasicAuthClient(); try { - api.User.GpgKeys.Delete(Key.Id).Wait(TimeSpan.FromSeconds(15)); + api.User.GpgKey.Delete(Key.Id).Wait(TimeSpan.FromSeconds(15)); } catch { } } diff --git a/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs b/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs index 0d2dcf4e95..72730612a7 100644 --- a/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs +++ b/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs @@ -76,7 +76,7 @@ internal static async Task CreateGpgKeyContext(this IObservableGi -----END PGP PUBLIC KEY BLOCK----- "; - var key = await client.User.GpgKeys.Create(new NewGpgKey(publicKey)); + var key = await client.User.GpgKey.Create(new NewGpgKey(publicKey)); return new GpgKeyContext(key); } diff --git a/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs index c24d756d0e..7934dd6fe2 100644 --- a/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs +++ b/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs @@ -27,7 +27,7 @@ public async Task CanGetAllForCurrentUser() { using (var context = _gitHubClient.CreateGpgKeyContext()) { - var observable = _gitHubClient.User.GpgKeys.GetAllForCurrent(); + var observable = _gitHubClient.User.GpgKey.GetAllForCurrent(); var keys = await observable.ToList(); Assert.NotEmpty(keys); @@ -46,7 +46,7 @@ public async Task CanGetKeyById() { using (var context = await _gitHubClient.CreateGpgKeyContext()) { - var observable = _gitHubClient.User.GpgKeys.Get(context.GpgKeyId); + var observable = _gitHubClient.User.GpgKey.Get(context.GpgKeyId); var key = await observable; Assert.Equal(knownKeyId, key.KeyId); @@ -77,7 +77,7 @@ public async Task CanCreateAndDeleteKey() -----END PGP PUBLIC KEY BLOCK----- "; // Create a key - var observable = _gitHubClient.User.GpgKeys.Create(new NewGpgKey(publicKey)); + var observable = _gitHubClient.User.GpgKey.Create(new NewGpgKey(publicKey)); var key = await observable; Assert.NotNull(key); @@ -85,10 +85,10 @@ public async Task CanCreateAndDeleteKey() Assert.Equal(knownPublicKey, key.PublicKey); // Delete the key - await _gitHubClient.User.GpgKeys.Delete(key.Id); + await _gitHubClient.User.GpgKey.Delete(key.Id); // Verify key no longer exists - var keys = await _gitHubClient.User.GpgKeys.GetAllForCurrent().ToList(); + var keys = await _gitHubClient.User.GpgKey.GetAllForCurrent().ToList(); Assert.False(keys.Any(k => k.KeyId == knownKeyId && k.PublicKey == knownPublicKey)); } } diff --git a/Octokit.Tests/Clients/UserGpgKeysClientTests.cs b/Octokit.Tests/Clients/UserGpgKeysClientTests.cs index 73fe4df7d6..a634ab9d55 100644 --- a/Octokit.Tests/Clients/UserGpgKeysClientTests.cs +++ b/Octokit.Tests/Clients/UserGpgKeysClientTests.cs @@ -28,13 +28,13 @@ public void RequestsTheCorrectUrl() var connection = Substitute.For(); var client = new UserGpgKeysClient(connection); - var expectedUri = ApiUrls.GpgKeys().ToString(); + var expectedUri = "user/gpg_keys"; client.GetAllForCurrent(); connection.Received().GetAll( Arg.Is(u => u.ToString() == expectedUri), Arg.Any>(), - Arg.Is(s => s == AcceptHeaders.GpgKeysPreview), + Arg.Is(s => s == "application/vnd.github.cryptographer-preview+sha"), Arg.Any()); } } @@ -47,13 +47,13 @@ public void RequestsTheCorrectUrl() var connection = Substitute.For(); var client = new UserGpgKeysClient(connection); - var expectedUri = ApiUrls.GpgKeys(1).ToString(); + var expectedUri = "user/gpg_keys/1"; client.Get(1); connection.Received().Get( Arg.Is(u => u.ToString() == expectedUri), Arg.Any>(), - Arg.Is(s => s == AcceptHeaders.GpgKeysPreview)); + Arg.Is(s => s == "application/vnd.github.cryptographer-preview+sha")); } } @@ -72,13 +72,13 @@ public void RequestsTheCorrectUrl() var connection = Substitute.For(); var client = new UserGpgKeysClient(connection); - var expectedUri = ApiUrls.GpgKeys().ToString(); + var expectedUri = "user/gpg_keys"; client.Create(new NewGpgKey("ABCDEFG")); connection.Received().Post( Arg.Is(u => u.ToString() == expectedUri), Arg.Any(), - Arg.Is(s => s == AcceptHeaders.GpgKeysPreview)); + Arg.Is(s => s == "application/vnd.github.cryptographer-preview+sha")); } [Fact] @@ -87,11 +87,11 @@ public void PassesRequestObject() var connection = Substitute.For(); var client = new UserGpgKeysClient(connection); - var expectedUri = ApiUrls.GpgKeys().ToString(); + var expectedUri = "user/gpg_keys"; client.Create(new NewGpgKey("ABCDEFG")); connection.Received().Post( - Arg.Any(), + Arg.Is(u => u.ToString() == expectedUri), Arg.Is(a => a.ArmoredPublicKey == "ABCDEFG"), Arg.Any()); @@ -106,13 +106,13 @@ public void RequestsTheCorrectUrl() var connection = Substitute.For(); var client = new UserGpgKeysClient(connection); - var expectedUri = ApiUrls.GpgKeys(1).ToString(); + var expectedUri = "user/gpg_keys/1"; client.Delete(1); connection.Received().Delete( Arg.Is(u => u.ToString() == expectedUri), Arg.Any(), - Arg.Is(s => s == AcceptHeaders.GpgKeysPreview)); + Arg.Is(s => s == "application/vnd.github.cryptographer-preview+sha")); } } } diff --git a/Octokit.Tests/Reactive/ObservableUserGpgKeysClientTests.cs b/Octokit.Tests/Reactive/ObservableUserGpgKeysClientTests.cs index ca2cc0b630..2d5f79d2d7 100644 --- a/Octokit.Tests/Reactive/ObservableUserGpgKeysClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableUserGpgKeysClientTests.cs @@ -21,7 +21,7 @@ public void CallsIntoClient() client.GetAllForCurrent(); - githubClient.User.GpgKeys.Received().GetAllForCurrent(Arg.Any()); + githubClient.User.GpgKey.Received().GetAllForCurrent(Arg.Any()); } } @@ -35,7 +35,7 @@ public void CallsIntoClient() client.Get(1); - githubClient.User.GpgKeys.Received().Get(1); + githubClient.User.GpgKey.Received().Get(1); } } @@ -49,7 +49,7 @@ public void CallsIntoClient() client.Create(new NewGpgKey("ABCDEFG")); - githubClient.User.GpgKeys.Received().Create(Arg.Is(k => k.ArmoredPublicKey == "ABCDEFG")); + githubClient.User.GpgKey.Received().Create(Arg.Is(k => k.ArmoredPublicKey == "ABCDEFG")); } } @@ -63,7 +63,7 @@ public void CallsIntoClient() client.Delete(1); - githubClient.User.GpgKeys.Received().Delete(1); + githubClient.User.GpgKey.Received().Delete(1); } } diff --git a/Octokit/Clients/IUsersClient.cs b/Octokit/Clients/IUsersClient.cs index 046441aefd..93c5fc3405 100644 --- a/Octokit/Clients/IUsersClient.cs +++ b/Octokit/Clients/IUsersClient.cs @@ -28,7 +28,7 @@ public interface IUsersClient IUserKeysClient Keys { get; } [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] - IUserGpgKeysClient GpgKeys { get; } + IUserGpgKeysClient GpgKey { get; } /// /// Returns the user specified by the login. diff --git a/Octokit/Clients/UsersClient.cs b/Octokit/Clients/UsersClient.cs index e041615a75..1b98e13b6a 100644 --- a/Octokit/Clients/UsersClient.cs +++ b/Octokit/Clients/UsersClient.cs @@ -22,7 +22,7 @@ public UsersClient(IApiConnection apiConnection) : base(apiConnection) Email = new UserEmailsClient(apiConnection); Followers = new FollowersClient(apiConnection); Keys = new UserKeysClient(apiConnection); - GpgKeys = new UserGpgKeysClient(apiConnection); + GpgKey = new UserGpgKeysClient(apiConnection); Administration = new UserAdministrationClient(apiConnection); } @@ -49,7 +49,7 @@ public UsersClient(IApiConnection apiConnection) : base(apiConnection) /// /// See the User GPG Keys documentation for more information. /// - public IUserGpgKeysClient GpgKeys { get; private set; } + public IUserGpgKeysClient GpgKey { get; private set; } /// /// Returns the user specified by the login. From 9e594a6451a20cab36ffea2bcd7179365b87a1d5 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Tue, 7 Jun 2016 17:23:08 +1000 Subject: [PATCH 09/11] Update access header used for GPG Keys --- Octokit.Tests/Clients/UserGpgKeysClientTests.cs | 8 ++++---- Octokit/Helpers/AcceptHeaders.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Octokit.Tests/Clients/UserGpgKeysClientTests.cs b/Octokit.Tests/Clients/UserGpgKeysClientTests.cs index a634ab9d55..be5e63181b 100644 --- a/Octokit.Tests/Clients/UserGpgKeysClientTests.cs +++ b/Octokit.Tests/Clients/UserGpgKeysClientTests.cs @@ -34,7 +34,7 @@ public void RequestsTheCorrectUrl() connection.Received().GetAll( Arg.Is(u => u.ToString() == expectedUri), Arg.Any>(), - Arg.Is(s => s == "application/vnd.github.cryptographer-preview+sha"), + Arg.Is(s => s == "application/vnd.github.cryptographer-preview"), Arg.Any()); } } @@ -53,7 +53,7 @@ public void RequestsTheCorrectUrl() connection.Received().Get( Arg.Is(u => u.ToString() == expectedUri), Arg.Any>(), - Arg.Is(s => s == "application/vnd.github.cryptographer-preview+sha")); + Arg.Is(s => s == "application/vnd.github.cryptographer-preview")); } } @@ -78,7 +78,7 @@ public void RequestsTheCorrectUrl() connection.Received().Post( Arg.Is(u => u.ToString() == expectedUri), Arg.Any(), - Arg.Is(s => s == "application/vnd.github.cryptographer-preview+sha")); + Arg.Is(s => s == "application/vnd.github.cryptographer-preview")); } [Fact] @@ -112,7 +112,7 @@ public void RequestsTheCorrectUrl() connection.Received().Delete( Arg.Is(u => u.ToString() == expectedUri), Arg.Any(), - Arg.Is(s => s == "application/vnd.github.cryptographer-preview+sha")); + Arg.Is(s => s == "application/vnd.github.cryptographer-preview")); } } } diff --git a/Octokit/Helpers/AcceptHeaders.cs b/Octokit/Helpers/AcceptHeaders.cs index c488404972..95f8179217 100644 --- a/Octokit/Helpers/AcceptHeaders.cs +++ b/Octokit/Helpers/AcceptHeaders.cs @@ -27,6 +27,6 @@ public static class AcceptHeaders public const string OrganizationPermissionsPreview = "application/vnd.github.ironman-preview+json"; [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] - public const string GpgKeysPreview = "application/vnd.github.cryptographer-preview+sha"; + public const string GpgKeysPreview = "application/vnd.github.cryptographer-preview"; } } From 397776579685e6e5b5a06dff3b60df8798987b4d Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Thu, 9 Jun 2016 00:03:07 +1000 Subject: [PATCH 10/11] Tweak GpgKeyContext inline with recent change made to other helper contexts --- Octokit.Tests.Integration/Helper.cs | 16 ++++++++++++++++ .../Helpers/GithubClientExtensions.cs | 2 +- .../Helpers/GpgKeyContext.cs | 12 ++++-------- .../Helpers/ObservableGithubClientExtensions.cs | 2 +- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Octokit.Tests.Integration/Helper.cs b/Octokit.Tests.Integration/Helper.cs index f383d37724..c4479308f7 100644 --- a/Octokit.Tests.Integration/Helper.cs +++ b/Octokit.Tests.Integration/Helper.cs @@ -159,6 +159,22 @@ public static void DeleteKey(IConnection connection, int keyId) catch { } } + public static void DeleteGpgKey(IConnection connection, GpgKey key) + { + if (key != null) + DeleteGpgKey(connection, key.Id); + } + + public static void DeleteGpgKey(IConnection connection, int keyId) + { + try + { + var client = new GitHubClient(connection); + client.User.GpgKey.Delete(keyId).Wait(TimeSpan.FromSeconds(15)); + } + catch { } + } + public static string MakeNameWithTimestamp(string name) { return string.Concat(name, "-", DateTime.UtcNow.ToString("yyyyMMddhhmmssfff")); diff --git a/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs b/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs index 2aa0c72615..f4f2679a9f 100644 --- a/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs +++ b/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs @@ -76,7 +76,7 @@ internal static async Task CreateGpgKeyContext(this IGitHubClient var key = await client.User.GpgKey.Create(new NewGpgKey(publicKey)); - return new GpgKeyContext(key); + return new GpgKeyContext(client.Connection, key); } } } \ No newline at end of file diff --git a/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs b/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs index 4260151adf..bb85369a4f 100644 --- a/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs +++ b/Octokit.Tests.Integration/Helpers/GpgKeyContext.cs @@ -8,15 +8,16 @@ namespace Octokit.Tests.Integration.Helpers { public class GpgKeyContext : IDisposable { - internal GpgKeyContext(GpgKey key) + internal GpgKeyContext(IConnection connection, GpgKey key) { + _connection = connection; Key = key; GpgKeyId = key.Id; KeyId = key.KeyId; PublicKeyData = key.PublicKey; } - + private IConnection _connection; internal int GpgKeyId { get; set; } internal string KeyId { get; set; } internal string PublicKeyData { get; set; } @@ -27,12 +28,7 @@ public void Dispose() { if (Key != null) { - var api = Helper.GetBasicAuthClient(); - try - { - api.User.GpgKey.Delete(Key.Id).Wait(TimeSpan.FromSeconds(15)); - } - catch { } + Helper.DeleteGpgKey(_connection, Key); } } } diff --git a/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs b/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs index 72730612a7..856abdcb72 100644 --- a/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs +++ b/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs @@ -78,7 +78,7 @@ internal static async Task CreateGpgKeyContext(this IObservableGi var key = await client.User.GpgKey.Create(new NewGpgKey(publicKey)); - return new GpgKeyContext(key); + return new GpgKeyContext(client.Connection, key); } } } \ No newline at end of file From 089938b07589f6a77df6c3e5571c7a3456aaf231 Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Thu, 9 Jun 2016 00:03:31 +1000 Subject: [PATCH 11/11] missing await --- .../Reactive/ObservableUserGpgKeysClientTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs index 7934dd6fe2..0d6878c44d 100644 --- a/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs +++ b/Octokit.Tests.Integration/Reactive/ObservableUserGpgKeysClientTests.cs @@ -25,7 +25,7 @@ public ObservableUserGpgKeysClientTests() [IntegrationTest] public async Task CanGetAllForCurrentUser() { - using (var context = _gitHubClient.CreateGpgKeyContext()) + using (var context = await _gitHubClient.CreateGpgKeyContext()) { var observable = _gitHubClient.User.GpgKey.GetAllForCurrent(); var keys = await observable.ToList();