diff --git a/Octokit.Tests/Clients/PullRequestsClientTests.cs b/Octokit.Tests/Clients/PullRequestsClientTests.cs index 0b84433d..38d897b6 100644 --- a/Octokit.Tests/Clients/PullRequestsClientTests.cs +++ b/Octokit.Tests/Clients/PullRequestsClientTests.cs @@ -44,16 +44,35 @@ namespace Octokit.Tests.Clients await client.GetAllForRepository("fake", "repo"); connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/fake/repo/pulls"), - Arg.Any>()); + Arg.Any>(), Args.ApiOptions); } [Fact] - public void SendsAppropriateParameters() + public async Task RequestsCorrectUrlWithApiOptions() { var connection = Substitute.For(); var client = new PullRequestsClient(connection); - client.GetAllForRepository("fake", "repo", new PullRequestRequest { Head = "user:ref-head", Base = "fake_base_branch" }); + var options = new ApiOptions + { + StartPage = 1, + PageCount = 1, + PageSize = 1 + }; + + await client.GetAllForRepository("fake", "repo", options); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/fake/repo/pulls"), + Arg.Any>(), options); + } + + [Fact] + public async Task SendsAppropriateParameters() + { + var connection = Substitute.For(); + var client = new PullRequestsClient(connection); + + await client.GetAllForRepository("fake", "repo", new PullRequestRequest { Head = "user:ref-head", Base = "fake_base_branch" }); connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/fake/repo/pulls"), Arg.Is>(d => d.Count == 5 @@ -61,20 +80,78 @@ namespace Octokit.Tests.Clients && d["state"] == "open" && d["base"] == "fake_base_branch" && d["sort"] == "created" - && d["direction"] == "desc")); + && d["direction"] == "desc"), Args.ApiOptions); + } + + [Fact] + public async Task SendsAppropriateParametersWithApiOptions() + { + var connection = Substitute.For(); + var client = new PullRequestsClient(connection); + + var options = new ApiOptions + { + StartPage = 1, + PageCount = 1, + PageSize = 1 + }; + + await client.GetAllForRepository("fake", "repo", new PullRequestRequest { Head = "user:ref-head", Base = "fake_base_branch" }, options); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/fake/repo/pulls"), + Arg.Is>(d => d.Count == 5 + && d["head"] == "user:ref-head" + && d["state"] == "open" + && d["base"] == "fake_base_branch" + && d["sort"] == "created" + && d["direction"] == "desc"), options); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PullRequestsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.GetAllForRepository(null, "name")); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", null)); + + await Assert.ThrowsAsync(() => client.GetAllForRepository(null, "name", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", null, ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", "name", (ApiOptions)null)); + + await Assert.ThrowsAsync(() => client.GetAllForRepository(null, "name", new PullRequestRequest())); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", null, new PullRequestRequest())); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", "name", (PullRequestRequest)null)); + + await Assert.ThrowsAsync(() => client.GetAllForRepository(null, "name", new PullRequestRequest(), ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", null, new PullRequestRequest(), ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", "name", null, ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", "name", new PullRequestRequest(), null)); + + await Assert.ThrowsAsync(() => client.GetAllForRepository("", "name")); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", "")); + + await Assert.ThrowsAsync(() => client.GetAllForRepository("", "name", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", "", ApiOptions.None)); + + await Assert.ThrowsAsync(() => client.GetAllForRepository("", "name", new PullRequestRequest())); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", "", new PullRequestRequest())); + + await Assert.ThrowsAsync(() => client.GetAllForRepository("", "name", new PullRequestRequest(), ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllForRepository("owner", "", new PullRequestRequest(), ApiOptions.None)); } } public class TheCreateMethod { [Fact] - public void PostsToCorrectUrl() + public async Task PostsToCorrectUrl() { var newPullRequest = new NewPullRequest("some title", "branch:name", "branch:name"); var connection = Substitute.For(); var client = new PullRequestsClient(connection); - client.Create("fake", "repo", newPullRequest); + await client.Create("fake", "repo", newPullRequest); connection.Received().Post(Arg.Is(u => u.ToString() == "repos/fake/repo/pulls"), newPullRequest); @@ -102,13 +179,13 @@ namespace Octokit.Tests.Clients public class TheUpdateMethod { [Fact] - public void PostsToCorrectUrl() + public async Task PostsToCorrectUrl() { var pullRequestUpdate = new PullRequestUpdate(); var connection = Substitute.For(); var client = new PullRequestsClient(connection); - client.Update("fake", "repo", 42, pullRequestUpdate); + await client.Update("fake", "repo", 42, pullRequestUpdate); connection.Received().Patch(Arg.Is(u => u.ToString() == "repos/fake/repo/pulls/42"), pullRequestUpdate); @@ -136,13 +213,13 @@ namespace Octokit.Tests.Clients public class TheMergeMethod { [Fact] - public void PutsToCorrectUrl() + public async Task PutsToCorrectUrl() { var mergePullRequest = new MergePullRequest { CommitMessage = "fake commit message" }; var connection = Substitute.For(); var client = new PullRequestsClient(connection); - client.Merge("fake", "repo", 42, mergePullRequest); + await client.Merge("fake", "repo", 42, mergePullRequest); connection.Received().Put(Arg.Is(u => u.ToString() == "repos/fake/repo/pulls/42/merge"), mergePullRequest,null, "application/vnd.github.polaris-preview+json"); @@ -166,7 +243,7 @@ namespace Octokit.Tests.Clients public class TheMergedMethod { [Fact] - public void RequestsCorrectUrl() + public async Task RequestsCorrectUrl() { var conn = Substitute.For(); var connection = Substitute.For(); @@ -174,7 +251,7 @@ namespace Octokit.Tests.Clients var client = new PullRequestsClient(connection); - client.Merged("fake", "repo", 42); + await client.Merged("fake", "repo", 42); conn.Received().Get(Arg.Is(u => u.ToString() == "repos/fake/repo/pulls/42/merge"), null, null); } diff --git a/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs b/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs index 3d8ad7b9..c4e8e769 100644 --- a/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs +++ b/Octokit.Tests/Reactive/ObservablePullRequestsClientTests.cs @@ -41,7 +41,7 @@ namespace Octokit.Tests.Reactive public class TheGetForRepositoryMethod { [Fact] - public void ReturnsEveryPageOfPullRequests() + public async Task ReturnsEveryPageOfPullRequests() { var firstPageUrl = new Uri("repos/fake/repo/pulls", UriKind.Relative); var secondPageUrl = new Uri("https://example.com/page/2"); @@ -77,15 +77,15 @@ namespace Octokit.Tests.Reactive } ); var gitHubClient = Substitute.For(); - gitHubClient.Connection.Get>(firstPageUrl, null, null) + gitHubClient.Connection.Get>(firstPageUrl, Args.EmptyDictionary, null) .Returns(Task.Factory.StartNew>>(() => firstPageResponse)); - gitHubClient.Connection.Get>(secondPageUrl, null, null) + gitHubClient.Connection.Get>(secondPageUrl, Args.EmptyDictionary, null) .Returns(Task.Factory.StartNew>>(() => secondPageResponse)); - gitHubClient.Connection.Get>(thirdPageUrl, null, null) + gitHubClient.Connection.Get>(thirdPageUrl, Args.EmptyDictionary, null) .Returns(Task.Factory.StartNew>>(() => lastPageResponse)); var client = new ObservablePullRequestsClient(gitHubClient); - var results = client.GetAllForRepository("fake", "repo").ToArray().Wait(); + var results = await client.GetAllForRepository("fake", "repo").ToArray(); Assert.Equal(7, results.Length); Assert.Equal(firstPageResponse.Body[0].Number, results[0].Number); @@ -94,7 +94,74 @@ namespace Octokit.Tests.Reactive } [Fact] - public void SendsAppropriateParameters() + public async Task ReturnsEveryPageOfPullRequestsWithApiOptions() + { + var firstPageUrl = new Uri("repos/fake/repo/pulls", UriKind.Relative); + var secondPageUrl = new Uri("https://example.com/page/2"); + var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; + var firstPageResponse = new ApiResponse> + ( + CreateResponseWithApiInfo(firstPageLinks), + new List + { + new PullRequest(1), + new PullRequest(2), + new PullRequest(3) + } + ); + var thirdPageUrl = new Uri("https://example.com/page/3"); + var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; + var secondPageResponse = new ApiResponse> + ( + CreateResponseWithApiInfo(secondPageLinks), + new List + { + new PullRequest(4), + new PullRequest(5), + new PullRequest(6) + } + ); + var lastPageResponse = new ApiResponse> + ( + new Response(), + new List + { + new PullRequest(7) + } + ); + + var gitHubClient = Substitute.For(); + gitHubClient.Connection.Get>(firstPageUrl, Arg.Is>(d => d.Count == 2 + && d["page"] == "1" + && d["per_page"] == "2"), null) + .Returns(Task.Factory.StartNew>>(() => firstPageResponse)); + gitHubClient.Connection.Get>(secondPageUrl, Arg.Is>(d => d.Count == 2 + && d["page"] == "1" + && d["per_page"] == "2"), null) + .Returns(Task.Factory.StartNew>>(() => secondPageResponse)); + gitHubClient.Connection.Get>(thirdPageUrl, Arg.Is>(d => d.Count == 2 + && d["page"] == "1" + && d["per_page"] == "2"), null) + .Returns(Task.Factory.StartNew>>(() => lastPageResponse)); + var client = new ObservablePullRequestsClient(gitHubClient); + + var options = new ApiOptions + { + StartPage = 1, + PageSize = 2, + PageCount = 1 + }; + + var results = await client.GetAllForRepository("fake", "repo", options).ToArray(); + + Assert.Equal(7, results.Length); + Assert.Equal(firstPageResponse.Body[0].Number, results[0].Number); + Assert.Equal(secondPageResponse.Body[1].Number, results[4].Number); + Assert.Equal(lastPageResponse.Body[0].Number, results[6].Number); + } + + [Fact] + public async Task SendsAppropriateParameters() { var firstPageUrl = new Uri("repos/fake/repo/pulls", UriKind.Relative); var secondPageUrl = new Uri("https://example.com/page/2"); @@ -138,19 +205,145 @@ namespace Octokit.Tests.Reactive && d["sort"] == "created" && d["direction"] == "desc"), Arg.Any()) .Returns(Task.Factory.StartNew>>(() => firstPageResponse)); - gitHubClient.Connection.Get>(secondPageUrl, null, null) + gitHubClient.Connection.Get>(secondPageUrl, Arg.Is>(d => d.Count == 5 + && d["head"] == "user:ref-name" + && d["state"] == "open" + && d["base"] == "fake_base_branch" + && d["sort"] == "created" + && d["direction"] == "desc"), null) .Returns(Task.Factory.StartNew>>(() => secondPageResponse)); - gitHubClient.Connection.Get>(thirdPageUrl, null, null) + gitHubClient.Connection.Get>(thirdPageUrl, Arg.Is>(d => d.Count == 5 + && d["head"] == "user:ref-name" + && d["state"] == "open" + && d["base"] == "fake_base_branch" + && d["sort"] == "created" + && d["direction"] == "desc"), null) .Returns(Task.Factory.StartNew>>(() => lastPageResponse)); var client = new ObservablePullRequestsClient(gitHubClient); - var results = client.GetAllForRepository("fake", "repo", new PullRequestRequest { Head = "user:ref-name", Base = "fake_base_branch" }).ToArray().Wait(); + var results = await client.GetAllForRepository("fake", "repo", new PullRequestRequest { Head = "user:ref-name", Base = "fake_base_branch" }).ToArray(); Assert.Equal(7, results.Length); Assert.Equal(firstPageResponse.Body[0].Number, results[0].Number); Assert.Equal(secondPageResponse.Body[1].Number, results[4].Number); Assert.Equal(lastPageResponse.Body[0].Number, results[6].Number); } + + [Fact] + public async Task SendsAppropriateParametersWitApiOptions() + { + var firstPageUrl = new Uri("repos/fake/repo/pulls", UriKind.Relative); + var secondPageUrl = new Uri("https://example.com/page/2"); + var firstPageLinks = new Dictionary { { "next", secondPageUrl } }; + var firstPageResponse = new ApiResponse> + ( + CreateResponseWithApiInfo(firstPageLinks), + new List + { + new PullRequest(1), + new PullRequest(2), + new PullRequest(3) + } + ); + var thirdPageUrl = new Uri("https://example.com/page/3"); + var secondPageLinks = new Dictionary { { "next", thirdPageUrl } }; + var secondPageResponse = new ApiResponse> + ( + CreateResponseWithApiInfo(secondPageLinks), + new List + { + new PullRequest(4), + new PullRequest(5), + new PullRequest(6) + } + ); + var lastPageResponse = new ApiResponse> + ( + new Response(), + new List + { + new PullRequest(7) + } + ); + + var gitHubClient = Substitute.For(); + gitHubClient.Connection.Get>(Arg.Is(firstPageUrl), + Arg.Is>(d => d.Count == 7 + && d["head"] == "user:ref-name" + && d["state"] == "open" + && d["base"] == "fake_base_branch" + && d["sort"] == "created" + && d["direction"] == "desc" + && d["page"] == "1" + && d["per_page"] == "2"), Arg.Any()) + .Returns(Task.Factory.StartNew>>(() => firstPageResponse)); + gitHubClient.Connection.Get>(secondPageUrl, Arg.Is>(d => d.Count == 7 + && d["head"] == "user:ref-name" + && d["state"] == "open" + && d["base"] == "fake_base_branch" + && d["sort"] == "created" + && d["direction"] == "desc"), null) + .Returns(Task.Factory.StartNew>>(() => secondPageResponse)); + gitHubClient.Connection.Get>(thirdPageUrl, Arg.Is>(d => d.Count == 7 + && d["head"] == "user:ref-name" + && d["state"] == "open" + && d["base"] == "fake_base_branch" + && d["sort"] == "created" + && d["direction"] == "desc" + && d["page"] == "1" + && d["per_page"] == "2"), null) + .Returns(Task.Factory.StartNew>>(() => lastPageResponse)); + var client = new ObservablePullRequestsClient(gitHubClient); + + var options = new ApiOptions + { + StartPage = 1, + PageSize = 2, + PageCount = 1 + }; + + var results = await client.GetAllForRepository("fake", "repo", new PullRequestRequest { Head = "user:ref-name", Base = "fake_base_branch" }, options).ToArray(); + + Assert.Equal(7, results.Length); + Assert.Equal(firstPageResponse.Body[0].Number, results[0].Number); + Assert.Equal(secondPageResponse.Body[1].Number, results[4].Number); + Assert.Equal(lastPageResponse.Body[0].Number, results[6].Number); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePullRequestsClient(gitHubClient); + + Assert.Throws(() => client.GetAllForRepository(null, "name")); + Assert.Throws(() => client.GetAllForRepository("owner", null)); + + Assert.Throws(() => client.GetAllForRepository(null, "name", ApiOptions.None)); + Assert.Throws(() => client.GetAllForRepository("owner", null, ApiOptions.None)); + Assert.Throws(() => client.GetAllForRepository("owner", "name", (ApiOptions)null)); + + Assert.Throws(() => client.GetAllForRepository(null, "name", new PullRequestRequest())); + Assert.Throws(() => client.GetAllForRepository("owner", null, new PullRequestRequest())); + Assert.Throws(() => client.GetAllForRepository("owner", "name", (PullRequestRequest)null)); + + Assert.Throws(() => client.GetAllForRepository(null, "name", new PullRequestRequest(), ApiOptions.None)); + Assert.Throws(() => client.GetAllForRepository("owner", null, new PullRequestRequest(), ApiOptions.None)); + Assert.Throws(() => client.GetAllForRepository("owner", "name", null, ApiOptions.None)); + Assert.Throws(() => client.GetAllForRepository("owner", "name", new PullRequestRequest(), null)); + + Assert.Throws(() => client.GetAllForRepository("", "name")); + Assert.Throws(() => client.GetAllForRepository("owner", "")); + + Assert.Throws(() => client.GetAllForRepository("", "name", ApiOptions.None)); + Assert.Throws(() => client.GetAllForRepository("owner", "", ApiOptions.None)); + + Assert.Throws(() => client.GetAllForRepository("", "name", new PullRequestRequest())); + Assert.Throws(() => client.GetAllForRepository("owner", "", new PullRequestRequest())); + + Assert.Throws(() => client.GetAllForRepository("", "name", new PullRequestRequest(), ApiOptions.None)); + Assert.Throws(() => client.GetAllForRepository("owner", "", new PullRequestRequest(), ApiOptions.None)); + } } public class TheCreateMethod