From c5d12dcc7ead908356cb013fb0efb0880b70f912 Mon Sep 17 00:00:00 2001 From: Peter MacNaughton Date: Tue, 21 Jan 2014 10:29:36 -0700 Subject: [PATCH] Implemented ObservableDeploymentStatusClient and... unit tests. --- .../IObservableDeploymentStatusClient.cs | 36 +++++ .../ObservableDeploymentStatusClient.cs | 59 ++++++++ Octokit.Reactive/Octokit.Reactive-Mono.csproj | 2 + .../Octokit.Reactive-MonoAndroid.csproj | 2 + .../Octokit.Reactive-Monotouch.csproj | 2 + Octokit.Reactive/Octokit.Reactive.csproj | 2 + Octokit.Tests/Octokit.Tests.csproj | 1 + .../ObservableDeploymentStatusClientTests.cs | 143 ++++++++++++++++++ 8 files changed, 247 insertions(+) create mode 100644 Octokit.Reactive/Clients/IObservableDeploymentStatusClient.cs create mode 100644 Octokit.Reactive/Clients/ObservableDeploymentStatusClient.cs create mode 100644 Octokit.Tests/Reactive/ObservableDeploymentStatusClientTests.cs diff --git a/Octokit.Reactive/Clients/IObservableDeploymentStatusClient.cs b/Octokit.Reactive/Clients/IObservableDeploymentStatusClient.cs new file mode 100644 index 00000000..2ae7cf14 --- /dev/null +++ b/Octokit.Reactive/Clients/IObservableDeploymentStatusClient.cs @@ -0,0 +1,36 @@ +using System; +using System.Reactive.Threading.Tasks; +using Octokit.Reactive.Internal; + +namespace Octokit.Reactive.Clients +{ + public interface IObservableDeploymentStatusClient + { + /// + /// Gets all the statuses for the given deployment. Any user with pull access to a repository can + /// view deployments. + /// + /// + /// http://developer.github.com/v3/repos/deployments/#list-deployment-statuses + /// + /// The owner of the repository. + /// The name of the repository. + /// The id of the deployment. + /// All deployment statuses for the given deployment. + IObservable GetAll(string owner, string name, int deploymentId); + + /// + /// Creates a new status for the given deployment. Users with push access can create deployment + /// statuses for a given deployment. + /// + /// + /// http://developer.github.com/v3/repos/deployments/#create-a-deployment-status + /// + /// The owner of the repository. + /// The name of the repository. + /// The id of the deployment. + /// The new deployment status to create. + /// + IObservable Create(string owner, string name, int deploymentId, NewDeploymentStatus newDeploymentStatus); + } +} \ No newline at end of file diff --git a/Octokit.Reactive/Clients/ObservableDeploymentStatusClient.cs b/Octokit.Reactive/Clients/ObservableDeploymentStatusClient.cs new file mode 100644 index 00000000..ec646d9e --- /dev/null +++ b/Octokit.Reactive/Clients/ObservableDeploymentStatusClient.cs @@ -0,0 +1,59 @@ +using Octokit.Reactive.Internal; +using System; +using System.Reactive.Threading.Tasks; + +namespace Octokit.Reactive.Clients +{ + public class ObservableDeploymentStatusClient : IObservableDeploymentStatusClient + { + const string acceptsHeader = "application/vnd.github.cannonball-preview+json"; + private IDeploymentStatusClient _client; + private IConnection _connection; + + public ObservableDeploymentStatusClient(IGitHubClient client) + { + Ensure.ArgumentNotNull(client, "client"); + + _client = client.Deployment.Status; + _connection = client.Connection; + } + + /// + /// Gets all the statuses for the given deployment. Any user with pull access to a repository can + /// view deployments. + /// + /// + /// http://developer.github.com/v3/repos/deployments/#list-deployment-statuses + /// + /// The owner of the repository. + /// The name of the repository. + /// The id of the deployment. + /// All deployment statuses for the given deployment. + public IObservable GetAll(string owner, string name, int deploymentId) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "name"); + + return _connection.GetAndFlattenAllPages( + ApiUrls.DeploymentStatuses(owner, name, deploymentId), + null, acceptsHeader); + } + + /// + /// Creates a new status for the given deployment. Users with push access can create deployment + /// statuses for a given deployment. + /// + /// + /// http://developer.github.com/v3/repos/deployments/#create-a-deployment-status + /// + /// The owner of the repository. + /// The name of the repository. + /// The id of the deployment. + /// The new deployment status to create. + /// + public IObservable Create(string owner, string name, int deploymentId, NewDeploymentStatus newDeploymentStatus) + { + return _client.Create(owner, name, deploymentId, newDeploymentStatus).ToObservable(); + } + } +} diff --git a/Octokit.Reactive/Octokit.Reactive-Mono.csproj b/Octokit.Reactive/Octokit.Reactive-Mono.csproj index 93e07216..aea65088 100644 --- a/Octokit.Reactive/Octokit.Reactive-Mono.csproj +++ b/Octokit.Reactive/Octokit.Reactive-Mono.csproj @@ -120,6 +120,8 @@ + + diff --git a/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj b/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj index 0f1bff01..6dfc2a78 100644 --- a/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj +++ b/Octokit.Reactive/Octokit.Reactive-MonoAndroid.csproj @@ -129,6 +129,8 @@ + + diff --git a/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj b/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj index 4186eb1e..ef06fde1 100644 --- a/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj +++ b/Octokit.Reactive/Octokit.Reactive-Monotouch.csproj @@ -124,6 +124,8 @@ + + diff --git a/Octokit.Reactive/Octokit.Reactive.csproj b/Octokit.Reactive/Octokit.Reactive.csproj index 34d4e8ea..876530db 100644 --- a/Octokit.Reactive/Octokit.Reactive.csproj +++ b/Octokit.Reactive/Octokit.Reactive.csproj @@ -74,7 +74,9 @@ Properties\SolutionInfo.cs + + diff --git a/Octokit.Tests/Octokit.Tests.csproj b/Octokit.Tests/Octokit.Tests.csproj index 413468bd..5f2090ae 100644 --- a/Octokit.Tests/Octokit.Tests.csproj +++ b/Octokit.Tests/Octokit.Tests.csproj @@ -132,6 +132,7 @@ + diff --git a/Octokit.Tests/Reactive/ObservableDeploymentStatusClientTests.cs b/Octokit.Tests/Reactive/ObservableDeploymentStatusClientTests.cs new file mode 100644 index 00000000..c1710404 --- /dev/null +++ b/Octokit.Tests/Reactive/ObservableDeploymentStatusClientTests.cs @@ -0,0 +1,143 @@ +using NSubstitute; +using Octokit.Reactive.Clients; +using Octokit.Tests.Helpers; +using System; +using System.Collections.Generic; +using System.Reactive.Linq; +using System.Threading.Tasks; +using Xunit; + +namespace Octokit.Tests.Reactive +{ + public class ObservableDeploymentStatusClientTests + { + const string ExpectedAcceptHeader = "application/vnd.github.cannonball-preview+json"; + + public class TheGetAllMethod + { + readonly IGitHubClient _githubClient; + readonly ObservableDeploymentStatusClient _client; + + public TheGetAllMethod() + { + _githubClient = new GitHubClient(Substitute.For()); + _client = new ObservableDeploymentStatusClient(_githubClient); + } + + [Fact] + public void EnsuresNonNullArguments() + { + AssertEx.Throws( + async () => await _client.GetAll(null, "repo", 1)); + AssertEx.Throws( + async () => await _client.GetAll("owner", null, 1)); + } + + [Fact] + public void EnsuresNonEmptyArguments() + { + AssertEx.Throws( + async () => await _client.GetAll("", "repo", 1)); + AssertEx.Throws( + async () => await _client.GetAll("owner", "", 1)); + } + + [Fact] + public void EnsureNonWhitespaceArguments() + { + AssertEx.ThrowsWhenGivenWhitespaceArgument( + async whitespace => await _client.GetAll(whitespace, "repo", 1)); + AssertEx.ThrowsWhenGivenWhitespaceArgument( + async whitespace => await _client.GetAll("owner", whitespace, 1)); + } + + [Fact] + public void GetsFromCorrectUrl() + { + var expectedUri = ApiUrls.DeploymentStatuses("owner", "repo", 1); + + _client.GetAll("owner", "repo", 1); + + _githubClient.Connection + .Received(1) + .GetAsync>(Arg.Is(expectedUri), + Arg.Any>(), + Arg.Any()); + } + + [Fact] + public void UsesPreviewAcceptHeader() + { + _client.GetAll("owner", "repo", 1); + + _githubClient.Connection + .Received(1) + .GetAsync>(Arg.Any(), + Arg.Any>(), + Arg.Is(ExpectedAcceptHeader)); + } + } + + public class TheCreateMethod + { + readonly IGitHubClient _githubClient = Substitute.For(); + readonly ObservableDeploymentStatusClient _client; + + public TheCreateMethod() + { + _client = new ObservableDeploymentStatusClient(_githubClient); + } + + [Fact] + public void EnsuresNonNullArguments() + { + AssertEx.Throws( + async () => await _client.GetAll(null, "repo", 1)); + AssertEx.Throws( + async () => await _client.GetAll("owner", null, 1)); + } + + [Fact] + public void EnsuresNonEmptyArguments() + { + AssertEx.Throws( + async () => await _client.GetAll("", "repo", 1)); + AssertEx.Throws( + async () => await _client.GetAll("owner", "", 1)); + } + + [Fact] + public void EnsureNonWhitespaceArguments() + { + AssertEx.ThrowsWhenGivenWhitespaceArgument( + async ws => await _client.GetAll(ws, "repo", 1)); + AssertEx.ThrowsWhenGivenWhitespaceArgument( + async ws => await _client.GetAll("owner", ws, 1)); + } + + [Fact] + public void CallsIntoDeploymentStatusClient() + { + var newStatus = new NewDeploymentStatus(); + _client.Create("owner", "repo", 1, newStatus); + _githubClient.Deployment + .Status + .Received(1) + .Create(Arg.Is("owner"), + Arg.Is("repo"), + Arg.Is(1), + Arg.Is(newStatus)); + } + } + + public class TheCtor + { + [Fact] + public void EnsuresArgument() + { + Assert.Throws( + () => new ObservableDeploymentStatusClient(null)); + } + } + } +}