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 @@
+