From 654622371a4260bf34de3f3726bed057799cfed3 Mon Sep 17 00:00:00 2001 From: Josh Sullivan Date: Wed, 13 Nov 2013 01:28:10 -0500 Subject: [PATCH] PullRequest model now contains all of necessary fields - Initial integration test for pull requests (can't seem to do much without the tree api) - Added Observable unit tests for the rest of the pull request client --- .../Octokit.Tests.Integration.csproj | 3 + .../PullRequestsClientTests.cs | 71 +++++++++++ .../Clients/PullRequestsClientTests.cs | 18 +-- .../ObservablePullRequestsClientTests.cs | 101 +++++++++++++-- Octokit/Models/Request/NewPullRequest.cs | 20 ++- Octokit/Models/Response/GitReference.cs | 32 ++++- Octokit/Models/Response/PullRequest.cs | 115 +++++++++++++++++- 7 files changed, 332 insertions(+), 28 deletions(-) create mode 100644 Octokit.Tests.Integration/PullRequestsClientTests.cs diff --git a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj index 9587edf9..37879656 100644 --- a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj +++ b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj @@ -73,6 +73,9 @@ + + + diff --git a/Octokit.Tests.Integration/PullRequestsClientTests.cs b/Octokit.Tests.Integration/PullRequestsClientTests.cs new file mode 100644 index 00000000..704628d4 --- /dev/null +++ b/Octokit.Tests.Integration/PullRequestsClientTests.cs @@ -0,0 +1,71 @@ +using System; +using System.Linq; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Octokit; +using Octokit.Tests.Integration; +using Xunit; + +public class PullRequestsClientTests : IDisposable +{ + readonly IGitHubClient _gitHubClient; + readonly ICommitsClient _commitsClient; + readonly IPullRequestsClient _pullRequestsClient; + readonly Repository _modifiedRepository; + readonly string _modifiedRepositoryOwner; + readonly string _modifiedRepositoryName; + readonly Repository _targetRepository; + readonly string _targetRepositoryOwner; + readonly string _targetRepositoryName; + + public PullRequestsClientTests() + { + _gitHubClient = new GitHubClient(new ProductHeaderValue("OctokitTests")) + { + Credentials = Helper.Credentials + }; + + _commitsClient = _gitHubClient.GitDatabase.Commit; + _pullRequestsClient = _gitHubClient.Repository.PullRequest; + + var repoName = Helper.MakeNameWithTimestamp("public-repo"); + var targetRepoName = Helper.MakeNameWithTimestamp("source-repo"); + + _modifiedRepository = _gitHubClient.Repository.Create(new NewRepository { Name = repoName, AutoInit = true }).Result; + _modifiedRepositoryOwner = _modifiedRepository.Owner.Login; + _modifiedRepositoryName = _modifiedRepository.Name; + + _targetRepository = _gitHubClient.Repository.Create(new NewRepository { Name = targetRepoName, AutoInit = true}).Result; + _targetRepositoryOwner = _targetRepository.Owner.Login; + _targetRepositoryName = _targetRepository.Name; + + // add a new commit to the modified repository + var author = new Signature { Name = "author", Email = "test-author@example.com", Date = DateTime.UtcNow }; + var commiter = new Signature { Name = "commiter", Email = "test-commiter@example.com", Date = DateTime.Today }; + + var newCommit = new NewCommit("test-commit", "", Enumerable.Empty()) + { + Author = author, + Committer = commiter + }; + + _commitsClient.Create(_modifiedRepositoryOwner, _modifiedRepositoryName, newCommit); + } + + [IntegrationTest(Skip = "Requires Tree Api implementation to create a commit")] + public async Task CanRetrieveOnePullRequest() { + var baseRef = _targetRepositoryOwner + ":master"; + var headRef = _modifiedRepositoryOwner + ":master"; + + var newPullRequest = new NewPullRequest("a pull request", "a body", baseRef, headRef); + var result = await _pullRequestsClient.Create(_targetRepositoryOwner, _targetRepositoryName, newPullRequest); + + Assert.Equal("a pull request", result.Title); + } + + public void Dispose() + { + Helper.DeleteRepo(_modifiedRepository); + Helper.DeleteRepo(_targetRepository); + } +} diff --git a/Octokit.Tests/Clients/PullRequestsClientTests.cs b/Octokit.Tests/Clients/PullRequestsClientTests.cs index f07e2ce6..ab369339 100644 --- a/Octokit.Tests/Clients/PullRequestsClientTests.cs +++ b/Octokit.Tests/Clients/PullRequestsClientTests.cs @@ -71,7 +71,7 @@ namespace Octokit.Tests.Clients [Fact] public void PostsToCorrectUrl() { - var newPullRequest = new NewPullRequest("some title"); + var newPullRequest = new NewPullRequest("some title", "some body", "branch:name", "branch:name"); var connection = Substitute.For(); var client = new PullRequestsClient(connection); @@ -88,13 +88,13 @@ namespace Octokit.Tests.Clients var client = new PullRequestsClient(connection); AssertEx.Throws(async () => await - client.Create(null, "name", new NewPullRequest("title"))); + client.Create(null, "name", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("", "name", new NewPullRequest("x"))); + client.Create("", "name", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("owner", null, new NewPullRequest("x"))); + client.Create("owner", null, new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("owner", "", new NewPullRequest("x"))); + client.Create("owner", "", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await client.Create("owner", "name", null)); } @@ -122,13 +122,13 @@ namespace Octokit.Tests.Clients var client = new PullRequestsClient(connection); AssertEx.Throws(async () => await - client.Create(null, "name", new NewPullRequest("title"))); + client.Create(null, "name", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("", "name", new NewPullRequest("x"))); + client.Create("", "name", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("owner", null, new NewPullRequest("x"))); + client.Create("owner", null, new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("owner", "", new NewPullRequest("x"))); + client.Create("owner", "", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await client.Create("owner", "name", null)); } diff --git a/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs b/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs index d8a00516..ba21cbd1 100644 --- a/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs +++ b/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs @@ -156,7 +156,7 @@ namespace Octokit.Tests.Reactive [Fact] public void CreatesFromClientRepositoryPullRequest() { - var newPullRequest = new NewPullRequest("some title"); + var newPullRequest = new NewPullRequest("some title", "some body", "branch:name", "branch:name"); var gitHubClient = Substitute.For(); var client = new ObservablePullRequestsClient(gitHubClient); @@ -172,13 +172,13 @@ namespace Octokit.Tests.Reactive var client = new ObservablePullRequestsClient(gitHubClient); AssertEx.Throws(async () => await - client.Create(null, "name", new NewPullRequest("title"))); + client.Create(null, "name", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("", "name", new NewPullRequest("x"))); + client.Create("", "name", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("owner", null, new NewPullRequest("x"))); + client.Create("owner", null, new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("owner", "", new NewPullRequest("x"))); + client.Create("owner", "", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await client.Create("owner", "name", null)); } @@ -205,18 +205,101 @@ namespace Octokit.Tests.Reactive var client = new ObservablePullRequestsClient(gitHubClient); AssertEx.Throws(async () => await - client.Create(null, "name", new NewPullRequest("title"))); + client.Create(null, "name", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("", "name", new NewPullRequest("x"))); + client.Create("", "name", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("owner", null, new NewPullRequest("x"))); + client.Create("owner", null, new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await - client.Create("owner", "", new NewPullRequest("x"))); + client.Create("owner", "", new NewPullRequest("title", "body", "ref", "ref2"))); AssertEx.Throws(async () => await client.Create("owner", "name", null)); } } + public class TheMergeMethod + { + [Fact] + public void MergesPullRequest() + { + var mergePullRequest = new MergePullRequest("fake commit message"); + var gitHubClient = Substitute.For(); + var client = new ObservablePullRequestsClient(gitHubClient); + + client.Merge("fake", "repo", 42, mergePullRequest); + + gitHubClient.Repository.PullRequest.Received().Merge("fake", "repo", 42, mergePullRequest); + } + + [Fact] + public async Task EnsuresArgumentsNotNull() + { + var connection = Substitute.For(); + var client = new PullRequestsClient(connection); + + AssertEx.Throws(async () => await + client.Merge(null, "name", 42, new MergePullRequest("message"))); + AssertEx.Throws(async () => await + client.Merge("owner", null, 42, new MergePullRequest("message"))); + AssertEx.Throws(async () => await + client.Merge("owner", "name", 42, null)); + } + } + + public class TheMergedMethod + { + [Fact] + public void PullRequestMerged() + { + var pullRequestUpdate = new PullRequestUpdate(); + var gitHubClient = Substitute.For(); + var client = new ObservablePullRequestsClient(gitHubClient); + + client.Merged("fake", "repo", 42); + + gitHubClient.Repository.PullRequest.Received().Merged("fake", "repo", 42); + } + + [Fact] + public async Task EnsuresArgumentsNotNull() + { + var connection = Substitute.For(); + var client = new PullRequestsClient(connection); + + await AssertEx.Throws(async () => await client.Merged(null, "name", 1)); + await AssertEx.Throws(async () => await client.Merged("owner", null, 1)); + await AssertEx.Throws(async () => await client.Merged(null, "", 1)); + await AssertEx.Throws(async () => await client.Merged("", null, 1)); + } + } + + public class TheCommitsMethod + { + [Fact] + public async void FetchesAllCommitsForPullRequest() + { + var pullRequestUpdate = new PullRequestUpdate(); + var gitHubClient = Substitute.For(); + var client = new ObservablePullRequestsClient(gitHubClient); + + client.Commits("fake", "repo", 42); + + gitHubClient.Repository.PullRequest.Received().Commits("fake", "repo", 42); + } + + [Fact] + public async Task EnsuresArgumentsNotNull() + { + var connection = Substitute.For(); + var client = new PullRequestsClient(connection); + + await AssertEx.Throws(async () => await client.Commits(null, "name", 1)); + await AssertEx.Throws(async () => await client.Commits("owner", null, 1)); + await AssertEx.Throws(async () => await client.Commits(null, "", 1)); + await AssertEx.Throws(async () => await client.Commits("", null, 1)); + } + } + public class TheCtor { [Fact] diff --git a/Octokit/Models/Request/NewPullRequest.cs b/Octokit/Models/Request/NewPullRequest.cs index e2e799e8..03d65a05 100644 --- a/Octokit/Models/Request/NewPullRequest.cs +++ b/Octokit/Models/Request/NewPullRequest.cs @@ -7,12 +7,14 @@ namespace Octokit /// public class NewPullRequest { - public NewPullRequest(string title) + public NewPullRequest(string title, string body, string baseRef, string head) { Ensure.ArgumentNotNull(title, "title"); Title = title; - State = ItemState.Open; + Body = body; + Base = baseRef; + Head = head; } /// @@ -21,8 +23,18 @@ namespace Octokit public string Title { get; private set; } /// - /// Whether the pull request is open or closed. The default is . + /// Body of the pull request (optional) /// - public ItemState State { get; set; } + public string Body { get; set; } + + /// + /// The branch (or git ref) you want your changes pulled into (required). + /// + public string Base { get; set; } + + /// + /// The branch (or git ref) where your changes are implemented (required). + /// + public string Head { get; set; } } } diff --git a/Octokit/Models/Response/GitReference.cs b/Octokit/Models/Response/GitReference.cs index cae404d1..281f76e7 100644 --- a/Octokit/Models/Response/GitReference.cs +++ b/Octokit/Models/Response/GitReference.cs @@ -1,8 +1,38 @@ -namespace Octokit +using Octokit.Internal; + +namespace Octokit { public class GitReference { + /// + /// The URL associated with this reference. + /// public string Url { get; set; } + + /// + /// The reference label. + /// + public string Label { get; set; } + + /// + /// The reference identifier. + /// + public string Ref { get; set; } + + /// + /// The sha value of the reference. + /// public string Sha { get; set; } + + /// + /// The user associated with this reference. + /// + public User User { get; set; } + + /// + /// The repository associated with this reference. + /// + [Parameter(Key = "repo")] + public Repository Repository { get; set; } } } \ No newline at end of file diff --git a/Octokit/Models/Response/PullRequest.cs b/Octokit/Models/Response/PullRequest.cs index d9a2dd95..ac39c812 100644 --- a/Octokit/Models/Response/PullRequest.cs +++ b/Octokit/Models/Response/PullRequest.cs @@ -9,11 +9,6 @@ namespace Octokit /// public Uri Url { get; set; } - /// - /// The pull request number. - /// - public int Number { get; set; } - /// /// The URL for the pull request page. /// @@ -28,5 +23,115 @@ namespace Octokit /// The URL for the pull request's patch (.patch) file. /// public Uri PatchUrl { get; set; } + + /// + /// The URL for the specific pull request issue. + /// + public Uri IssueUrl { get; set; } + + /// + /// The URL for the pull request statuses. + /// + public Uri StatusesUrl { get; set; } + + /// + /// The pull request number. + /// + public int Number { get; set; } + + /// + /// Whether the pull request is open or closed. The default is . + /// + public ItemState State { get; set; } + + /// + /// Title of the pull request. + /// + public string Title { get; set; } + + /// + /// The body (content) contained within the pull request. + /// + public string Body { get; set; } + + /// + /// When the pull request was created. + /// + public DateTimeOffset CreatedAt { get; set; } + + /// + /// When the pull request was last updated. + /// + public DateTimeOffset UpdatedAt { get; set; } + + /// + /// When the pull request was closed. + /// + public DateTimeOffset ClosedAt { get; set; } + + /// + /// When the pull request was merged. + /// + public DateTimeOffset MergedAt { get; set; } + + /// + /// The HEAD reference for the pull request. + /// + public GitReference Head { get; set; } + + /// + /// The BASE reference for the pull request. + /// + public GitReference Base { get; set; } + + /// + /// The user who created the pull request. + /// + public User User { get; set; } + + /// + /// The SHA of the merge commit. + /// + public string MergeCommitSha { get; set; } + + /// + /// Whether or not the pull request has been merged. + /// + public bool Merged { get; set; } + + /// + /// Whether or not the pull request can be merged. + /// + public bool Mergable { get; set; } + + /// + /// The user who merged the pull request. + /// + public User MergedBy { get; set; } + + /// + /// Total number of comments contained in the pull request. + /// + public int Comments { get; set; } + + /// + /// Total number of commits contained in the pull request. + /// + public int Commits { get; set; } + + /// + /// Total number of additions contained in the pull request. + /// + public int Additions { get; set; } + + /// + /// Total number of deletions contained in the pull request. + /// + public int Deletions { get; set; } + + /// + /// Total number of files changed in the pull request. + /// + public int ChangedFiles { get; set; } } } \ No newline at end of file