From d7472d669965e7f454ca1d790559a762743cb7e0 Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Sun, 13 Dec 2015 21:09:29 +1000 Subject: [PATCH] Add Protect/Unprotect Branch functionality - Create BranchUpdate model - Add ProtectBranch and UnprotectBranch calls to RepositoryClient - Add tests --- .../Clients/RepositoriesClientTests.cs | 88 +++++++++++++++++++ Octokit/Clients/IRepositoriesClient.cs | 19 ++++ Octokit/Clients/RepositoriesClient.cs | 41 +++++++++ Octokit/Models/Request/BranchUpdate.cs | 22 +++++ Octokit/Octokit-Mono.csproj | 1 + Octokit/Octokit-Portable.csproj | 1 + Octokit/Octokit-netcore45.csproj | 3 +- Octokit/Octokit.csproj | 1 + 8 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 Octokit/Models/Request/BranchUpdate.cs diff --git a/Octokit.Tests/Clients/RepositoriesClientTests.cs b/Octokit.Tests/Clients/RepositoriesClientTests.cs index 98a68c5a..65ed8274 100644 --- a/Octokit.Tests/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests/Clients/RepositoriesClientTests.cs @@ -717,5 +717,93 @@ namespace Octokit.Tests.Clients Arg.Any>()); } } + + public class TheProtectBranchMethod + { + [Fact] + public void GetsCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoriesClient(connection); + var update = new BranchUpdate(); + const string previewAcceptsHeader = "application/vnd.github.loki-preview+json"; + + client.ProtectBranch("owner", "repo", "branch", update); + + connection.Received() + .Patch(Arg.Is(u => u.ToString() == "repos/owner/repo/branches/branch"), Arg.Any(), previewAcceptsHeader); + } + + [Fact] + public void EnablesProtection() + { + var connection = Substitute.For(); + var client = new RepositoriesClient(connection); + var update = new BranchUpdate(); + const string previewAcceptsHeader = "application/vnd.github.loki-preview+json"; + + client.ProtectBranch("owner", "repo", "branch", update); + + connection.Received() + .Patch(Arg.Any(), Arg.Is(b => b.Protection.Enabled == true), previewAcceptsHeader); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new RepositoriesClient(Substitute.For()); + var update = new BranchUpdate(); + + await Assert.ThrowsAsync(() => client.ProtectBranch(null, "repo", "branch", update)); + await Assert.ThrowsAsync(() => client.ProtectBranch("owner", null, "branch", update)); + await Assert.ThrowsAsync(() => client.ProtectBranch("owner", "repo", null, update)); + await Assert.ThrowsAsync(() => client.ProtectBranch("owner", "repo", "branch", null)); + await Assert.ThrowsAsync(() => client.ProtectBranch("", "repo", "branch", update)); + await Assert.ThrowsAsync(() => client.ProtectBranch("owner", "", "branch", update)); + await Assert.ThrowsAsync(() => client.ProtectBranch("owner", "repo", "", update)); + } + } + + public class TheUnprotectBranchMethod + { + [Fact] + public void GetsCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoriesClient(connection); + const string previewAcceptsHeader = "application/vnd.github.loki-preview+json"; + + client.UnprotectBranch("owner", "repo", "branch"); + + connection.Received() + .Patch(Arg.Is(u => u.ToString() == "repos/owner/repo/branches/branch"), Arg.Any(), previewAcceptsHeader); + } + + [Fact] + public void DisablesProtection() + { + var connection = Substitute.For(); + var client = new RepositoriesClient(connection); + const string previewAcceptsHeader = "application/vnd.github.loki-preview+json"; + + client.UnprotectBranch("owner", "repo", "branch"); + + connection.Received() + .Patch(Arg.Any(), Arg.Is(b => b.Protection.Enabled == false), previewAcceptsHeader); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new RepositoriesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.UnprotectBranch(null, "repo", "branch")); + await Assert.ThrowsAsync(() => client.UnprotectBranch("owner", null, "branch")); + await Assert.ThrowsAsync(() => client.UnprotectBranch("owner", "repo", null)); + await Assert.ThrowsAsync(() => client.UnprotectBranch("", "repo", "branch")); + await Assert.ThrowsAsync(() => client.UnprotectBranch("owner", "", "branch")); + await Assert.ThrowsAsync(() => client.UnprotectBranch("owner", "repo", "")); + } + } } } diff --git a/Octokit/Clients/IRepositoriesClient.cs b/Octokit/Clients/IRepositoriesClient.cs index c6774cd6..67954bf4 100644 --- a/Octokit/Clients/IRepositoriesClient.cs +++ b/Octokit/Clients/IRepositoriesClient.cs @@ -327,5 +327,24 @@ namespace Octokit /// New values to update the repository with /// The updated Task Edit(string owner, string name, RepositoryUpdate update); + + /// + /// Protects the specified branch with the values given in + /// + /// The owner of the repository + /// The name of the repository + /// The name of the branch + /// + /// The updated + Task ProtectBranch(string owner, string repositoryName, string branchName, BranchUpdate update); + + /// + /// Unprotects the specified branch + /// + /// The owner of the repository + /// The name of the repository + /// The name of the branch + /// The updated + Task UnprotectBranch(string owner, string repositoryName, string branchName); } } diff --git a/Octokit/Clients/RepositoriesClient.cs b/Octokit/Clients/RepositoriesClient.cs index 0ebd979c..46f42730 100644 --- a/Octokit/Clients/RepositoriesClient.cs +++ b/Octokit/Clients/RepositoriesClient.cs @@ -505,5 +505,46 @@ namespace Octokit const string previewAcceptsHeader = "application/vnd.github.loki-preview+json"; return ApiConnection.Get(ApiUrls.RepoBranch(owner, repositoryName, branchName), null, previewAcceptsHeader); } + + /// + /// Protects the specified branch with the values given in + /// + /// The owner of the repository + /// The name of the repository + /// The name of the branch + /// + /// The updated + public Task ProtectBranch(string owner, string repositoryName, string branchName, BranchUpdate update) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(repositoryName, "repositoryName"); + Ensure.ArgumentNotNullOrEmptyString(branchName, "branchName"); + Ensure.ArgumentNotNull(update, "update"); + + update.Protection.Enabled = true; + + const string previewAcceptsHeader = "application/vnd.github.loki-preview+json"; + return ApiConnection.Patch(ApiUrls.RepoBranch(owner, repositoryName, branchName), update, previewAcceptsHeader); + } + + /// + /// Unprotects the specified branch + /// + /// The owner of the repository + /// The name of the repository + /// The name of the branch + /// The updated + public Task UnprotectBranch(string owner, string repositoryName, string branchName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(repositoryName, "repositoryName"); + Ensure.ArgumentNotNullOrEmptyString(branchName, "branchName"); + + var update = new BranchUpdate(); + update.Protection.Enabled = false; + + const string previewAcceptsHeader = "application/vnd.github.loki-preview+json"; + return ApiConnection.Patch(ApiUrls.RepoBranch(owner, repositoryName, branchName), update, previewAcceptsHeader); + } } } diff --git a/Octokit/Models/Request/BranchUpdate.cs b/Octokit/Models/Request/BranchUpdate.cs new file mode 100644 index 00000000..d3b43f18 --- /dev/null +++ b/Octokit/Models/Request/BranchUpdate.cs @@ -0,0 +1,22 @@ +using System.Diagnostics; + +namespace Octokit +{ + /// + /// Specifies the values used to update a . + /// Note: this is a PREVIEW api: https://developer.github.com/changes/2015-11-11-protected-branches-api/ + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class BranchUpdate + { + /// + /// The details + /// + public BranchProtection Protection { get; private set; } + + public BranchUpdate() + { + Protection = new BranchProtection(); + } + } +} diff --git a/Octokit/Octokit-Mono.csproj b/Octokit/Octokit-Mono.csproj index 089d49df..c0baead2 100644 --- a/Octokit/Octokit-Mono.csproj +++ b/Octokit/Octokit-Mono.csproj @@ -98,6 +98,7 @@ + diff --git a/Octokit/Octokit-Portable.csproj b/Octokit/Octokit-Portable.csproj index 9ab4e5e2..07fc6294 100644 --- a/Octokit/Octokit-Portable.csproj +++ b/Octokit/Octokit-Portable.csproj @@ -176,6 +176,7 @@ + diff --git a/Octokit/Octokit-netcore45.csproj b/Octokit/Octokit-netcore45.csproj index 2c45e324..89c5d6b3 100644 --- a/Octokit/Octokit-netcore45.csproj +++ b/Octokit/Octokit-netcore45.csproj @@ -183,6 +183,7 @@ + @@ -430,4 +431,4 @@ --> - + \ No newline at end of file diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index b893dac6..1ac42ce6 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -92,6 +92,7 @@ +