From 3c5e39cc25b7afcb4dfb8b1dde86a379c5b46d30 Mon Sep 17 00:00:00 2001 From: pmacnaughton Date: Fri, 10 Jan 2014 15:28:37 -0700 Subject: [PATCH] Implemented DeploymentStatusesClient and unit tests --- .../Clients/DeploymentStatusClientTests.cs | 149 ++++++++++++++++++ Octokit.Tests/Octokit.Tests.csproj | 1 + Octokit/Clients/DeploymentStatusClient.cs | 35 ++++ Octokit/Clients/DeploymentsClient.cs | 3 + Octokit/Clients/IDeploymentStatusClient.cs | 12 ++ Octokit/Clients/IDeploymentsClient.cs | 1 + Octokit/Helpers/ApiUrls.cs | 5 + Octokit/Models/Request/NewDeploymentStatus.cs | 11 ++ Octokit/Models/Response/DeploymentStatus.cs | 33 ++++ Octokit/Octokit-Mono.csproj | 4 + Octokit/Octokit-MonoAndroid.csproj | 4 + Octokit/Octokit-Monotouch.csproj | 4 + Octokit/Octokit-netcore45.csproj | 4 + Octokit/Octokit.csproj | 4 + 14 files changed, 270 insertions(+) create mode 100644 Octokit.Tests/Clients/DeploymentStatusClientTests.cs create mode 100644 Octokit/Clients/DeploymentStatusClient.cs create mode 100644 Octokit/Clients/IDeploymentStatusClient.cs create mode 100644 Octokit/Models/Request/NewDeploymentStatus.cs create mode 100644 Octokit/Models/Response/DeploymentStatus.cs diff --git a/Octokit.Tests/Clients/DeploymentStatusClientTests.cs b/Octokit.Tests/Clients/DeploymentStatusClientTests.cs new file mode 100644 index 00000000..24b20cc0 --- /dev/null +++ b/Octokit.Tests/Clients/DeploymentStatusClientTests.cs @@ -0,0 +1,149 @@ +using NSubstitute; +using Octokit; +using Octokit.Tests.Helpers; +using System; +using System.Collections.Generic; +using Xunit; +using Xunit.Extensions; + +public class DeploymentStatusClientTests +{ + const string expectedAcceptsHeader = "application/vnd.github.cannonball-preview+json"; + + public class TheGetAllMethod + { + [Fact] + public async void EnsuresNonNullArguments() + { + var client = new DeploymentStatusClient(Substitute.For()); + + await AssertEx.Throws(async () => await client.GetAll(null, "name", 1)); + await AssertEx.Throws(async () => await client.GetAll("owner", null, 1)); + } + + [Fact] + public async void EnsuresNonEmptyArguments() + { + var client = new DeploymentStatusClient(Substitute.For()); + + await AssertEx.Throws(async () => await client.GetAll("", "name", 1)); + await AssertEx.Throws(async () => await client.GetAll("owner", "", 1)); + } + + [Theory] + [InlineData(" ")] + [InlineData("\n")] + [InlineData("\t")] + [InlineData(" ")] + [InlineData("\n\r")] + public async void EnsureNonWhitespaceArguments(string whitespace) + { + var client = new DeploymentStatusClient(Substitute.For()); + + await AssertEx.Throws(async () => await client.GetAll(whitespace, "name", 1)); + await AssertEx.Throws(async () => await client.GetAll("owner", whitespace, 1)); + } + + [Fact] + public void RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new DeploymentStatusClient(connection); + var expectedUrl = "repos/owner/name/deployments/1/statuses"; + + client.GetAll("owner", "name", 1); + connection.Received().GetAll(Arg.Is(u => u.ToString() == expectedUrl), + Arg.Any>(), + Arg.Any()); + } + + [Fact] + public void UsesPreviewAcceptHeader() + { + var connection = Substitute.For(); + var client = new DeploymentStatusClient(connection); + + client.GetAll("owner", "name", 1); + connection.Received().GetAll(Arg.Any(), + Arg.Any>(), + expectedAcceptsHeader); + } + } + + public class TheCreateMethod + { + readonly NewDeploymentStatus newDeploymentStatus = new NewDeploymentStatus(); + + [Fact] + public async void EnsuresNonNullArguments() + { + var client = new DeploymentStatusClient(Substitute.For()); + + await AssertEx.Throws(async () => + await client.Create(null, "name", 1, newDeploymentStatus)); + await AssertEx.Throws(async () => + await client.Create("owner", null, 1, newDeploymentStatus)); + } + + [Fact] + public async void EnsuresNonEmptyArguments() + { + var client = new DeploymentStatusClient(Substitute.For()); + + await AssertEx.Throws(async () => await client.GetAll("", "name", 1)); + await AssertEx.Throws(async () => await client.GetAll("owner", "", 1)); + } + + [Theory] + [InlineData(" ")] + [InlineData("\n")] + [InlineData("\t")] + [InlineData(" ")] + [InlineData("\n\r")] + public async void EnsureNonWhitespaceArguments(string whitespace) + { + var client = new DeploymentStatusClient(Substitute.For()); + + await AssertEx.Throws(async () => + await client.Create(whitespace, "repo", 1, newDeploymentStatus)); + await AssertEx.Throws(async () => + await client.Create("owner", whitespace, 1, newDeploymentStatus)); + } + + [Fact] + public void PostsToCorrectUrl() + { + var connection = Substitute.For(); + var client = new DeploymentStatusClient(connection); + var expectedUrl = "repos/owner/repo/deployments/1/statuses"; + + client.Create("owner", "repo", 1, newDeploymentStatus); + + connection.Received().Post(Arg.Is(u => u.ToString() == expectedUrl), + Arg.Any(), + Arg.Any()); + } + + [Fact] + public void UsesPreviewAcceptHeader() + { + var connection = Substitute.For(); + var client = new DeploymentStatusClient(connection); + + client.Create("owner", "repo", 1, newDeploymentStatus); + + connection.Received().Post(Arg.Any(), + Arg.Any(), + expectedAcceptsHeader); + } + } + + public class TheCtor + { + [Fact] + public void EnsuresArgument() + { + Assert.Throws(() => new DeploymentStatusClient(null)); + } + } +} \ No newline at end of file diff --git a/Octokit.Tests/Octokit.Tests.csproj b/Octokit.Tests/Octokit.Tests.csproj index 1f5b2327..2a3a9e95 100644 --- a/Octokit.Tests/Octokit.Tests.csproj +++ b/Octokit.Tests/Octokit.Tests.csproj @@ -63,6 +63,7 @@ + diff --git a/Octokit/Clients/DeploymentStatusClient.cs b/Octokit/Clients/DeploymentStatusClient.cs new file mode 100644 index 00000000..cdda84e6 --- /dev/null +++ b/Octokit/Clients/DeploymentStatusClient.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + public class DeploymentStatusClient : ApiClient, IDeploymentStatusClient + { + const string acceptsHeader = "application/vnd.github.cannonball-preview+json"; + + public DeploymentStatusClient(IApiConnection apiConnection) + : base(apiConnection) + { + } + + public Task> GetAll(string owner, string name, int deploymentId) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "name"); + + return ApiConnection.GetAll(ApiUrls.DeploymentStatuses(owner, name, deploymentId), + null, acceptsHeader); + } + + public Task Create(string owner, string name, int deploymentId, NewDeploymentStatus newDeploymentStatus) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "name"); + Ensure.ArgumentNotNull(newDeploymentStatus, "newDeploymentStatus"); + + return ApiConnection.Post(ApiUrls.DeploymentStatuses(owner, name, deploymentId), + newDeploymentStatus, acceptsHeader); + } + } +} diff --git a/Octokit/Clients/DeploymentsClient.cs b/Octokit/Clients/DeploymentsClient.cs index 5b8765c7..2a7e6031 100644 --- a/Octokit/Clients/DeploymentsClient.cs +++ b/Octokit/Clients/DeploymentsClient.cs @@ -10,6 +10,7 @@ namespace Octokit public DeploymentsClient(IApiConnection apiConnection) : base(apiConnection) { + Status = new DeploymentStatusClient(apiConnection); } public Task> GetAll(string owner, string name) @@ -30,5 +31,7 @@ namespace Octokit return ApiConnection.Post(ApiUrls.Deployments(owner, name), newDeployment, acceptsHeader); } + + public IDeploymentStatusClient Status { get; set; } } } diff --git a/Octokit/Clients/IDeploymentStatusClient.cs b/Octokit/Clients/IDeploymentStatusClient.cs new file mode 100644 index 00000000..fe0fc8b3 --- /dev/null +++ b/Octokit/Clients/IDeploymentStatusClient.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + public interface IDeploymentStatusClient + { + Task> GetAll(string owner, string name, int deploymentId); + + Task Create(string owner, string name, int deploymentId, NewDeploymentStatus newDeploymentStatus); + } +} \ No newline at end of file diff --git a/Octokit/Clients/IDeploymentsClient.cs b/Octokit/Clients/IDeploymentsClient.cs index 78995359..356565d0 100644 --- a/Octokit/Clients/IDeploymentsClient.cs +++ b/Octokit/Clients/IDeploymentsClient.cs @@ -7,5 +7,6 @@ namespace Octokit { Task> GetAll(string owner, string name); Task Create(string owner, string name, NewDeployment newDeployment); + IDeploymentStatusClient Status { get; } } } \ No newline at end of file diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index 72c73421..6a5e7562 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -786,5 +786,10 @@ namespace Octokit { return "repos/{0}/{1}/deployments".FormatUri(owner, name); } + + public static Uri DeploymentStatuses(string owner, string name, int deploymentId) + { + return "repos/{0}/{1}/deployments/{2}/statuses".FormatUri(owner, name, deploymentId); + } } } diff --git a/Octokit/Models/Request/NewDeploymentStatus.cs b/Octokit/Models/Request/NewDeploymentStatus.cs new file mode 100644 index 00000000..ab942f37 --- /dev/null +++ b/Octokit/Models/Request/NewDeploymentStatus.cs @@ -0,0 +1,11 @@ +namespace Octokit +{ + public class NewDeploymentStatus + { + public DeploymentState State { get; set; } + + public string TargetUrl { get; set; } + + public string Description { get; set; } + } +} \ No newline at end of file diff --git a/Octokit/Models/Response/DeploymentStatus.cs b/Octokit/Models/Response/DeploymentStatus.cs new file mode 100644 index 00000000..fff05eb0 --- /dev/null +++ b/Octokit/Models/Response/DeploymentStatus.cs @@ -0,0 +1,33 @@ +using System; + +namespace Octokit +{ + public class DeploymentStatus + { + public int Id { get; set; } + + public string Url { get; set; } + + public DeploymentState State { get; set; } + + public User Creator { get; set; } + + public string Payload { get; set; } + + public string TargetUrl { get; set; } + + public DateTime CreatedAt { get; set; } + + public DateTime UpdatedAt { get; set; } + + public string Description { get; set; } + } + + public enum DeploymentState + { + Pending, + Success, + Error, + Failure + } +} \ No newline at end of file diff --git a/Octokit/Octokit-Mono.csproj b/Octokit/Octokit-Mono.csproj index c82c3616..25d12f01 100644 --- a/Octokit/Octokit-Mono.csproj +++ b/Octokit/Octokit-Mono.csproj @@ -246,10 +246,14 @@ + + + + \ No newline at end of file diff --git a/Octokit/Octokit-MonoAndroid.csproj b/Octokit/Octokit-MonoAndroid.csproj index 710dd1b3..ff75e645 100644 --- a/Octokit/Octokit-MonoAndroid.csproj +++ b/Octokit/Octokit-MonoAndroid.csproj @@ -256,10 +256,14 @@ + + + + \ No newline at end of file diff --git a/Octokit/Octokit-Monotouch.csproj b/Octokit/Octokit-Monotouch.csproj index b21b9178..4d6b1ad9 100644 --- a/Octokit/Octokit-Monotouch.csproj +++ b/Octokit/Octokit-Monotouch.csproj @@ -251,10 +251,14 @@ + + + + \ No newline at end of file diff --git a/Octokit/Octokit-netcore45.csproj b/Octokit/Octokit-netcore45.csproj index 64f02a2a..41b181a8 100644 --- a/Octokit/Octokit-netcore45.csproj +++ b/Octokit/Octokit-netcore45.csproj @@ -244,10 +244,14 @@ + + + + diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index 7f0bc76c..3587649b 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -54,6 +54,10 @@ Properties\SolutionInfo.cs + + + +