diff --git a/CustomDictionary.xml b/CustomDictionary.xml index cba89b9b3e..0f5443f0dd 100644 --- a/CustomDictionary.xml +++ b/CustomDictionary.xml @@ -23,6 +23,7 @@ Submodule Forkee Tarball + Unsuspend Zipball diff --git a/Octokit.Reactive/Clients/IObservableUserAdministrationClient.cs b/Octokit.Reactive/Clients/IObservableUserAdministrationClient.cs new file mode 100644 index 0000000000..cdd42fee16 --- /dev/null +++ b/Octokit.Reactive/Clients/IObservableUserAdministrationClient.cs @@ -0,0 +1,56 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reactive; + +namespace Octokit.Reactive +{ + /// + /// A client for GitHub's User Administration API. + /// + /// + /// See the Administration API documentation for more details. + /// + public interface IObservableUserAdministrationClient + { + /// + /// Promotes ordinary user to a site administrator. + /// + /// + /// https://developer.github.com/v3/users/administration/#promote-an-ordinary-user-to-a-site-administrator + /// + /// The user to promote to administrator. + /// + IObservable Promote(string login); + + /// + /// Demotes a site administrator to an ordinary user. + /// + /// + /// https://developer.github.com/v3/users/administration/#demote-a-site-administrator-to-an-ordinary-user + /// + /// The user to demote from administrator. + /// + IObservable Demote(string login); + + /// + /// Suspends a user. + /// + /// + /// https://developer.github.com/v3/users/administration/#suspend-a-user + /// + /// The user to suspend. + /// + IObservable Suspend(string login); + + /// + /// Unsuspends a user. + /// + /// + /// https://developer.github.com/v3/users/administration/#unsuspend-a-user + /// + /// The user to unsuspend. + /// + IObservable Unsuspend(string login); + + } +} diff --git a/Octokit.Reactive/Clients/IObservableUsersClient.cs b/Octokit.Reactive/Clients/IObservableUsersClient.cs index 20ab684db6..6672974aea 100644 --- a/Octokit.Reactive/Clients/IObservableUsersClient.cs +++ b/Octokit.Reactive/Clients/IObservableUsersClient.cs @@ -51,5 +51,13 @@ public interface IObservableUsersClient /// See the Keys API documentation for more information. /// IObservableUserKeysClient Keys { get; } + + /// + /// A client for GitHub's User Administration API + /// + /// + /// See the User Administrator API documentation for more information. + /// + IObservableUserAdministrationClient Administration { get; } } } diff --git a/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs b/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs new file mode 100644 index 0000000000..d76d7e9dad --- /dev/null +++ b/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs @@ -0,0 +1,77 @@ +using System; +using System.Reactive; +using System.Reactive.Threading.Tasks; +using Octokit.Reactive.Internal; +using System.Reactive.Linq; + + +namespace Octokit.Reactive +{ + public class ObservableUserAdministrationClient : IObservableUserAdministrationClient + { + readonly IUserAdministrationClient _client; + + /// + /// Initializes a new instance of the class. + /// + /// An used to make the requests + public ObservableUserAdministrationClient(IGitHubClient client) + { + Ensure.ArgumentNotNull(client, "client"); + + _client = client.User.Administration; + } + + /// + /// Promotes ordinary user to a site administrator. + /// + /// + /// https://developer.github.com/v3/users/administration/#promote-an-ordinary-user-to-a-site-administrator + /// + /// The user to promote to administrator. + /// + public IObservable Promote(string login) + { + return _client.Promote(login).ToObservable(); + } + + /// + /// Demotes a site administrator to an ordinary user. + /// + /// + /// https://developer.github.com/v3/users/administration/#demote-a-site-administrator-to-an-ordinary-user + /// + /// The user to demote from administrator. + /// + public IObservable Demote(string login) + { + return _client.Demote(login).ToObservable(); + } + + /// + /// Suspends a user. + /// + /// + /// https://developer.github.com/v3/users/administration/#suspend-a-user + /// + /// The user to suspend. + /// + public IObservable Suspend(string login) + { + return _client.Suspend(login).ToObservable(); + } + + /// + /// Unsuspends a user. + /// + /// + /// https://developer.github.com/v3/users/administration/#unsuspend-a-user + /// + /// The user to unsuspend. + /// + public IObservable Unsuspend(string login) + { + return _client.Unsuspend(login).ToObservable(); + } + } +} diff --git a/Octokit.Reactive/Clients/ObservableUsersClient.cs b/Octokit.Reactive/Clients/ObservableUsersClient.cs index 1d6b9c6e3f..8460153158 100644 --- a/Octokit.Reactive/Clients/ObservableUsersClient.cs +++ b/Octokit.Reactive/Clients/ObservableUsersClient.cs @@ -16,6 +16,8 @@ public ObservableUsersClient(IGitHubClient client) Followers = new ObservableFollowersClient(client); Email = new ObservableUserEmailsClient(client); Keys = new ObservableUserKeysClient(client); + Administration = new ObservableUserAdministrationClient(client); + } /// @@ -75,5 +77,13 @@ public IObservable Update(UserUpdate user) /// See the Keys API documentation for more information. /// public IObservableUserKeysClient Keys { get; private set; } + + /// + /// A client for GitHub's User Administration API + /// + /// + /// See the User Administrator API documentation for more information. + /// + public IObservableUserAdministrationClient Administration { get; private set; } } } diff --git a/Octokit.Reactive/Octokit.Reactive-Mono.csproj b/Octokit.Reactive/Octokit.Reactive-Mono.csproj index 0d93d33ae5..8ca3abddd0 100644 --- a/Octokit.Reactive/Octokit.Reactive-Mono.csproj +++ b/Octokit.Reactive/Octokit.Reactive-Mono.csproj @@ -163,6 +163,8 @@ + + diff --git a/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj b/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj index de9321e9e9..ad9522c1c9 100644 --- a/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj +++ b/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj @@ -171,6 +171,8 @@ + + diff --git a/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj b/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj index 018f37d0c6..21f480080e 100644 --- a/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj +++ b/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj @@ -167,6 +167,8 @@ + + diff --git a/Octokit.Reactive/Octokit.Reactive.csproj b/Octokit.Reactive/Octokit.Reactive.csproj index aee83c4189..618f9d2610 100644 --- a/Octokit.Reactive/Octokit.Reactive.csproj +++ b/Octokit.Reactive/Octokit.Reactive.csproj @@ -84,6 +84,7 @@ + @@ -161,6 +162,7 @@ + diff --git a/Octokit.Tests/Clients/UserAdministrationClientTests.cs b/Octokit.Tests/Clients/UserAdministrationClientTests.cs new file mode 100644 index 0000000000..237e96b4be --- /dev/null +++ b/Octokit.Tests/Clients/UserAdministrationClientTests.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NSubstitute; +using Octokit.Tests.Helpers; +using Xunit; + +namespace Octokit.Tests.Clients +{ + public class UserAdministrationClientTests + { + public class ThePromoteMethod + { + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new UserAdministrationClient(Substitute.For()); + await Assert.ThrowsAsync(() => client.Promote(null)); + } + + [Fact] + public async Task EnsuresNonEmptyString() + { + var client = new UserAdministrationClient(Substitute.For()); + var exception = await Assert.ThrowsAsync(() => client.Promote("")); + Assert.Equal("login", exception.ParamName); + } + + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new UserAdministrationClient(connection); + + client.Promote("auser"); + + connection.Received().Put(Arg.Is(u => u.ToString() == "/users/auser/site_admin")); + } + } + public class TheDemoteMethod + { + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new UserAdministrationClient(Substitute.For()); + await Assert.ThrowsAsync(() => client.Demote(null)); + } + + [Fact] + public async Task EnsuresNonEmptyString() + { + var client = new UserAdministrationClient(Substitute.For()); + var exception = await Assert.ThrowsAsync(() => client.Demote("")); + Assert.Equal("login", exception.ParamName); + } + + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new UserAdministrationClient(connection); + + client.Demote("auser"); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "/users/auser/site_admin")); + } + } + + public class TheSuspendMethod + { + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new UserAdministrationClient(Substitute.For()); + await Assert.ThrowsAsync(() => client.Suspend(null)); + } + + [Fact] + public async Task EnsuresNonEmptyString() + { + var client = new UserAdministrationClient(Substitute.For()); + var exception = await Assert.ThrowsAsync(() => client.Suspend("")); + Assert.Equal("login", exception.ParamName); + } + + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new UserAdministrationClient(connection); + + client.Suspend("auser"); + + connection.Received().Put(Arg.Is(u => u.ToString() == "/users/auser/suspended")); + } + } + + public class TheUnsuspendMethod + { + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new UserAdministrationClient(Substitute.For()); + await Assert.ThrowsAsync(() => client.Unsuspend(null)); + } + + [Fact] + public async Task EnsuresNonEmptyString() + { + var client = new UserAdministrationClient(Substitute.For()); + var exception = await Assert.ThrowsAsync(() => client.Unsuspend("")); + Assert.Equal("login", exception.ParamName); + } + + [Fact] + public void RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new UserAdministrationClient(connection); + + client.Unsuspend("auser"); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "/users/auser/suspended")); + } + } + } +} diff --git a/Octokit.Tests/OctoKit.Tests-NetCore45.csproj b/Octokit.Tests/OctoKit.Tests-NetCore45.csproj index 58da5c6c1b..c6f5566f49 100644 --- a/Octokit.Tests/OctoKit.Tests-NetCore45.csproj +++ b/Octokit.Tests/OctoKit.Tests-NetCore45.csproj @@ -102,6 +102,7 @@ + diff --git a/Octokit.Tests/Octokit.Tests-Portable.csproj b/Octokit.Tests/Octokit.Tests-Portable.csproj index a8bde696d5..e79ed5b755 100644 --- a/Octokit.Tests/Octokit.Tests-Portable.csproj +++ b/Octokit.Tests/Octokit.Tests-Portable.csproj @@ -111,6 +111,7 @@ + diff --git a/Octokit.Tests/Octokit.Tests.csproj b/Octokit.Tests/Octokit.Tests.csproj index 5af192547d..8df0ed6a85 100644 --- a/Octokit.Tests/Octokit.Tests.csproj +++ b/Octokit.Tests/Octokit.Tests.csproj @@ -124,6 +124,7 @@ + @@ -207,6 +208,7 @@ + diff --git a/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs b/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs new file mode 100644 index 0000000000..d605e71843 --- /dev/null +++ b/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs @@ -0,0 +1,75 @@ +using System; +using NSubstitute; +using Octokit.Reactive; +using Xunit; + +namespace Octokit.Tests.Reactive +{ + public class ObservableUserAdministrationClientTests + { + public class ThePromoteMethod + { + [Fact] + public void GetsFromClientPromtePromote() + { + var gitHubClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(gitHubClient); + + client.Promote("auser"); + + gitHubClient.User.Administration.Received().Promote("auser"); + } + } + + public class TheDemoteMethod + { + [Fact] + public void GetsFromClientDemoteDemote() + { + var gitHubClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(gitHubClient); + + client.Demote("auser"); + + gitHubClient.User.Administration.Received().Demote("auser"); + } + } + + public class TheSuspendMethod + { + [Fact] + public void GetsFromClientSuspendSuspend() + { + var gitHubClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(gitHubClient); + + client.Suspend("auser"); + + gitHubClient.User.Administration.Received().Suspend("auser"); + } + } + + public class TheUnsuspendMethod + { + [Fact] + public void GetsFromClientUnsuspendUnsuspend() + { + var gitHubClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(gitHubClient); + + client.Unsuspend("auser"); + + gitHubClient.User.Administration.Received().Unsuspend("auser"); + } + } + + public class TheCtor + { + [Fact] + public void EnsuresArgument() + { + Assert.Throws(() => new ObservableUserAdministrationClient(null)); + } + } + } +} diff --git a/Octokit/Clients/IUserAdministrationClient.cs b/Octokit/Clients/IUserAdministrationClient.cs new file mode 100644 index 0000000000..36d1c8584a --- /dev/null +++ b/Octokit/Clients/IUserAdministrationClient.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Octokit +{ /// + /// A client for GitHub's User Administration API. + /// + /// + /// See the Administration API documentation for more details. + /// + public interface IUserAdministrationClient + { + /// + /// Promotes ordinary user to a site administrator. + /// + /// + /// https://developer.github.com/v3/users/administration/#promote-an-ordinary-user-to-a-site-administrator + /// + /// The user to promote to administrator. + /// + Task Promote(string login); + + /// + /// Demotes a site administrator to an ordinary user. + /// + /// + /// https://developer.github.com/v3/users/administration/#demote-a-site-administrator-to-an-ordinary-user + /// + /// The user to demote from administrator. + /// + Task Demote(string login); + + /// + /// Suspends a user. + /// + /// + /// https://developer.github.com/v3/users/administration/#suspend-a-user + /// + /// The user to suspend. + /// + Task Suspend(string login); + + /// + /// Unsuspends a user. + /// + /// + /// https://developer.github.com/v3/users/administration/#unsuspend-a-user + /// + /// The user to unsuspend. + /// + Task Unsuspend(string login); + + } +} diff --git a/Octokit/Clients/IUsersClient.cs b/Octokit/Clients/IUsersClient.cs index 1e2cefe5c3..d08b41c67c 100644 --- a/Octokit/Clients/IUsersClient.cs +++ b/Octokit/Clients/IUsersClient.cs @@ -57,5 +57,13 @@ public interface IUsersClient /// See the Followers API documentation for more information. /// IFollowersClient Followers { get; } + + /// + /// A client for GitHub's User Administration API + /// + /// + /// See the User Administrator API documentation for more information. + /// + IUserAdministrationClient Administration { get; } } } diff --git a/Octokit/Clients/UserAdministrationClient.cs b/Octokit/Clients/UserAdministrationClient.cs new file mode 100644 index 0000000000..4b8ff4c8c2 --- /dev/null +++ b/Octokit/Clients/UserAdministrationClient.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's User Administration API. + /// + /// + /// See the Administration API documentation for more details. + /// + public class UserAdministrationClient : ApiClient, IUserAdministrationClient + { + /// + /// Initializes a new instance of the class. + /// + /// The client's connection + public UserAdministrationClient(IApiConnection apiConnection) + : base(apiConnection) + { + } + + /// + /// Promotes ordinary user to a site administrator. + /// + /// + /// https://developer.github.com/v3/users/administration/#promote-an-ordinary-user-to-a-site-administrator + /// + /// The user to promote to administrator. + /// + public Task Promote(string login) + { + Ensure.ArgumentNotNullOrEmptyString(login, "login"); + var endpoint = ApiUrls.UserAdministration(login); + return ApiConnection.Put(endpoint); + } + + /// + /// Demotes a site administrator to an ordinary user. + /// + /// + /// https://developer.github.com/v3/users/administration/#demote-a-site-administrator-to-an-ordinary-user + /// + /// The user to demote from administrator. + /// + public Task Demote(string login) + { + Ensure.ArgumentNotNullOrEmptyString(login, "login"); + var endpoint = ApiUrls.UserAdministration(login); + return ApiConnection.Delete(endpoint); + } + + /// + /// Suspends a user. + /// + /// + /// https://developer.github.com/v3/users/administration/#suspend-a-user + /// + /// The user to suspend. + /// + public Task Suspend(string login) + { + Ensure.ArgumentNotNullOrEmptyString(login, "login"); + var endpoint = ApiUrls.UserSuspension(login); + return ApiConnection.Put(endpoint); + } + + /// + /// Unsuspends a user. + /// + /// + /// https://developer.github.com/v3/users/administration/#unsuspend-a-user + /// + /// The user to unsuspend. + /// + public Task Unsuspend(string login) + { + Ensure.ArgumentNotNullOrEmptyString(login, "login"); + var endpoint = ApiUrls.UserSuspension(login); + return ApiConnection.Delete(endpoint); + } + } +} diff --git a/Octokit/Clients/UsersClient.cs b/Octokit/Clients/UsersClient.cs index 03429382d7..6febbc1e74 100644 --- a/Octokit/Clients/UsersClient.cs +++ b/Octokit/Clients/UsersClient.cs @@ -22,6 +22,7 @@ public UsersClient(IApiConnection apiConnection) : base(apiConnection) Email = new UserEmailsClient(apiConnection); Followers = new FollowersClient(apiConnection); Keys = new UserKeysClient(apiConnection); + Administration = new UserAdministrationClient(apiConnection); } /// @@ -82,5 +83,14 @@ public Task Update(UserUpdate user) /// See the Followers API documentation for more information. /// public IFollowersClient Followers { get; private set; } + + /// + /// A client for GitHub's User Administration API + /// + /// + /// See the User Administration API documentation for more information. + /// + public IUserAdministrationClient Administration { get; private set; } + } } diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index efc680b3d7..5d85ba5b15 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -1652,5 +1652,27 @@ public static Uri EnterpriseAdminStatsAll() { return EnterpriseAdminStats("all"); } + + /// + /// Creates the relative for altering administration status of a user. + /// + /// The login for the intended user. + /// + public static Uri UserAdministration(string login) + { + return "/users/{0}/site_admin".FormatUri(login); + + } + + /// + /// Creates the relative for altering suspension status of a user. + /// + /// The login for the intended user. + /// + public static Uri UserSuspension(string login) + { + return "/users/{0}/suspended".FormatUri(login); + + } } } diff --git a/Octokit/Octokit-Mono.csproj b/Octokit/Octokit-Mono.csproj index d46271b2a0..08bf819f80 100644 --- a/Octokit/Octokit-Mono.csproj +++ b/Octokit/Octokit-Mono.csproj @@ -74,6 +74,7 @@ + @@ -93,6 +94,7 @@ + diff --git a/Octokit/Octokit-MonoAndroid.csproj b/Octokit/Octokit-MonoAndroid.csproj index 3897d4ae61..157b5ad22c 100644 --- a/Octokit/Octokit-MonoAndroid.csproj +++ b/Octokit/Octokit-MonoAndroid.csproj @@ -442,6 +442,8 @@ + + \ No newline at end of file diff --git a/Octokit/Octokit-Monotouch.csproj b/Octokit/Octokit-Monotouch.csproj index cd30e2a088..d0926bc589 100644 --- a/Octokit/Octokit-Monotouch.csproj +++ b/Octokit/Octokit-Monotouch.csproj @@ -438,6 +438,8 @@ + + diff --git a/Octokit/Octokit-Portable.csproj b/Octokit/Octokit-Portable.csproj index dd5907bd89..b110b9f94c 100644 --- a/Octokit/Octokit-Portable.csproj +++ b/Octokit/Octokit-Portable.csproj @@ -58,6 +58,7 @@ + @@ -124,6 +125,7 @@ + diff --git a/Octokit/Octokit-netcore45.csproj b/Octokit/Octokit-netcore45.csproj index 9d5fd54614..0b60e716ef 100644 --- a/Octokit/Octokit-netcore45.csproj +++ b/Octokit/Octokit-netcore45.csproj @@ -74,6 +74,7 @@ + @@ -131,6 +132,7 @@ + diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index 549f391f49..253a567f80 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -67,6 +67,7 @@ + @@ -78,6 +79,7 @@ + diff --git a/SolutionInfo.cs b/SolutionInfo.cs index ba2f342f8d..311d444a5d 100644 --- a/SolutionInfo.cs +++ b/SolutionInfo.cs @@ -3,11 +3,11 @@ using System.Runtime.InteropServices; [assembly: AssemblyProductAttribute("Octokit")] -[assembly: AssemblyVersionAttribute("0.17.0")] -[assembly: AssemblyFileVersionAttribute("0.17.0")] +[assembly: AssemblyVersionAttribute("0.18.0")] +[assembly: AssemblyFileVersionAttribute("0.18.0")] [assembly: ComVisibleAttribute(false)] namespace System { internal static class AssemblyVersionInformation { - internal const string Version = "0.17.0"; + internal const string Version = "0.18.0"; } }