Skip to content

Commit

Permalink
Merge pull request #1112 from TattsGroup/userkeys-client
Browse files Browse the repository at this point in the history
Complete UserKeysClient implementation and deprecate SshKeysClient
  • Loading branch information
ryangribble committed Mar 1, 2016
2 parents 84539f7 + 78e7b49 commit 9e9de4b
Show file tree
Hide file tree
Showing 30 changed files with 714 additions and 52 deletions.
6 changes: 6 additions & 0 deletions Octokit.Reactive/Clients/IObservableSshKeysClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ public interface IObservableSshKeysClient
/// <param name="id">The ID of the SSH key</param>
/// <returns>A <see cref="SshKey"/></returns>
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")]
[Obsolete("This method is obsolete. Please use User.Keys.Get(int) instead.")]
IObservable<SshKey> Get(int id);

/// <summary>
/// Retrieves the <see cref="SshKey"/> for the specified id.
/// </summary>
/// <param name="user">The login of the user</param>
/// <returns>A <see cref="IReadOnlyPagedCollection{SshKey}"/> of <see cref="SshKey"/>.</returns>
[Obsolete("This method is obsolete. Please use User.Keys.GetAll(string) instead.")]
IObservable<SshKey> GetAll(string user);

/// <summary>
Expand All @@ -28,6 +30,7 @@ public interface IObservableSshKeysClient
/// <returns>A <see cref="IReadOnlyPagedCollection{SshKey}"/> of <see cref="SshKey"/>.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
Justification = "Makes a network request")]
[Obsolete("This method is obsolete. Please use User.Keys.GetAll() instead.")]
IObservable<SshKey> GetAllForCurrent();

/// <summary>
Expand All @@ -36,6 +39,7 @@ public interface IObservableSshKeysClient
/// <param name="key">The SSH Key contents</param>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="User"/></returns>
[Obsolete("This method is obsolete. Please use User.Keys.Create(NewPublicKey) instead.")]
IObservable<SshKey> Create(SshKeyUpdate key);

/// <summary>
Expand All @@ -45,6 +49,7 @@ public interface IObservableSshKeysClient
/// <param name="key">The SSH Key contents</param>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="User"/></returns>
[Obsolete("This method is no longer supported in the GitHub API. Delete and Create the key again instead.")]
IObservable<SshKey> Update(int id, SshKeyUpdate key);

/// <summary>
Expand All @@ -53,6 +58,7 @@ public interface IObservableSshKeysClient
/// <param name="id">The id of the SSH key</param>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="User"/></returns>
[Obsolete("This method is obsolete. Please use User.Keys.Delete(int) instead.")]
IObservable<Unit> Delete(int id);
}
}
37 changes: 35 additions & 2 deletions Octokit.Reactive/Clients/IObservableUserKeysClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive;

