diff --git a/CustomDictionary.xml b/CustomDictionary.xml index cba89b9b..0f5443f0 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 00000000..5509c422 --- /dev/null +++ b/Octokit.Reactive/Clients/IObservableUserAdministrationClient.cs @@ -0,0 +1,42 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reactive; + +namespace Octokit.Reactive +{ + public interface IObservableUserAdministrationClient + { + /// + /// A client for GitHub's User Administration API. + /// + /// + /// See the Administration API documentation for more details. + /// + IObservable Promote(string login); + + /// + /// A client for GitHub's User Administration API. + /// + /// + /// See the Administration API documentation for more details. + /// + IObservable Demote(string login); + + /// + /// A client for GitHub's User Administration API. + /// + /// + /// See the Administration API documentation for more details. + /// + IObservable Suspend(string login); + + /// + /// A client for GitHub's User Administration API. + /// + /// + /// See the Administration API documentation for more details. + /// + IObservable Unsuspend(string login); + + } +} diff --git a/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs b/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs new file mode 100644 index 00000000..4e9762fc --- /dev/null +++ b/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs @@ -0,0 +1,31 @@ +using System; +using System.Reactive; +using System.Reactive.Threading.Tasks; +using Octokit.Reactive.Internal; + +namespace Octokit.Reactive +{ + public class ObservableUserAdministrationClient : IObservableUserAdministrationClient + { + public IObservable Demote(string login) + { + throw new NotImplementedException(); + } + + public IObservable Promote(string login) + { + Ensure.ArgumentNotNullOrEmptyString(login, "login"); + throw new NotImplementedException(); + } + + public IObservable Suspend(string login) + { + throw new NotImplementedException(); + } + + public IObservable Unsuspend(string login) + { + throw new NotImplementedException(); + } + } +} diff --git a/Octokit.Reactive/Octokit.Reactive.csproj b/Octokit.Reactive/Octokit.Reactive.csproj index ad06ce2c..627239e0 100644 --- a/Octokit.Reactive/Octokit.Reactive.csproj +++ b/Octokit.Reactive/Octokit.Reactive.csproj @@ -80,6 +80,7 @@ + @@ -157,6 +158,7 @@ + diff --git a/Octokit.Tests/Clients/UserAdministrationClientTests.cs b/Octokit.Tests/Clients/UserAdministrationClientTests.cs new file mode 100644 index 00000000..340bf802 --- /dev/null +++ b/Octokit.Tests/Clients/UserAdministrationClientTests.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NSubstitute; +using Octokit.Tests.Helpers; +using Xunit; +using Octokit.Clients; + +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")); + } + } + } +} diff --git a/Octokit.Tests/OctoKit.Tests-NetCore45.csproj b/Octokit.Tests/OctoKit.Tests-NetCore45.csproj index c5ccda1c..de80cf70 100644 --- a/Octokit.Tests/OctoKit.Tests-NetCore45.csproj +++ b/Octokit.Tests/OctoKit.Tests-NetCore45.csproj @@ -101,6 +101,7 @@ + diff --git a/Octokit.Tests/Octokit.Tests-Portable.csproj b/Octokit.Tests/Octokit.Tests-Portable.csproj index 8babf25a..d502ffef 100644 --- a/Octokit.Tests/Octokit.Tests-Portable.csproj +++ b/Octokit.Tests/Octokit.Tests-Portable.csproj @@ -110,6 +110,7 @@ + diff --git a/Octokit.Tests/Octokit.Tests.csproj b/Octokit.Tests/Octokit.Tests.csproj index 57055097..72cbb10e 100644 --- a/Octokit.Tests/Octokit.Tests.csproj +++ b/Octokit.Tests/Octokit.Tests.csproj @@ -123,6 +123,7 @@ + @@ -206,6 +207,7 @@ + diff --git a/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs b/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs new file mode 100644 index 00000000..84f6cf29 --- /dev/null +++ b/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.IO; +using NSubstitute; +using Octokit.Reactive; +using Xunit; +using System.Reactive.Linq; + +namespace Octokit.Tests.Reactive +{ + public class ObservableUserAdministrationClientTests + { + public class ThePromoteMethod + { + [Fact] + public void EnsuresArgumentIsNotNull() + { + var client = new ObservableUserAdministrationClient(); + Assert.Throws(() => client.Promote(null)); + } + } + } +} diff --git a/Octokit/Clients/IUserAdministrationClient.cs b/Octokit/Clients/IUserAdministrationClient.cs index 7a598caa..decb1306 100644 --- a/Octokit/Clients/IUserAdministrationClient.cs +++ b/Octokit/Clients/IUserAdministrationClient.cs @@ -11,7 +11,7 @@ namespace Octokit /// /// See the Administration API documentation for more details. /// - interface IUserAdministrationClient + public interface IUserAdministrationClient { /// /// Promotes ordinary user to a site administrator. @@ -22,6 +22,36 @@ namespace Octokit /// 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 1e2cefe5..d08b41c6 100644 --- a/Octokit/Clients/IUsersClient.cs +++ b/Octokit/Clients/IUsersClient.cs @@ -57,5 +57,13 @@ namespace Octokit /// 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 00000000..77113e82 --- /dev/null +++ b/Octokit/Clients/UserAdministrationClient.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Octokit.Clients +{ + public class UserAdministrationClient : ApiClient, IUserAdministrationClient + { + public UserAdministrationClient(IApiConnection apiConnection) + : base(apiConnection) + { + } + + public Task Demote(string login) + { + throw new NotImplementedException(); + } + + public Task Promote(string login) + { + Ensure.ArgumentNotNullOrEmptyString(login, "login"); + var endpoint = ApiUrls.UserAdministration(login); + + return ApiConnection.Put(endpoint); + } + + public Task Suspend(string login) + { + throw new NotImplementedException(); + } + + public Task Unsuspend(string login) + { + throw new NotImplementedException(); + } + } +} diff --git a/Octokit/Clients/UsersClient.cs b/Octokit/Clients/UsersClient.cs index 03429382..7fa162d8 100644 --- a/Octokit/Clients/UsersClient.cs +++ b/Octokit/Clients/UsersClient.cs @@ -82,5 +82,14 @@ namespace Octokit /// 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 a1bc2dca..8e08c4f9 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -1569,5 +1569,11 @@ namespace Octokit { return "repos/{0}/{1}/pages/builds/latest".FormatUri(owner, name); } + + public static Uri UserAdministration(string login) + { + return "/users/{0}/site_admin".FormatUri(login); + + } } } diff --git a/Octokit/Octokit-Mono.csproj b/Octokit/Octokit-Mono.csproj index b76e6323..cbb4ffec 100644 --- a/Octokit/Octokit-Mono.csproj +++ b/Octokit/Octokit-Mono.csproj @@ -74,6 +74,7 @@ + @@ -93,6 +94,7 @@ + diff --git a/Octokit/Octokit-Portable.csproj b/Octokit/Octokit-Portable.csproj index 6860a747..ca254ce6 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 e922b06a..6c927e68 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 c19e5c3f..e042ed96 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -75,6 +75,7 @@ +