From fd91d72ce3e83b53d3872f74370686bb9ab38550 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Tue, 26 Jan 2016 21:12:11 -0500 Subject: [PATCH 1/6] Getting started on #1030 --- Octokit/Clients/IUserAdministrationClient.cs | 27 ++++++++++++++++++++ Octokit/Octokit.csproj | 1 + 2 files changed, 28 insertions(+) create mode 100644 Octokit/Clients/IUserAdministrationClient.cs diff --git a/Octokit/Clients/IUserAdministrationClient.cs b/Octokit/Clients/IUserAdministrationClient.cs new file mode 100644 index 0000000000..7a598caa87 --- /dev/null +++ b/Octokit/Clients/IUserAdministrationClient.cs @@ -0,0 +1,27 @@ +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. + /// + 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); + + } +} diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index 38e4487511..c19e5c3fd2 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -63,6 +63,7 @@ + From 19f0bf389e175bfededd80caeaf0362f8d0e7529 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Thu, 28 Jan 2016 14:29:08 -0500 Subject: [PATCH 2/6] Added Observable classes and got started on observable tests --- CustomDictionary.xml | 1 + .../IObservableUserAdministrationClient.cs | 42 +++++++++++++++++++ .../ObservableUserAdministrationClient.cs | 31 ++++++++++++++ Octokit.Reactive/Octokit.Reactive.csproj | 2 + .../Clients/UserAdministrationClientTests.cs | 42 +++++++++++++++++++ Octokit.Tests/OctoKit.Tests-NetCore45.csproj | 1 + Octokit.Tests/Octokit.Tests-Portable.csproj | 1 + Octokit.Tests/Octokit.Tests.csproj | 2 + ...ObservableUserAdministrationClientTests.cs | 23 ++++++++++ Octokit/Clients/IUserAdministrationClient.cs | 34 ++++++++++++++- Octokit/Clients/IUsersClient.cs | 8 ++++ Octokit/Clients/UserAdministrationClient.cs | 39 +++++++++++++++++ Octokit/Clients/UsersClient.cs | 9 ++++ Octokit/Helpers/ApiUrls.cs | 6 +++ Octokit/Octokit-Mono.csproj | 2 + Octokit/Octokit-Portable.csproj | 2 + Octokit/Octokit-netcore45.csproj | 2 + Octokit/Octokit.csproj | 1 + 18 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 Octokit.Reactive/Clients/IObservableUserAdministrationClient.cs create mode 100644 Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs create mode 100644 Octokit.Tests/Clients/UserAdministrationClientTests.cs create mode 100644 Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs create mode 100644 Octokit/Clients/UserAdministrationClient.cs 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..5509c4225c --- /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 0000000000..4e9762fcdc --- /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 ad06ce2c5f..627239e070 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 0000000000..340bf80277 --- /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 c5ccda1c8c..de80cf7071 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 8babf25a20..d502ffefde 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 57055097f4..72cbb10ee6 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 0000000000..84f6cf29a8 --- /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 7a598caa87..decb1306ad 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 @@ interface IUserAdministrationClient /// 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..77113e8289 --- /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 03429382d7..7fa162d8e4 100644 --- a/Octokit/Clients/UsersClient.cs +++ b/Octokit/Clients/UsersClient.cs @@ -82,5 +82,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 a1bc2dcab7..8e08c4f960 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -1569,5 +1569,11 @@ public static Uri RepositoryPageBuildsLatest(string owner, string name) { 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 b76e632319..cbb4ffecf9 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 6860a747e9..ca254ce6ab 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 e922b06a0a..6c927e68ea 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 c19e5c3fd2..e042ed96de 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -75,6 +75,7 @@ + From e93aa31351e73638d8946c619438b97a6d090299 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Thu, 28 Jan 2016 14:44:33 -0500 Subject: [PATCH 3/6] Fixprojects script update --- Octokit.Reactive/Octokit.Reactive-Mono.csproj | 2 ++ Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj | 2 ++ Octokit.Reactive/Octokit.Reactive-Monotouch.csproj | 2 ++ Octokit/Octokit-MonoAndroid.csproj | 2 ++ Octokit/Octokit-Monotouch.csproj | 2 ++ SolutionInfo.cs | 6 +++--- 6 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Octokit.Reactive/Octokit.Reactive-Mono.csproj b/Octokit.Reactive/Octokit.Reactive-Mono.csproj index 194345c7f3..e01788fedf 100644 --- a/Octokit.Reactive/Octokit.Reactive-Mono.csproj +++ b/Octokit.Reactive/Octokit.Reactive-Mono.csproj @@ -159,6 +159,8 @@ + + diff --git a/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj b/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj index 1f676b026f..6ce5c1198b 100644 --- a/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj +++ b/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj @@ -167,6 +167,8 @@ + + diff --git a/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj b/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj index 9fb92e213c..89f02df2ff 100644 --- a/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj +++ b/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj @@ -163,6 +163,8 @@ + + diff --git a/Octokit/Octokit-MonoAndroid.csproj b/Octokit/Octokit-MonoAndroid.csproj index 45e80dc009..e53cbe8ef6 100644 --- a/Octokit/Octokit-MonoAndroid.csproj +++ b/Octokit/Octokit-MonoAndroid.csproj @@ -427,6 +427,8 @@ + + \ No newline at end of file diff --git a/Octokit/Octokit-Monotouch.csproj b/Octokit/Octokit-Monotouch.csproj index e66291bf67..65a810a752 100644 --- a/Octokit/Octokit-Monotouch.csproj +++ b/Octokit/Octokit-Monotouch.csproj @@ -423,6 +423,8 @@ + + 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"; } } From 9e2eda5ceeb936b0d8c7bfad5cae4ec38aeb0628 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Thu, 28 Jan 2016 19:29:30 -0500 Subject: [PATCH 4/6] Implemented the rest of the User Administration Client and tests, including observable classes. --- .../IObservableUserAdministrationClient.cs | 30 +++++-- .../ObservableUserAdministrationClient.cs | 56 ++++++++++-- .../Clients/UserAdministrationClientTests.cs | 87 ++++++++++++++++++- ...ObservableUserAdministrationClientTests.cs | 55 ++++++++++-- Octokit/Clients/IUserAdministrationClient.cs | 2 +- Octokit/Clients/UserAdministrationClient.cs | 63 ++++++++++++-- Octokit/Clients/UsersClient.cs | 1 + Octokit/Helpers/ApiUrls.cs | 16 ++++ 8 files changed, 280 insertions(+), 30 deletions(-) diff --git a/Octokit.Reactive/Clients/IObservableUserAdministrationClient.cs b/Octokit.Reactive/Clients/IObservableUserAdministrationClient.cs index 5509c4225c..cdd42fee16 100644 --- a/Octokit.Reactive/Clients/IObservableUserAdministrationClient.cs +++ b/Octokit.Reactive/Clients/IObservableUserAdministrationClient.cs @@ -4,38 +4,52 @@ namespace Octokit.Reactive { + /// + /// A client for GitHub's User Administration API. + /// + /// + /// See the Administration API documentation for more details. + /// public interface IObservableUserAdministrationClient { /// - /// A client for GitHub's User Administration API. + /// Promotes ordinary user to a site administrator. /// /// - /// See the Administration API documentation for more details. + /// 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); /// - /// A client for GitHub's User Administration API. + /// Demotes a site administrator to an ordinary user. /// /// - /// See the Administration API documentation for more details. + /// 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); /// - /// A client for GitHub's User Administration API. + /// Suspends a user. /// /// - /// See the Administration API documentation for more details. + /// https://developer.github.com/v3/users/administration/#suspend-a-user /// + /// The user to suspend. + /// IObservable Suspend(string login); /// - /// A client for GitHub's User Administration API. + /// Unsuspends a user. /// /// - /// See the Administration API documentation for more details. + /// https://developer.github.com/v3/users/administration/#unsuspend-a-user /// + /// The user to unsuspend. + /// IObservable Unsuspend(string login); } diff --git a/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs b/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs index 4e9762fcdc..126517ee6c 100644 --- a/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs +++ b/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs @@ -2,30 +2,74 @@ using System.Reactive; using System.Reactive.Threading.Tasks; using Octokit.Reactive.Internal; +using System.Reactive.Linq; + namespace Octokit.Reactive { public class ObservableUserAdministrationClient : IObservableUserAdministrationClient { - public IObservable Demote(string login) + readonly IUserAdministrationClient _client; + + /// + /// Initializes a new instance of the class. + /// + /// An used to make the requests + public ObservableUserAdministrationClient(IUserAdministrationClient userAdministrationClient) { - throw new NotImplementedException(); + _client = userAdministrationClient; } + /// + /// 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) { - Ensure.ArgumentNotNullOrEmptyString(login, "login"); - throw new NotImplementedException(); + 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) { - throw new NotImplementedException(); + 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) { - throw new NotImplementedException(); + return _client.Unsuspend(login).ToObservable(); } } } diff --git a/Octokit.Tests/Clients/UserAdministrationClientTests.cs b/Octokit.Tests/Clients/UserAdministrationClientTests.cs index 340bf80277..237e96b4be 100644 --- a/Octokit.Tests/Clients/UserAdministrationClientTests.cs +++ b/Octokit.Tests/Clients/UserAdministrationClientTests.cs @@ -4,7 +4,6 @@ using NSubstitute; using Octokit.Tests.Helpers; using Xunit; -using Octokit.Clients; namespace Octokit.Tests.Clients { @@ -38,5 +37,91 @@ public void RequestsTheCorrectUrl() 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/Reactive/ObservableUserAdministrationClientTests.cs b/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs index 84f6cf29a8..8fd2845ee4 100644 --- a/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs @@ -1,10 +1,7 @@ using System; -using System.Collections.Generic; -using System.IO; using NSubstitute; using Octokit.Reactive; using Xunit; -using System.Reactive.Linq; namespace Octokit.Tests.Reactive { @@ -13,10 +10,56 @@ public class ObservableUserAdministrationClientTests public class ThePromoteMethod { [Fact] - public void EnsuresArgumentIsNotNull() + public void GetsFromClientPromtePromote() { - var client = new ObservableUserAdministrationClient(); - Assert.Throws(() => client.Promote(null)); + var administrationClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(administrationClient); + + client.Promote("auser"); + + administrationClient.Received().Promote("auser"); + } + } + + public class TheDemoteMethod + { + [Fact] + public void GetsFromClientDemoteDemote() + { + var administrationClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(administrationClient); + + client.Demote("auser"); + + administrationClient.Received().Demote("auser"); + } + } + + public class TheSuspendMethod + { + [Fact] + public void GetsFromClientSuspendSuspend() + { + var administrationClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(administrationClient); + + client.Suspend("auser"); + + administrationClient.Received().Suspend("auser"); + } + } + + public class TheUnsuspendMethod + { + [Fact] + public void GetsFromClientUnsuspendUnsuspend() + { + var administrationClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(administrationClient); + + client.Unsuspend("auser"); + + administrationClient.Received().Unsuspend("auser"); } } } diff --git a/Octokit/Clients/IUserAdministrationClient.cs b/Octokit/Clients/IUserAdministrationClient.cs index decb1306ad..36d1c8584a 100644 --- a/Octokit/Clients/IUserAdministrationClient.cs +++ b/Octokit/Clients/IUserAdministrationClient.cs @@ -44,7 +44,7 @@ public interface IUserAdministrationClient Task Suspend(string login); /// - /// Unsuspends a user + /// Unsuspends a user. /// /// /// https://developer.github.com/v3/users/administration/#unsuspend-a-user diff --git a/Octokit/Clients/UserAdministrationClient.cs b/Octokit/Clients/UserAdministrationClient.cs index 77113e8289..4b8ff4c8c2 100644 --- a/Octokit/Clients/UserAdministrationClient.cs +++ b/Octokit/Clients/UserAdministrationClient.cs @@ -4,36 +4,83 @@ using System.Text; using System.Threading.Tasks; -namespace Octokit.Clients +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) { } - public Task Demote(string login) + /// + /// 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) { - throw new NotImplementedException(); + Ensure.ArgumentNotNullOrEmptyString(login, "login"); + var endpoint = ApiUrls.UserAdministration(login); + return ApiConnection.Put(endpoint); } - public 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. + /// + public Task Demote(string login) { Ensure.ArgumentNotNullOrEmptyString(login, "login"); var endpoint = ApiUrls.UserAdministration(login); - - return ApiConnection.Put(endpoint); + 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) { - throw new NotImplementedException(); + 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) { - throw new NotImplementedException(); + 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 7fa162d8e4..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); } /// diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index 8e08c4f960..f36a62df2d 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -1570,10 +1570,26 @@ public static Uri RepositoryPageBuildsLatest(string owner, string name) return "repos/{0}/{1}/pages/builds/latest".FormatUri(owner, name); } + /// + /// 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); + + } } } From 2a92a4eea7f659246e4a78f6f2dbd257aca0c6e0 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Thu, 28 Jan 2016 19:56:58 -0500 Subject: [PATCH 5/6] Fix to failed build Fixed incorrect comment param tag. --- Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs b/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs index 126517ee6c..4e2acab284 100644 --- a/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs +++ b/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs @@ -14,7 +14,7 @@ public class ObservableUserAdministrationClient : IObservableUserAdministrationC /// /// Initializes a new instance of the class. /// - /// An used to make the requests + /// An used to make the requests public ObservableUserAdministrationClient(IUserAdministrationClient userAdministrationClient) { _client = userAdministrationClient; From 5ad6313738943487ad326c6c7f04c0f79009b69c Mon Sep 17 00:00:00 2001 From: Jasmine Date: Mon, 1 Feb 2016 15:35:18 -0500 Subject: [PATCH 6/6] Fixes for failing convention tests --- .../Clients/IObservableUsersClient.cs | 8 +++++ .../ObservableUserAdministrationClient.cs | 8 +++-- .../Clients/ObservableUsersClient.cs | 10 ++++++ ...ObservableUserAdministrationClientTests.cs | 33 ++++++++++++------- 4 files changed, 44 insertions(+), 15 deletions(-) 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 index 4e2acab284..d76d7e9dad 100644 --- a/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs +++ b/Octokit.Reactive/Clients/ObservableUserAdministrationClient.cs @@ -14,10 +14,12 @@ public class ObservableUserAdministrationClient : IObservableUserAdministrationC /// /// Initializes a new instance of the class. /// - /// An used to make the requests - public ObservableUserAdministrationClient(IUserAdministrationClient userAdministrationClient) + /// An used to make the requests + public ObservableUserAdministrationClient(IGitHubClient client) { - _client = userAdministrationClient; + Ensure.ArgumentNotNull(client, "client"); + + _client = client.User.Administration; } /// 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.Tests/Reactive/ObservableUserAdministrationClientTests.cs b/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs index 8fd2845ee4..d605e71843 100644 --- a/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableUserAdministrationClientTests.cs @@ -12,12 +12,12 @@ public class ThePromoteMethod [Fact] public void GetsFromClientPromtePromote() { - var administrationClient = Substitute.For(); - var client = new ObservableUserAdministrationClient(administrationClient); + var gitHubClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(gitHubClient); client.Promote("auser"); - administrationClient.Received().Promote("auser"); + gitHubClient.User.Administration.Received().Promote("auser"); } } @@ -26,12 +26,12 @@ public class TheDemoteMethod [Fact] public void GetsFromClientDemoteDemote() { - var administrationClient = Substitute.For(); - var client = new ObservableUserAdministrationClient(administrationClient); + var gitHubClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(gitHubClient); client.Demote("auser"); - administrationClient.Received().Demote("auser"); + gitHubClient.User.Administration.Received().Demote("auser"); } } @@ -40,12 +40,12 @@ public class TheSuspendMethod [Fact] public void GetsFromClientSuspendSuspend() { - var administrationClient = Substitute.For(); - var client = new ObservableUserAdministrationClient(administrationClient); + var gitHubClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(gitHubClient); client.Suspend("auser"); - administrationClient.Received().Suspend("auser"); + gitHubClient.User.Administration.Received().Suspend("auser"); } } @@ -54,12 +54,21 @@ public class TheUnsuspendMethod [Fact] public void GetsFromClientUnsuspendUnsuspend() { - var administrationClient = Substitute.For(); - var client = new ObservableUserAdministrationClient(administrationClient); + var gitHubClient = Substitute.For(); + var client = new ObservableUserAdministrationClient(gitHubClient); client.Unsuspend("auser"); - administrationClient.Received().Unsuspend("auser"); + gitHubClient.User.Administration.Received().Unsuspend("auser"); + } + } + + public class TheCtor + { + [Fact] + public void EnsuresArgument() + { + Assert.Throws(() => new ObservableUserAdministrationClient(null)); } } }