namespace Octokit.Reactive
{
Expand All @@ -16,7 +18,7 @@ public interface IObservableUserKeysClient
/// <remarks>
/// https://developer.github.com/v3/users/keys/#list-your-public-keys
/// </remarks>
/// <returns>The <see cref="PublicKey"/>s for the authenticated user.</returns>
/// <returns></returns>
IObservable<PublicKey> GetAll();

/// <summary>
Expand All @@ -25,7 +27,38 @@ public interface IObservableUserKeysClient
/// <remarks>
/// https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user
/// </remarks>
/// <returns>The <see cref="PublicKey"/>s for the user.</returns>
/// <returns></returns>
IObservable<PublicKey> GetAll(string userName);

/// <summary>
/// Retrieves the <see cref="PublicKey"/> for the specified id.
/// </summary>
/// <remarks>
/// https://developer.github.com/v3/users/keys/#get-a-single-public-key
/// </remarks>
/// <param name="id">The ID of the SSH key</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")]
IObservable<PublicKey> Get(int id);

/// <summary>
/// Create a public key <see cref="NewPublicKey"/>.
/// </summary>
/// <remarks>
/// https://developer.github.com/v3/users/keys/#create-a-public-key
/// </remarks>
/// <param name="newKey">The SSH Key contents</param>
/// <returns></returns>
IObservable<PublicKey> Create(NewPublicKey newKey);

/// <summary>
/// Delete a public key.
/// </summary>
/// <remarks>
/// https://developer.github.com/v3/users/keys/#delete-a-public-key
/// </remarks>
/// <param name="id">The id of the key to delete</param>
/// <returns></returns>
IObservable<Unit> Delete(int id);
}
}
6 changes: 6 additions & 0 deletions Octokit.Reactive/Clients/ObservableSshKeysClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public ObservableSshKeysClient(IGitHubClient client)
/// </summary>
/// <param name="id">The ID of the SSH key</param>
/// <returns>A <see cref="SshKey"/></returns>
[Obsolete("This method is obsolete. Please use User.Keys.Get(int) instead.")]
public IObservable<SshKey> Get(int id)
{
return _client.Get(id).ToObservable();
Expand All @@ -37,6 +38,7 @@ public IObservable<SshKey> Get(int id)
/// </summary>
/// <param name="user">The login of the user</param>
/// <returns>A <see cref="IReadOnlyPagedCollection{SshKey}"/> of <see cref="SshKey"/>.</returns>
[Obsolete("This method is obsolete. Please use User.Keys.GetAll(string) instead.")]
public IObservable<SshKey> GetAll(string user)
{
Ensure.ArgumentNotNullOrEmptyString(user, "user");
Expand All @@ -49,6 +51,7 @@ public IObservable<SshKey> GetAll(string user)
/// </summary>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="IReadOnlyPagedCollection{SshKey}"/> of <see cref="SshKey"/>.</returns>
[Obsolete("This method is obsolete. Please use User.Keys.GetAll() instead.")]
public IObservable<SshKey> GetAllForCurrent()
{
return _connection.GetAndFlattenAllPages<SshKey>(ApiUrls.SshKeys());
Expand All @@ -60,6 +63,7 @@ public IObservable<SshKey> GetAllForCurrent()
/// <param name="key">The SSH Key contents</param>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="User"/></returns>
[Obsolete("This method is obsolete. Please use User.Keys.Create(NewPublicKey) instead.")]
public IObservable<SshKey> Create(SshKeyUpdate key)
{
Ensure.ArgumentNotNull(key, "key");
Expand All @@ -74,6 +78,7 @@ public IObservable<SshKey> Create(SshKeyUpdate key)
/// <param name="key">The SSH Key contents</param>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="User"/></returns>
[Obsolete("This method is no longer supported in the GitHub API. Delete and Create the key again instead.")]
public IObservable<SshKey> Update(int id, SshKeyUpdate key)
{
Ensure.ArgumentNotNull(key, "key");
Expand All @@ -87,6 +92,7 @@ public IObservable<SshKey> Update(int id, SshKeyUpdate key)
/// <param name="id">The id of the SSH key</param>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="User"/></returns>
[Obsolete("This method is obsolete. Please use User.Keys.Delete(int) instead.")]
public IObservable<Unit> Delete(int id)
{
return _client.Delete(id).ToObservable();
Expand Down
46 changes: 44 additions & 2 deletions Octokit.Reactive/Clients/ObservableUserKeysClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;

Expand Down Expand Up @@ -27,7 +28,7 @@ public ObservableUserKeysClient(IGitHubClient client)
/// <remarks>
/// https://developer.github.com/v3/users/keys/#list-your-public-keys
/// </remarks>
/// <returns>The <see cref="PublicKey"/>s for the authenticated user.</returns>
/// <returns></returns>
public IObservable<PublicKey> GetAll()
{
return _client.GetAll().ToObservable().SelectMany(k => k);
Expand All @@ -39,10 +40,51 @@ public IObservable<PublicKey> GetAll()
/// <remarks>
/// https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user
/// </remarks>
/// <returns>The <see cref="PublicKey"/>s for the user.</returns>
/// <returns></returns>
public IObservable<PublicKey> GetAll(string userName)
{
return _client.GetAll(userName).ToObservable().SelectMany(k => k);
}

/// <summary>
/// Retrieves the <see cref="PublicKey"/> for the specified id.
/// </summary>
/// <remarks>
/// https://developer.github.com/v3/users/keys/#get-a-single-public-key
/// </remarks>
/// <param name="id">The ID of the SSH key</param>
/// <returns></returns>
public IObservable<PublicKey> Get(int id)
{
return _client.Get(id).ToObservable();
}

/// <summary>
/// Create a public key <see cref="NewPublicKey"/>.
/// </summary>
/// <remarks>
/// https://developer.github.com/v3/users/keys/#create-a-public-key
/// </remarks>
/// <param name="newKey">The SSH Key contents</param>
/// <returns></returns>
public IObservable<PublicKey> Create(NewPublicKey newKey)
{
Ensure.ArgumentNotNull(newKey, "newKey");

return _client.Create(newKey).ToObservable();
}

/// <summary>
/// Delete a public key.
/// </summary>
/// <remarks>
/// https://developer.github.com/v3/users/keys/#delete-a-public-key
/// </remarks>
/// <param name="id">The id of the key to delete</param>
/// <returns></returns>
public IObservable<Unit> Delete(int id)
{
return _client.Delete(id).ToObservable();
}
}
}
63 changes: 52 additions & 11 deletions Octokit.Tests.Integration/Clients/UserKeysClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
using System.Threading.Tasks;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Octokit.Tests.Integration.Helpers;

namespace Octokit.Tests.Integration.Clients
{
public class UserKeysClientTests
{
[IntegrationTest(Skip = "see https://github.com/octokit/octokit.net/issues/533 for the resolution to this failing test")]
public async Task GetAll()
[IntegrationTest]
public async Task CanGetAllForCurrentUser()
{
var github = Helper.GetAuthenticatedClient();

var keys = await github.User.Keys.GetAll();
Assert.NotEmpty(keys);
using (var context = await github.CreatePublicKeyContext())
{
var keys = await github.User.Keys.GetAll();
Assert.NotEmpty(keys);

var first = keys[0];
Assert.NotNull(first.Id);
Assert.NotNull(first.Key);
Assert.NotNull(first.Title);
Assert.NotNull(first.Url);
var first = keys[0];
Assert.NotNull(first.Id);
Assert.NotNull(first.Key);
Assert.NotNull(first.Title);
Assert.NotNull(first.Url);
}
}

[IntegrationTest]
public async Task GetAllForGivenUser()
public async Task CanGetAllForGivenUser()
{
var github = Helper.GetAuthenticatedClient();

Expand All @@ -34,5 +39,41 @@ public async Task GetAllForGivenUser()
Assert.Null(first.Title);
Assert.Null(first.Url);
}

[IntegrationTest]
public async Task CanGetKeyById()
{
var github = Helper.GetAuthenticatedClient();

using (var context = await github.CreatePublicKeyContext())
{
var key = await github.User.Keys.Get(context.KeyId);

Assert.Equal(key.Title, context.KeyTitle);
Assert.Equal(key.Key, context.KeyData);
}
}

[IntegrationTest]
public async Task CanCreateAndDeleteKey()
{
// Create a key
string keyTitle = "title";
string keyData = "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAjo4DqFKg8dOxiz/yjypmN1A4itU5QOStyYrfOFuTinesU/2zm9hqxJ5BctIhgtSHJ5foxkhsiBji0qrUg73Q25BThgNg8YFE8njr4EwjmqSqW13akx/zLV0GFFU0SdJ2F6rBldhi93lMnl0ex9swBqa3eLTY8C+HQGBI6MQUMw+BKp0oFkz87Kv+Pfp6lt/Uo32ejSxML1PT5hTH5n+fyl0ied+sRmPGZWmWoHB5Bc9mox7lB6I6A/ZgjtBqbEEn4HQ2/6vp4ojKfSgA4Mm7XMu0bZzX0itKjH1QWD9Lr5apV1cmZsj49Xf8SHucTtH+bq98hb8OOXEGFzplwsX2MQ==";
var github = Helper.GetAuthenticatedClient();

var key = await github.User.Keys.Create(new NewPublicKey(keyTitle, keyData));

Assert.NotNull(key);
Assert.Equal(key.Title, "title");
Assert.Equal(key.Key, keyData);

// Delete key
await github.User.Keys.Delete(key.Id);

// Verify key no longer exists
var keys = await github.User.Keys.GetAll();
Assert.False(keys.Any(k => k.Title == keyTitle && k.Key == keyData));
}
}
}
16 changes: 16 additions & 0 deletions Octokit.Tests.Integration/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,22 @@ public static void DeleteRepo(string owner, string name)
catch { }
}

public static void DeleteKey(PublicKey key)
{
if (key != null)
DeleteKey(key.Id);
}

public static void DeleteKey(int keyId)
{
var api = GetAuthenticatedClient();
try
{
api.User.Keys.Delete(keyId).Wait(TimeSpan.FromSeconds(15));
}
catch { }
}

public static string MakeNameWithTimestamp(string name)
{
return string.Concat(name, "-", DateTime.UtcNow.ToString("yyyyMMddhhmmssfff"));
Expand Down
11 changes: 11 additions & 0 deletions Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,16 @@ internal async static Task<EnterpriseUserContext> CreateEnterpriseUserContext(th

return new EnterpriseUserContext(user);
}

internal async static Task<PublicKeyContext> CreatePublicKeyContext(this IGitHubClient client)
{
// Create a key
string keyTitle = "title";
string keyData = "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAjo4DqFKg8dOxiz/yjypmN1A4itU5QOStyYrfOFuTinesU/2zm9hqxJ5BctIhgtSHJ5foxkhsiBji0qrUg73Q25BThgNg8YFE8njr4EwjmqSqW13akx/zLV0GFFU0SdJ2F6rBldhi93lMnl0ex9swBqa3eLTY8C+HQGBI6MQUMw+BKp0oFkz87Kv+Pfp6lt/Uo32ejSxML1PT5hTH5n+fyl0ied+sRmPGZWmWoHB5Bc9mox7lB6I6A/ZgjtBqbEEn4HQ2/6vp4ojKfSgA4Mm7XMu0bZzX0itKjH1QWD9Lr5apV1cmZsj49Xf8SHucTtH+bq98hb8OOXEGFzplwsX2MQ==";

var key = await client.User.Keys.Create(new NewPublicKey(keyTitle, keyData));

return new PublicKeyContext(key);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,16 @@ internal async static Task<EnterpriseUserContext> CreateEnterpriseUserContext(th

return new EnterpriseUserContext(user);
}

internal async static Task<PublicKeyContext> CreatePublicKeyContext(this IObservableGitHubClient client)
{
// Create a key
string keyTitle = "title";
string keyData = "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAjo4DqFKg8dOxiz/yjypmN1A4itU5QOStyYrfOFuTinesU/2zm9hqxJ5BctIhgtSHJ5foxkhsiBji0qrUg73Q25BThgNg8YFE8njr4EwjmqSqW13akx/zLV0GFFU0SdJ2F6rBldhi93lMnl0ex9swBqa3eLTY8C+HQGBI6MQUMw+BKp0oFkz87Kv+Pfp6lt/Uo32ejSxML1PT5hTH5n+fyl0ied+sRmPGZWmWoHB5Bc9mox7lB6I6A/ZgjtBqbEEn4HQ2/6vp4ojKfSgA4Mm7XMu0bZzX0itKjH1QWD9Lr5apV1cmZsj49Xf8SHucTtH+bq98hb8OOXEGFzplwsX2MQ==";

var key = await client.User.Keys.Create(new NewPublicKey(keyTitle, keyData));

return new PublicKeyContext(key);
}
}
}
30 changes: 30 additions & 0 deletions Octokit.Tests.Integration/Helpers/PublicKeyContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Octokit.Tests.Integration.Helpers
{
internal sealed class PublicKeyContext : IDisposable
{
internal PublicKeyContext(PublicKey key)
{
Key = key;
KeyId = key.Id;
KeyTitle = key.Title;
KeyData = key.Key;
}

internal int KeyId { get; private set; }
internal string KeyTitle { get; private set; }
internal string KeyData { get; private set; }

internal PublicKey Key { get; private set; }

public void Dispose()
{
Helper.DeleteKey(Key);
}
}
}
Loading

0 comments on commit 9e9de4b

Please sign in to comment.