diff --git a/Octokit.Reactive/Clients/IObservablePullRequestReviewsClient.cs b/Octokit.Reactive/Clients/IObservablePullRequestReviewsClient.cs
new file mode 100644
index 0000000000..92a2b17ade
--- /dev/null
+++ b/Octokit.Reactive/Clients/IObservablePullRequestReviewsClient.cs
@@ -0,0 +1,187 @@
+using System;
+using System.Reactive;
+
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Pull Request Review API.
+ ///
+ ///
+ /// See the Review API documentation for more information.
+ ///
+ public interface IObservablePullRequestReviewsClient
+ {
+ ///
+ /// Gets reviews for a specified pull request.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ IObservable GetAll(string owner, string name, int number);
+
+ ///
+ /// Gets reviews for a specified pull request.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+ /// The Id of the repository
+ /// The pull request number
+ IObservable GetAll(long repositoryId, int number);
+
+ ///
+ /// Gets reviews for a specified pull request.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// Options for changing the API response
+ IObservable GetAll(string owner, string name, int number, ApiOptions options);
+
+ ///
+ /// Gets reviews for a specified pull request.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+ /// The Id of the repository
+ /// The pull request number
+ /// Options for changing the API response
+ IObservable GetAll(long repositoryId, int number, ApiOptions options);
+
+ ///
+ /// Gets a single pull request review by ID.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-a-single-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ IObservable Get(string owner, string name, int number, long reviewId);
+
+ ///
+ /// Gets a single pull request review by ID.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-a-single-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ IObservable Get(long repositoryId, int number, long reviewId);
+
+ ///
+ /// Creates a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The Pull Request number
+ /// The review
+ IObservable Create(string owner, string name, int number, PullRequestReviewCreate review);
+
+ ///
+ /// Creates a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review
+ /// The Id of the repository
+ /// The Pull Request number
+ /// The review
+ IObservable Create(long repositoryId, int number, PullRequestReviewCreate review);
+
+ ///
+ /// Deletes a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ IObservable Delete(string owner, string name, int number, long reviewId);
+
+ ///
+ /// Deletes a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ IObservable Delete(long repositoryId, int number, long reviewId);
+
+ ///
+ /// Submits a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ /// The message and event being submitted for the review
+ IObservable Submit(string owner, string name, int number, long reviewId, PullRequestReviewSubmit submitMessage);
+
+ ///
+ /// Submits a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ /// The message and event being submitted for the review
+ IObservable Submit(long repositoryId, int number, long reviewId, PullRequestReviewSubmit submitMessage);
+
+ ///
+ /// Dismisses a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#dismiss-a-pull-request-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ /// The message indicating why the review was dismissed
+ IObservable Dismiss(string owner, string name, int number, long reviewId, PullRequestReviewDismiss dismissMessage);
+
+ ///
+ /// Dismisses a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#dismiss-a-pull-request-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ /// The message indicating why the review was dismissed
+ IObservable Dismiss(long repositoryId, int number, long reviewId, PullRequestReviewDismiss dismissMessage);
+
+ ///
+ /// Lists comments for a single review
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ IObservable GetAllComments(string owner, string name, int number, long reviewId);
+
+ ///
+ /// Dismisses a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ IObservable GetAllComments(long repositoryId, int number, long reviewId);
+
+ ///
+ /// Lists comments for a single review
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ IObservable GetAllComments(string owner, string name, int number, long reviewId, ApiOptions options);
+
+ ///
+ /// Dismisses a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ IObservable GetAllComments(long repositoryId, int number, long reviewId, ApiOptions options);
+ }
+}
diff --git a/Octokit.Reactive/Clients/IObservablePullRequestsClient.cs b/Octokit.Reactive/Clients/IObservablePullRequestsClient.cs
index 9df36fd39b..5b7fb37128 100644
--- a/Octokit.Reactive/Clients/IObservablePullRequestsClient.cs
+++ b/Octokit.Reactive/Clients/IObservablePullRequestsClient.cs
@@ -17,6 +17,11 @@ public interface IObservablePullRequestsClient
[Obsolete("Please use IObservablePullRequestsClient.ReviewComment. This will be removed in a future version")]
IObservablePullRequestReviewCommentsClient Comment { get; }
+ ///
+ /// Client for managing reviews.
+ ///
+ IObservablePullRequestReviewsClient Review { get; }
+
///
/// Client for managing review comments.
///
diff --git a/Octokit.Reactive/Clients/ObservablePullRequestReviewsClient.cs b/Octokit.Reactive/Clients/ObservablePullRequestReviewsClient.cs
new file mode 100644
index 0000000000..3debbc94be
--- /dev/null
+++ b/Octokit.Reactive/Clients/ObservablePullRequestReviewsClient.cs
@@ -0,0 +1,292 @@
+using System;
+using System.Reactive;
+using System.Reactive.Threading.Tasks;
+using Octokit.Reactive.Internal;
+
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Pull Request Review API.
+ ///
+ ///
+ /// See the Review API documentation for more information.
+ ///
+ public class ObservablePullRequestReviewsClient : IObservablePullRequestReviewsClient
+ {
+ readonly IPullRequestReviewsClient _client;
+ readonly IConnection _connection;
+
+ public ObservablePullRequestReviewsClient(IGitHubClient client)
+ {
+ Ensure.ArgumentNotNull(client, nameof(client));
+
+ _client = client.PullRequest.Review;
+ _connection = client.Connection;
+ }
+
+ ///
+ /// Creates a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The Pull Request number
+ /// The review
+ public IObservable Create(string owner, string name, int number, PullRequestReviewCreate review)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name,nameof(name));
+ Ensure.ArgumentNotNull(review, nameof(review));
+ return _client.Create(owner, name, number, review).ToObservable();
+ }
+
+ ///
+ /// Creates a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review
+ /// The Id of the repository
+ /// The Pull Request number
+ /// The review
+ public IObservable Create(long repositoryId, int number, PullRequestReviewCreate review)
+ {
+ Ensure.ArgumentNotNull(review, nameof(review));
+
+ return _client.Create(repositoryId, number, review).ToObservable();
+ }
+
+ ///
+ /// Deletes a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ public IObservable Delete(string owner, string name, int number, long reviewId)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name,nameof(name));
+
+ return _client.Delete(owner, name, number, reviewId).ToObservable();
+ }
+
+ ///
+ /// Deletes a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ public IObservable Delete(long repositoryId, int number, long reviewId)
+ {
+ return _client.Delete(repositoryId, number, reviewId).ToObservable();
+ }
+
+ ///
+ /// Dismisses a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#dismiss-a-pull-request-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ /// The message indicating why the review was dismissed
+ public IObservable Dismiss(string owner, string name, int number, long reviewId, PullRequestReviewDismiss dismissMessage)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name,nameof(name));
+ Ensure.ArgumentNotNull(dismissMessage, nameof(dismissMessage));
+
+ return _client.Dismiss(owner, name, number, reviewId, dismissMessage).ToObservable();
+ }
+
+ ///
+ /// Dismisses a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#dismiss-a-pull-request-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ /// The message indicating why the review was dismissed
+ public IObservable Dismiss(long repositoryId, int number, long reviewId, PullRequestReviewDismiss dismissMessage)
+ {
+ Ensure.ArgumentNotNull(dismissMessage, nameof(dismissMessage));
+
+ return GetAll(repositoryId, number);
+ }
+
+ ///
+ /// Gets reviews for a specified pull request.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ public IObservable GetAll(string owner, string name, int number)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name,nameof(name));
+
+ return GetAll(owner, name, number, ApiOptions.None);
+ }
+
+ ///
+ /// Gets reviews for a specified pull request.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+ /// The Id of the repository
+ /// The pull request number
+ public IObservable GetAll(long repositoryId, int number)
+ {
+ return GetAll(repositoryId, number, ApiOptions.None);
+ }
+
+ ///
+ /// Gets reviews for a specified pull request.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// Options for changing the API response
+ public IObservable GetAll(string owner, string name, int number, ApiOptions options)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name,nameof(name));
+ Ensure.ArgumentNotNull(options, nameof(options));
+
+ return _connection.GetAndFlattenAllPages(ApiUrls.PullRequestReviews(owner, name, number), null, null, options);
+ }
+
+ ///
+ /// Gets reviews for a specified pull request.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+ /// The Id of the repository
+ /// The pull request number
+ /// Options for changing the API response
+ public IObservable GetAll(long repositoryId, int number, ApiOptions options)
+ {
+ Ensure.ArgumentNotNull(options, nameof(options));
+
+ return _connection.GetAndFlattenAllPages(ApiUrls.PullRequestReviews(repositoryId, number), null, null, options);
+ }
+
+ ///
+ /// Gets a single pull request review by ID.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-a-single-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ public IObservable Get(string owner, string name, int number, long reviewId)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name,nameof(name));
+
+ return _client.Get(owner, name, number, reviewId).ToObservable();
+ }
+
+ ///
+ /// Gets a single pull request review by ID.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-a-single-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ public IObservable Get(long repositoryId, int number, long reviewId)
+ {
+ return _client.Get(repositoryId, number, reviewId).ToObservable();
+ }
+
+ ///
+ /// Submits a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ /// The message and event being submitted for the review
+ public IObservable Submit(string owner, string name, int number, long reviewId, PullRequestReviewSubmit submitMessage)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name,nameof(name));
+ Ensure.ArgumentNotNull(submitMessage, nameof(submitMessage));
+
+ return _client.Submit(owner, name, number, reviewId, submitMessage).ToObservable();
+ }
+
+ ///
+ /// Submits a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ /// The message and event being submitted for the review
+ public IObservable Submit(long repositoryId, int number, long reviewId, PullRequestReviewSubmit submitMessage)
+ {
+ Ensure.ArgumentNotNull(submitMessage, nameof(submitMessage));
+
+ return _client.Submit(repositoryId, number, reviewId, submitMessage).ToObservable();
+ }
+
+ ///
+ /// Lists comments for a single review
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ public IObservable GetAllComments(string owner, string name, int number, long reviewId)
+ {
+ return GetAllComments(owner, name, number, reviewId, ApiOptions.None);
+ }
+
+ ///
+ /// Dismisses a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ public IObservable GetAllComments(long repositoryId, int number, long reviewId)
+ {
+ return GetAllComments(repositoryId, number, reviewId, ApiOptions.None);
+ }
+
+ ///
+ /// Lists comments for a single review
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+ /// The owner of the repository
+ /// The name of the repository
+ /// The pull request number
+ /// The pull request review number
+ public IObservable GetAllComments(string owner, string name, int number, long reviewId, ApiOptions options)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name,nameof(name));
+ Ensure.ArgumentNotNull(options, nameof(options));
+
+ return _connection.GetAndFlattenAllPages(ApiUrls.PullRequestReviewComments(owner, name, number, reviewId), options);
+ }
+
+ ///
+ /// Dismisses a pull request review.
+ ///
+ /// https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+ /// The Id of the repository
+ /// The pull request number
+ /// The pull request review number
+ public IObservable GetAllComments(long repositoryId, int number, long reviewId, ApiOptions options)
+ {
+ Ensure.ArgumentNotNull(options, nameof(options));
+
+ return _connection.GetAndFlattenAllPages(ApiUrls.PullRequestReviewComments(repositoryId, number, reviewId),options);
+ }
+ }
+}
diff --git a/Octokit.Reactive/Clients/ObservablePullRequestsClient.cs b/Octokit.Reactive/Clients/ObservablePullRequestsClient.cs
index 30a3496afe..7787544c49 100644
--- a/Octokit.Reactive/Clients/ObservablePullRequestsClient.cs
+++ b/Octokit.Reactive/Clients/ObservablePullRequestsClient.cs
@@ -8,7 +8,7 @@ namespace Octokit.Reactive
/// A client for GitHub's Pull Requests API.
///
///
- /// See the Pull Requests API documentation for more information.
+ /// See the Pull Requests API documentation for more information.
///
public class ObservablePullRequestsClient : IObservablePullRequestsClient
{
@@ -21,6 +21,11 @@ public class ObservablePullRequestsClient : IObservablePullRequestsClient
[Obsolete("Please use ObservablePullRequestsClient.ReviewComment. This will be removed in a future version")]
public IObservablePullRequestReviewCommentsClient Comment { get { return this.ReviewComment; } }
+ ///
+ /// Client for managing reviews.
+ ///
+ public IObservablePullRequestReviewsClient Review { get; private set; }
+
///
/// Client for managing review comments.
///
@@ -37,6 +42,7 @@ public ObservablePullRequestsClient(IGitHubClient client)
_client = client.Repository.PullRequest;
_connection = client.Connection;
+ Review = new ObservablePullRequestReviewsClient(client);
ReviewComment = new ObservablePullRequestReviewCommentsClient(client);
ReviewRequest = new ObservablePullRequestReviewRequestsClient(client);
}
diff --git a/Octokit.Reactive/ObservableGitHubClient.cs b/Octokit.Reactive/ObservableGitHubClient.cs
index e7d42acbd1..3745687f44 100644
--- a/Octokit.Reactive/ObservableGitHubClient.cs
+++ b/Octokit.Reactive/ObservableGitHubClient.cs
@@ -38,6 +38,7 @@ public ObservableGitHubClient(IGitHubClient gitHubClient)
Oauth = new ObservableOauthClient(gitHubClient);
Organization = new ObservableOrganizationsClient(gitHubClient);
PullRequest = new ObservablePullRequestsClient(gitHubClient);
+ PullRequestReview = new ObservablePullRequestReviewsClient(gitHubClient);
Repository = new ObservableRepositoriesClient(gitHubClient);
User = new ObservableUsersClient(gitHubClient);
Git = new ObservableGitDatabaseClient(gitHubClient);
@@ -60,6 +61,7 @@ public IConnection Connection
public IObservableOauthClient Oauth { get; private set; }
public IObservableOrganizationsClient Organization { get; private set; }
public IObservablePullRequestsClient PullRequest { get; private set; }
+ public IObservablePullRequestReviewsClient PullRequestReview { get; private set; }
public IObservableRepositoriesClient Repository { get; private set; }
public IObservableGistsClient Gist { get; private set; }
public IObservableUsersClient User { get; private set; }
diff --git a/Octokit.Tests.Integration/Clients/PullRequestReviewRequestsClientTests.cs b/Octokit.Tests.Integration/Clients/PullRequestReviewRequestsClientTests.cs
index 3b638cb2b2..9d8ed3324c 100644
--- a/Octokit.Tests.Integration/Clients/PullRequestReviewRequestsClientTests.cs
+++ b/Octokit.Tests.Integration/Clients/PullRequestReviewRequestsClientTests.cs
@@ -44,9 +44,9 @@ public class TheGetAllMethod : PullRequestReviewRequestClientTestsBase
[IntegrationTest]
public async Task GetsNoRequestsWhenNoneExist()
{
- var pullRequestId = await CreateTheWorld(_github, _context, createReviewRequests: false);
+ var number = await CreateTheWorld(_github, _context, createReviewRequests: false);
- var reviewRequests = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, pullRequestId);
+ var reviewRequests = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, number);
Assert.NotNull(reviewRequests);
Assert.Empty(reviewRequests);
@@ -55,9 +55,9 @@ public async Task GetsNoRequestsWhenNoneExist()
[IntegrationTest]
public async Task GetsNoRequestsWhenNoneExistWithRepositoryId()
{
- var pullRequestId = await CreateTheWorld(_github, _context, createReviewRequests: false);
+ var number = await CreateTheWorld(_github, _context, createReviewRequests: false);
- var reviewRequests = await _client.GetAll(_context.RepositoryId, pullRequestId);
+ var reviewRequests = await _client.GetAll(_context.RepositoryId, number);
Assert.NotNull(reviewRequests);
Assert.Empty(reviewRequests);
@@ -66,9 +66,9 @@ public async Task GetsNoRequestsWhenNoneExistWithRepositoryId()
[IntegrationTest]
public async Task GetsRequests()
{
- var pullRequestId = await CreateTheWorld(_github, _context);
+ var number = await CreateTheWorld(_github, _context);
- var reviewRequests = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, pullRequestId);
+ var reviewRequests = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, number);
Assert.Equal(_collaboratorLogins, reviewRequests.Select(rr => rr.Login));
}
@@ -76,9 +76,9 @@ public async Task GetsRequests()
[IntegrationTest]
public async Task GetsRequestsWithRepositoryId()
{
- var pullRequestId = await CreateTheWorld(_github, _context);
+ var number = await CreateTheWorld(_github, _context);
- var reviewRequests = await _client.GetAll(_context.RepositoryId, pullRequestId);
+ var reviewRequests = await _client.GetAll(_context.RepositoryId, number);
Assert.Equal(_collaboratorLogins, reviewRequests.Select(rr => rr.Login));
}
@@ -86,7 +86,7 @@ public async Task GetsRequestsWithRepositoryId()
[IntegrationTest]
public async Task ReturnsCorrectCountOfReviewRequestsWithStart()
{
- var pullRequestId = await CreateTheWorld(_github, _context);
+ var number = await CreateTheWorld(_github, _context);
var options = new ApiOptions
{
@@ -94,7 +94,7 @@ public async Task ReturnsCorrectCountOfReviewRequestsWithStart()
PageCount = 1,
StartPage = 2
};
- var reviewRequests = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, pullRequestId, options);
+ var reviewRequests = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, number, options);
Assert.Equal(1, reviewRequests.Count);
}
@@ -102,7 +102,7 @@ public async Task ReturnsCorrectCountOfReviewRequestsWithStart()
[IntegrationTest]
public async Task ReturnsCorrectCountOfReviewRequestsWithStartWithRepositoryId()
{
- var pullRequestId = await CreateTheWorld(_github, _context);
+ var number = await CreateTheWorld(_github, _context);
var options = new ApiOptions
{
@@ -110,7 +110,7 @@ public async Task ReturnsCorrectCountOfReviewRequestsWithStartWithRepositoryId()
PageCount = 2,
StartPage = 2
};
- var reviewRequests = await _client.GetAll(_context.RepositoryId, pullRequestId, options);
+ var reviewRequests = await _client.GetAll(_context.RepositoryId, number, options);
Assert.Equal(1, reviewRequests.Count);
}
@@ -118,14 +118,14 @@ public async Task ReturnsCorrectCountOfReviewRequestsWithStartWithRepositoryId()
[IntegrationTest]
public async Task ReturnsDistinctResultsBasedOnStartPage()
{
- var pullRequestId = await CreateTheWorld(_github, _context);
+ var number = await CreateTheWorld(_github, _context);
var startOptions = new ApiOptions
{
PageSize = 1,
PageCount = 1
};
- var firstPage = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, pullRequestId, startOptions);
+ var firstPage = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, number, startOptions);
var skipStartOptions = new ApiOptions
{
@@ -133,7 +133,7 @@ public async Task ReturnsDistinctResultsBasedOnStartPage()
PageCount = 1,
StartPage = 2
};
- var secondPage = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, pullRequestId, skipStartOptions);
+ var secondPage = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, number, skipStartOptions);
Assert.Equal(1, firstPage.Count);
Assert.Equal(1, secondPage.Count);
@@ -143,14 +143,14 @@ public async Task ReturnsDistinctResultsBasedOnStartPage()
[IntegrationTest]
public async Task ReturnsDistinctResultsBasedOnStartPageWithRepositoryId()
{
- var pullRequestId = await CreateTheWorld(_github, _context);
+ var number = await CreateTheWorld(_github, _context);
var startOptions = new ApiOptions
{
PageSize = 1,
PageCount = 1
};
- var firstPage = await _client.GetAll(_context.RepositoryId, pullRequestId, startOptions);
+ var firstPage = await _client.GetAll(_context.RepositoryId, number, startOptions);
var skipStartOptions = new ApiOptions
{
@@ -158,7 +158,7 @@ public async Task ReturnsDistinctResultsBasedOnStartPageWithRepositoryId()
PageCount = 1,
StartPage = 2
};
- var secondPage = await _client.GetAll(_context.RepositoryId, pullRequestId, skipStartOptions);
+ var secondPage = await _client.GetAll(_context.RepositoryId, number, skipStartOptions);
Assert.Equal(1, firstPage.Count);
Assert.Equal(1, secondPage.Count);
@@ -171,12 +171,12 @@ public class TheDeleteMethod : PullRequestReviewRequestClientTestsBase
[IntegrationTest]
public async Task DeletesRequests()
{
- var pullRequestId = await CreateTheWorld(_github, _context);
+ var number = await CreateTheWorld(_github, _context);
- var reviewRequestsBeforeDelete = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, pullRequestId);
+ var reviewRequestsBeforeDelete = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, number);
var reviewRequestToCreate = new PullRequestReviewRequest(_collaboratorLogins);
- await _client.Delete(_context.RepositoryOwner, _context.RepositoryName, pullRequestId, reviewRequestToCreate);
- var reviewRequestsAfterDelete = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, pullRequestId);
+ await _client.Delete(_context.RepositoryOwner, _context.RepositoryName, number, reviewRequestToCreate);
+ var reviewRequestsAfterDelete = await _client.GetAll(_context.RepositoryOwner, _context.RepositoryName, number);
Assert.NotEmpty(reviewRequestsBeforeDelete);
Assert.Empty(reviewRequestsAfterDelete);
@@ -185,12 +185,12 @@ public async Task DeletesRequests()
[IntegrationTest]
public async Task DeletesRequestsWithRepositoryId()
{
- var pullRequestId = await CreateTheWorld(_github, _context);
+ var number = await CreateTheWorld(_github, _context);
- var reviewRequestsBeforeDelete = await _client.GetAll(_context.RepositoryId, pullRequestId);
+ var reviewRequestsBeforeDelete = await _client.GetAll(_context.RepositoryId, number);
var reviewRequestToCreate = new PullRequestReviewRequest(_collaboratorLogins);
- await _client.Delete(_context.RepositoryId, pullRequestId, reviewRequestToCreate);
- var reviewRequestsAfterDelete = await _client.GetAll(_context.RepositoryId, pullRequestId);
+ await _client.Delete(_context.RepositoryId, number, reviewRequestToCreate);
+ var reviewRequestsAfterDelete = await _client.GetAll(_context.RepositoryId, number);
Assert.NotEmpty(reviewRequestsBeforeDelete);
Assert.Empty(reviewRequestsAfterDelete);
@@ -202,10 +202,10 @@ public class TheCreateMethod : PullRequestReviewRequestClientTestsBase, IDisposa
[IntegrationTest]
public async Task CreatesRequests()
{
- var pullRequestId = await CreateTheWorld(_github, _context, createReviewRequests: false);
+ var number = await CreateTheWorld(_github, _context, createReviewRequests: false);
var reviewRequestToCreate = new PullRequestReviewRequest(_collaboratorLogins);
- var pr = await _client.Create(_context.RepositoryOwner, _context.RepositoryName, pullRequestId, reviewRequestToCreate);
+ var pr = await _client.Create(_context.RepositoryOwner, _context.RepositoryName, number, reviewRequestToCreate);
Assert.Equal(_collaboratorLogins.ToList(), pr.RequestedReviewers.Select(rr => rr.Login));
}
@@ -213,10 +213,10 @@ public async Task CreatesRequests()
[IntegrationTest]
public async Task CreatesRequestsWithRepositoryId()
{
- var pullRequestId = await CreateTheWorld(_github, _context, createReviewRequests: false);
+ var number = await CreateTheWorld(_github, _context, createReviewRequests: false);
var reviewRequestToCreate = new PullRequestReviewRequest(_collaboratorLogins);
- var pr = await _client.Create(_context.RepositoryId, pullRequestId, reviewRequestToCreate);
+ var pr = await _client.Create(_context.RepositoryId, number, reviewRequestToCreate);
Assert.Equal(_collaboratorLogins.ToList(), pr.RequestedReviewers.Select(rr => rr.Login));
}
diff --git a/Octokit.Tests.Integration/Clients/PullRequestReviewsClientTests.cs b/Octokit.Tests.Integration/Clients/PullRequestReviewsClientTests.cs
new file mode 100644
index 0000000000..8505687cbd
--- /dev/null
+++ b/Octokit.Tests.Integration/Clients/PullRequestReviewsClientTests.cs
@@ -0,0 +1,691 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Octokit;
+using Octokit.Tests.Integration;
+using Octokit.Tests.Integration.Helpers;
+using Xunit;
+
+public class PullRequestReviewsClientTests
+{
+ public class TheGetAllMethod
+ {
+ private readonly IGitHubClient _github;
+
+ public TheGetAllMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+ }
+
+ [IntegrationTest]
+ public async Task GetsAllReviews()
+ {
+ var reviews = await _github.PullRequest.Review.GetAll("octokit", "octokit.net", 1648);
+
+ Assert.NotNull(reviews);
+ Assert.NotEmpty(reviews);
+ Assert.True(reviews.Count > 1);
+ Assert.False(string.IsNullOrEmpty(reviews[0].Body));
+ Assert.False(string.IsNullOrEmpty(reviews[0].CommitId));
+ Assert.False(string.IsNullOrEmpty(reviews[0].User.Login));
+ }
+
+ [IntegrationTest]
+ public async Task ReturnsCorrectCountOfReviewsWithoutStart()
+ {
+ var options = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1
+ };
+
+ var reviews = await _github.PullRequest.Review.GetAll("octokit", "octokit.net", 1648, options);
+
+ Assert.Equal(1, reviews.Count);
+ }
+
+ [IntegrationTest]
+ public async Task ReturnsCorrectCountOfReviewsWithStart()
+ {
+ var options = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1,
+ StartPage = 1
+ };
+
+ var reviews = await _github.PullRequest.Review.GetAll("octokit", "octokit.net", 1648, options);
+
+ Assert.Equal(1, reviews.Count);
+ }
+
+ [IntegrationTest]
+ public async Task ReturnsDistinctReviewsBasedOnStartPage()
+ {
+ var startOptions = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1,
+ StartPage = 1
+ };
+
+ var firstPage = await _github.PullRequest.Review.GetAll("octokit", "octokit.net", 1648, startOptions);
+
+ var skipStartOptions = new ApiOptions
+ {
+ PageSize = 1,
+ PageCount = 1,
+ StartPage = 2
+ };
+
+ var secondPage = await _github.PullRequest.Review.GetAll("octokit", "octokit.net", 1648, skipStartOptions);
+
+ Assert.Equal(1, firstPage.Count);
+ Assert.Equal(1, secondPage.Count);
+ Assert.NotEqual(firstPage.First().Id, secondPage.First().Id);
+ }
+ }
+
+ public class TheGetMethod
+ {
+ private readonly IGitHubClient _github;
+
+ public TheGetMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+ }
+
+ [IntegrationTest]
+ public async Task GetsReview()
+ {
+ var review = await _github.PullRequest.Review.Get("octokit", "octokit.net", 1648, 54646850);
+
+ Assert.NotNull(review);
+ Assert.False(string.IsNullOrEmpty(review.Body));
+ Assert.False(string.IsNullOrEmpty(review.CommitId));
+ Assert.False(string.IsNullOrEmpty(review.User.Login));
+ }
+ }
+
+ public class TheCreateMethod
+ {
+ private readonly IGitHubClient _github;
+ private readonly IPullRequestReviewsClient _client;
+
+ private readonly IGitHubClient _github2;
+
+ public TheCreateMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+ _client = _github.PullRequest.Review;
+
+ _github2 = Helper.GetAuthenticatedClient(true);
+ }
+
+ [DualAccountTest]
+ public async Task CanCreatePendingReview()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+
+ var body = "A review comment message";
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = pullRequest.Head.Sha,
+ Body = body,
+ Comments = new List
+ {
+ new DraftPullRequestReviewComment("comment 1", "README.md", 1),
+ new DraftPullRequestReviewComment("comment 2", "README.md", 2)
+ }
+ };
+
+ var createdReview = await _client.Create(context.RepositoryOwner, context.RepositoryName, pullRequest.Number, review);
+
+ Assert.NotNull(createdReview);
+ Assert.Equal(body, createdReview.Body);
+ Assert.Equal(PullRequestReviewState.Pending, createdReview.State);
+ Assert.Equal(pullRequest.Head.Sha, createdReview.CommitId);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanCreatePendingReviewWithRepositoryId()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+
+ const string body = "A review comment message";
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = pullRequest.Head.Sha,
+ Body = body,
+ Comments = new List
+ {
+ new DraftPullRequestReviewComment("comment 1", "README.md", 1),
+ new DraftPullRequestReviewComment("comment 2", "README.md", 2)
+ }
+ };
+
+ var createdReview = await _client.Create(context.RepositoryId, pullRequest.Number, review);
+
+ Assert.NotNull(createdReview);
+ Assert.Equal(body, createdReview.Body);
+ Assert.Equal(PullRequestReviewState.Pending, createdReview.State);
+ Assert.Equal(pullRequest.Head.Sha, createdReview.CommitId);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanCreateCommentedReview()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+
+ var body = "A review comment message";
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = pullRequest.Head.Sha,
+ Body = body,
+ Event = PullRequestReviewEvent.Comment,
+ Comments = new List
+ {
+ new DraftPullRequestReviewComment("comment 1", "README.md", 1),
+ new DraftPullRequestReviewComment("comment 2", "README.md", 2)
+ }
+ };
+
+ var createdReview = await _client.Create(context.RepositoryOwner, context.RepositoryName, pullRequest.Number, review);
+
+ Assert.NotNull(createdReview);
+ Assert.Equal(body, createdReview.Body);
+ Assert.Equal(PullRequestReviewState.Commented, createdReview.State);
+ Assert.Equal(pullRequest.Head.Sha, createdReview.CommitId);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanCreateCommentedReviewWithRepositoryId()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+
+ const string body = "A review comment message";
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = pullRequest.Head.Sha,
+ Body = body,
+ Event = PullRequestReviewEvent.Comment,
+ Comments = new List
+ {
+ new DraftPullRequestReviewComment("comment 1", "README.md", 1),
+ new DraftPullRequestReviewComment("comment 2", "README.md", 2)
+ }
+ };
+
+ var createdReview = await _client.Create(context.RepositoryId, pullRequest.Number, review);
+
+ Assert.NotNull(createdReview);
+ Assert.Equal(body, createdReview.Body);
+ Assert.Equal(PullRequestReviewState.Commented, createdReview.State);
+ Assert.Equal(pullRequest.Head.Sha, createdReview.CommitId);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanCreateChangesRequestedReview()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+
+ var body = "A review comment message";
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = pullRequest.Head.Sha,
+ Body = body,
+ Event = PullRequestReviewEvent.RequestChanges,
+ Comments = new List
+ {
+ new DraftPullRequestReviewComment("comment 1", "README.md", 1),
+ new DraftPullRequestReviewComment("comment 2", "README.md", 2)
+ }
+ };
+
+ var createdReview = await _client.Create(context.RepositoryOwner, context.RepositoryName, pullRequest.Number, review);
+
+ Assert.NotNull(createdReview);
+ Assert.Equal(body, createdReview.Body);
+ Assert.Equal(PullRequestReviewState.ChangesRequested, createdReview.State);
+ Assert.Equal(pullRequest.Head.Sha, createdReview.CommitId);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanCreateChangesRequestedReviewWithRepositoryId()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+
+ const string body = "A review comment message";
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = pullRequest.Head.Sha,
+ Body = body,
+ Event = PullRequestReviewEvent.RequestChanges,
+ Comments = new List
+ {
+ new DraftPullRequestReviewComment("comment 1", "README.md", 1),
+ new DraftPullRequestReviewComment("comment 2", "README.md", 2)
+ }
+ };
+
+ var createdReview = await _client.Create(context.RepositoryId, pullRequest.Number, review);
+
+ Assert.NotNull(createdReview);
+ Assert.Equal(body, createdReview.Body);
+ Assert.Equal(PullRequestReviewState.ChangesRequested, createdReview.State);
+ Assert.Equal(pullRequest.Head.Sha, createdReview.CommitId);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanCreateApprovedReview()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+
+ var body = "A review comment message";
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = pullRequest.Head.Sha,
+ Body = body,
+ Event = PullRequestReviewEvent.Approve,
+ Comments = new List
+ {
+ new DraftPullRequestReviewComment("comment 1", "README.md", 1),
+ new DraftPullRequestReviewComment("comment 2", "README.md", 2)
+ }
+ };
+
+ var createdReview = await _client.Create(context.RepositoryOwner, context.RepositoryName, pullRequest.Number, review);
+
+ Assert.NotNull(createdReview);
+ Assert.Equal(body, createdReview.Body);
+ Assert.Equal(PullRequestReviewState.Approved, createdReview.State);
+ Assert.Equal(pullRequest.Head.Sha, createdReview.CommitId);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanCreateApprovedReviewWithRepositoryId()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+
+ const string body = "A review comment message";
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = pullRequest.Head.Sha,
+ Body = body,
+ Event = PullRequestReviewEvent.Approve,
+ Comments = new List
+ {
+ new DraftPullRequestReviewComment("comment 1", "README.md", 1),
+ new DraftPullRequestReviewComment("comment 2", "README.md", 2)
+ }
+ };
+
+ var createdReview = await _client.Create(context.RepositoryId, pullRequest.Number, review);
+
+ Assert.NotNull(createdReview);
+ Assert.Equal(body, createdReview.Body);
+ Assert.Equal(PullRequestReviewState.Approved, createdReview.State);
+ Assert.Equal(pullRequest.Head.Sha, createdReview.CommitId);
+ }
+ }
+ }
+
+ public class TheDeleteMethod
+ {
+ private readonly IGitHubClient _github;
+ private readonly IPullRequestReviewsClient _client;
+
+ private readonly IGitHubClient _github2;
+
+ public TheDeleteMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+ _client = _github.PullRequest.Review;
+
+ _github2 = Helper.GetAuthenticatedClient(true);
+ }
+
+ [DualAccountTest]
+ public async Task CanDeleteReview()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review");
+
+ await _client.Delete(context.RepositoryOwner, context.RepositoryName, pullRequest.Number, createdReview.Id);
+
+ var retrievedReviews = await _client.GetAll(context.RepositoryOwner, context.RepositoryName, pullRequest.Number);
+
+ Assert.False(retrievedReviews.Any(x => x.Id == createdReview.Id));
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanDeleteReviewWithRepositoryId()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review");
+
+ await _client.Delete(context.RepositoryId, pullRequest.Number, createdReview.Id);
+
+ var retrievedReviews = await _client.GetAll(context.RepositoryId, pullRequest.Number);
+
+ Assert.False(retrievedReviews.Any(x => x.Id == createdReview.Id));
+ }
+ }
+ }
+
+ public class TheDismissMethod
+ {
+ private readonly IGitHubClient _github;
+ private readonly IPullRequestReviewsClient _client;
+
+ private readonly IGitHubClient _github2;
+
+ public TheDismissMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+ _client = _github.PullRequest.Review;
+
+ _github2 = Helper.GetAuthenticatedClient(true);
+ }
+
+ [DualAccountTest]
+ public async Task CanDismissReview()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review", PullRequestReviewEvent.RequestChanges);
+
+ var dismissedReview = await _client.Dismiss(context.RepositoryOwner, context.RepositoryName, pullRequest.Number, createdReview.Id, new PullRequestReviewDismiss { Message = "No soup for you!" });
+
+ Assert.Equal(PullRequestReviewState.Dismissed, dismissedReview.State);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanDismissReviewWithRepositoryId()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review", PullRequestReviewEvent.RequestChanges);
+
+ var dismissedReview = await _client.Dismiss(context.RepositoryId, pullRequest.Number, createdReview.Id, new PullRequestReviewDismiss { Message = "No soup for you!" });
+
+ Assert.Equal(PullRequestReviewState.Dismissed, dismissedReview.State);
+ }
+ }
+ }
+
+ public class TheGetAllCommentsMethod
+ {
+ private readonly IGitHubClient _github;
+
+ public TheGetAllCommentsMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+ }
+
+ [IntegrationTest]
+ public async Task GetsAllComments()
+ {
+ var comments = await _github.PullRequest.Review.GetAllComments("octokit", "octokit.net", 1648, 54646850);
+
+ Assert.NotNull(comments);
+ Assert.NotEmpty(comments);
+ Assert.True(comments.Count > 1);
+ foreach (var comment in comments)
+ {
+ Assert.False(string.IsNullOrEmpty(comment.Body));
+ Assert.False(string.IsNullOrEmpty(comment.CommitId));
+ Assert.False(string.IsNullOrEmpty(comment.User.Login));
+ }
+ }
+
+ [IntegrationTest]
+ public async Task ReturnsCorrectCountOfCommentsWithoutStart()
+ {
+ var options = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1
+ };
+
+ var comments = await _github.PullRequest.Review.GetAllComments("octokit", "octokit.net", 1648, 54646850, options);
+
+ Assert.Equal(1, comments.Count);
+ }
+
+ [IntegrationTest]
+ public async Task ReturnsCorrectCountOfCommentsWithStart()
+ {
+ var options = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1,
+ StartPage = 1
+ };
+
+ var comments = await _github.PullRequest.Review.GetAllComments("octokit", "octokit.net", 1648, 54646850, options);
+
+ Assert.Equal(1, comments.Count);
+ }
+
+ [IntegrationTest]
+ public async Task ReturnsDistinctCommentsBasedOnStartPage()
+ {
+ var startOptions = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1,
+ StartPage = 1
+ };
+
+ var firstPage = await _github.PullRequest.Review.GetAllComments("octokit", "octokit.net", 1648, 54646850, startOptions);
+
+ var skipStartOptions = new ApiOptions
+ {
+ PageSize = 1,
+ PageCount = 1,
+ StartPage = 2
+ };
+
+ var secondPage = await _github.PullRequest.Review.GetAllComments("octokit", "octokit.net", 1648, 54646850, skipStartOptions);
+
+ Assert.Equal(1, firstPage.Count);
+ Assert.Equal(1, secondPage.Count);
+ Assert.NotEqual(firstPage.First().Id, secondPage.First().Id);
+ }
+ }
+
+ public class TheSubmitMethod
+ {
+ private readonly IGitHubClient _github;
+ private readonly IPullRequestReviewsClient _client;
+
+ private readonly IGitHubClient _github2;
+
+ public TheSubmitMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+ _client = _github.PullRequest.Review;
+
+ _github2 = Helper.GetAuthenticatedClient(true);
+ }
+
+ [DualAccountTest]
+ public async Task CanSubmitCommentedReview()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review");
+
+ var submitMessage = new PullRequestReviewSubmit
+ {
+ Body = "Roger roger!",
+ Event = PullRequestReviewEvent.Comment
+ };
+ var submittedReview = await _client.Submit(context.RepositoryOwner, context.RepositoryName, pullRequest.Number, createdReview.Id, submitMessage);
+
+ Assert.Equal("Roger roger!", submittedReview.Body);
+ Assert.Equal(PullRequestReviewState.Commented, submittedReview.State);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanSubmitCommentedReviewWithRepositoryId()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review");
+
+ var submitMessage = new PullRequestReviewSubmit
+ {
+ Body = "Roger roger!",
+ Event = PullRequestReviewEvent.Comment
+ };
+ var submittedReview = await _client.Submit(context.RepositoryId, pullRequest.Number, createdReview.Id, submitMessage);
+
+ Assert.Equal("Roger roger!", submittedReview.Body);
+ Assert.Equal(PullRequestReviewState.Commented, submittedReview.State);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanSubmitChangesRequestedReview()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review");
+
+ var submitMessage = new PullRequestReviewSubmit
+ {
+ Body = "Roger roger!",
+ Event = PullRequestReviewEvent.RequestChanges
+ };
+ var submittedReview = await _client.Submit(context.RepositoryOwner, context.RepositoryName, pullRequest.Number, createdReview.Id, submitMessage);
+
+ Assert.Equal("Roger roger!", submittedReview.Body);
+ Assert.Equal(PullRequestReviewState.ChangesRequested, submittedReview.State);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanSubmitChangesRequestedReviewWithRepositoryId()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review");
+
+ var submitMessage = new PullRequestReviewSubmit
+ {
+ Body = "Roger roger!",
+ Event = PullRequestReviewEvent.RequestChanges
+ };
+ var submittedReview = await _client.Submit(context.RepositoryId, pullRequest.Number, createdReview.Id, submitMessage);
+
+ Assert.Equal("Roger roger!", submittedReview.Body);
+ Assert.Equal(PullRequestReviewState.ChangesRequested, submittedReview.State);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanSubmitApprovedReview()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review");
+
+ var submitMessage = new PullRequestReviewSubmit
+ {
+ Body = "Roger roger!",
+ Event = PullRequestReviewEvent.Approve
+ };
+ var submittedReview = await _client.Submit(context.RepositoryOwner, context.RepositoryName, pullRequest.Number, createdReview.Id, submitMessage);
+
+ Assert.Equal("Roger roger!", submittedReview.Body);
+ Assert.Equal(PullRequestReviewState.Approved, submittedReview.State);
+ }
+ }
+
+ [DualAccountTest]
+ public async Task CanSubmitApprovedReviewWithRepositoryId()
+ {
+ using (var context = await _github.CreateRepositoryContext("test-repo"))
+ {
+ await _github.CreateTheWorld(context.Repository);
+ var pullRequest = await _github2.CreatePullRequest(context.Repository);
+ var createdReview = await _github.CreatePullRequestReview(context.Repository, pullRequest.Number, "A pending review");
+
+ var submitMessage = new PullRequestReviewSubmit
+ {
+ Body = "Roger roger!",
+ Event = PullRequestReviewEvent.Approve
+ };
+ var submittedReview = await _client.Submit(context.RepositoryId, pullRequest.Number, createdReview.Id, submitMessage);
+
+ Assert.Equal("Roger roger!", submittedReview.Body);
+ Assert.Equal(PullRequestReviewState.Approved, submittedReview.State);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Octokit.Tests.Integration/Helper.cs b/Octokit.Tests.Integration/Helper.cs
index 8682f78769..a18fabca8c 100644
--- a/Octokit.Tests.Integration/Helper.cs
+++ b/Octokit.Tests.Integration/Helper.cs
@@ -27,6 +27,18 @@ public static class Helper
return new Credentials(githubUsername, githubPassword);
});
+ static readonly Lazy _credentialsSecondUserThunk = new Lazy(() =>
+ {
+ var githubUsername = Environment.GetEnvironmentVariable("OCTOKIT_GITHUBUSERNAME_2");
+
+ var githubPassword = Environment.GetEnvironmentVariable("OCTOKIT_GITHUBPASSWORD_2");
+
+ if (githubUsername == null || githubPassword == null)
+ return null;
+
+ return new Credentials(githubUsername, githubPassword);
+ });
+
static readonly Lazy _oauthApplicationCredentials = new Lazy(() =>
{
var applicationClientId = ClientId;
@@ -78,6 +90,8 @@ static Helper()
///
public static Credentials Credentials { get { return _credentialsThunk.Value; } }
+ public static Credentials CredentialsSecondUser { get { return _credentialsSecondUserThunk.Value; } }
+
public static Credentials ApplicationCredentials { get { return _oauthApplicationCredentials.Value; } }
public static Credentials BasicAuthCredentials { get { return _basicAuthCredentials.Value; } }
@@ -193,11 +207,11 @@ public static Stream LoadFixture(string fileName)
return stream;
}
- public static IGitHubClient GetAuthenticatedClient()
+ public static IGitHubClient GetAuthenticatedClient(bool useSecondUser = false)
{
return new GitHubClient(new ProductHeaderValue("OctokitTests"), TargetUrl)
{
- Credentials = Credentials
+ Credentials = useSecondUser ? CredentialsSecondUser : Credentials
};
}
diff --git a/Octokit.Tests.Integration/Helpers/DualAccountTestAttribute.cs b/Octokit.Tests.Integration/Helpers/DualAccountTestAttribute.cs
new file mode 100644
index 0000000000..9d93604da5
--- /dev/null
+++ b/Octokit.Tests.Integration/Helpers/DualAccountTestAttribute.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+using Xunit.Abstractions;
+using Xunit.Sdk;
+
+namespace Octokit.Tests.Integration
+{
+ public class DualAccountTestDiscoverer : IXunitTestCaseDiscoverer
+ {
+ readonly IMessageSink diagnosticMessageSink;
+
+ public DualAccountTestDiscoverer(IMessageSink diagnosticMessageSink)
+ {
+ this.diagnosticMessageSink = diagnosticMessageSink;
+ }
+
+ public IEnumerable Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
+ {
+ if (Helper.CredentialsSecondUser == null)
+ {
+ return Enumerable.Empty();
+ }
+
+ return new[] { new XunitTestCase(diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod) };
+ }
+ }
+
+ [XunitTestCaseDiscoverer("Octokit.Tests.Integration.DualAccountTestDiscoverer", "Octokit.Tests.Integration")]
+ public class DualAccountTestAttribute : FactAttribute
+ {
+ }
+}
diff --git a/Octokit.Tests.Integration/Helpers/RepositorySetupHelper.cs b/Octokit.Tests.Integration/Helpers/RepositorySetupHelper.cs
index 682353c299..3bfa7f4d02 100644
--- a/Octokit.Tests.Integration/Helpers/RepositorySetupHelper.cs
+++ b/Octokit.Tests.Integration/Helpers/RepositorySetupHelper.cs
@@ -54,11 +54,34 @@ public static async Task CreateTheWorld(this IGitHubClient client, Re
await client.Git.Reference.Update(repository.Owner.Login, repository.Name, "heads/master", new ReferenceUpdate(newMaster.Sha));
// create new commit for feature branch
- var featureBranchTree = await client.CreateTree(repository, new Dictionary { { "README.md", "I am overwriting this blob with something new" } });
+ var featureBranchTree = await client.CreateTree(repository, new Dictionary { { "README.md", "I am overwriting this blob with something new\nand a second line too" } });
var featureBranchCommit = await client.CreateCommit(repository, "this is the commit to merge into the pull request", featureBranchTree.Sha, newMaster.Sha);
// create branch
return await client.Git.Reference.Create(repository.Owner.Login, repository.Name, new NewReference("refs/heads/my-branch", featureBranchCommit.Sha));
}
+
+ public static async Task CreatePullRequest(this IGitHubClient client, Repository repository, string branch = "my-branch")
+ {
+ var pullRequest = new NewPullRequest("Nice title for the pull request", branch, "master");
+ var createdPullRequest = await client.PullRequest.Create(repository.Owner.Login, repository.Name, pullRequest);
+
+ return createdPullRequest;
+ }
+
+ public static async Task CreatePullRequestReview(this IGitHubClient client, Repository repository, int number, string body, PullRequestReviewEvent? @event = null, string commitId = null, List comments = null)
+ {
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = commitId,
+ Body = body,
+ Event = @event,
+ Comments = comments
+ };
+
+ var createdReview = await client.PullRequest.Review.Create(repository.Owner.Login, repository.Name, number, review);
+
+ return createdReview;
+ }
}
}
diff --git a/Octokit.Tests/Clients/PullRequestReviewsClientTests.cs b/Octokit.Tests/Clients/PullRequestReviewsClientTests.cs
new file mode 100644
index 0000000000..ad82d10734
--- /dev/null
+++ b/Octokit.Tests/Clients/PullRequestReviewsClientTests.cs
@@ -0,0 +1,464 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using NSubstitute;
+using Octokit;
+using Octokit.Tests;
+using Xunit;
+
+public class PullRequestReviewsClientTests
+{
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new PullRequestReviewCommentsClient(null));
+ }
+
+ [Fact]
+ public void PullRequestReviewCreateEnsuresArgumentsValue()
+ {
+ string body = "body";
+ string path = "path";
+ PullRequestReviewEvent evt = PullRequestReviewEvent.Approve;
+ int position = 1;
+
+ var comment = new DraftPullRequestReviewComment(body, path, position);
+
+ var review = new PullRequestReviewCreate()
+ {
+ Body = body,
+ Event = evt
+ };
+
+ review.Comments.Add(comment);
+
+
+ Assert.Equal(body, review.Body);
+ Assert.Equal(evt, review.Event);
+ Assert.NotEmpty(review.Comments);
+ }
+ }
+
+ public class TheGetAllMethod
+ {
+ [Fact]
+ public async Task RequestsCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ await client.GetAll("owner", "name", 7);
+
+ connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/owner/name/pulls/7/reviews"), null, Args.ApiOptions);
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlWithRepositoryId()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ await client.GetAll(1, 7);
+
+ connection.Received().GetAll(
+ Arg.Is(u => u.ToString() == "repositories/1/pulls/7/reviews"), Args.ApiOptions);
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlWithApiOptions()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var options = new ApiOptions
+ {
+ StartPage = 1,
+ PageCount = 1,
+ PageSize = 1
+ };
+
+ await client.GetAll("owner", "name", 7, options);
+
+ connection.Received().GetAll(
+ Arg.Is(u => u.ToString() == "repos/owner/name/pulls/7/reviews"), null, options);
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlWithApiOptionsWithRepositoryId()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var options = new ApiOptions
+ {
+ StartPage = 1,
+ PageCount = 1,
+ PageSize = 1
+ };
+
+ await client.GetAll(1, 7, options);
+
+ connection.Received().GetAll(
+ Arg.Is(u => u.ToString() == "repositories/1/pulls/7/reviews"), options);
+ }
+
+ [Fact]
+ public async Task EnsuresNotNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ await Assert.ThrowsAsync(() => client.GetAll(null, "name", 1));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", null, 1));
+
+ await Assert.ThrowsAsync(() => client.GetAll(null, "name", 1, ApiOptions.None));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", null, 1, ApiOptions.None));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", "name", 1, null));
+
+ await Assert.ThrowsAsync(() => client.GetAll(1, 1, null));
+
+ await Assert.ThrowsAsync(() => client.GetAll("", "name", 1));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", "", 1));
+
+ await Assert.ThrowsAsync(() => client.GetAll("", "name", 1, ApiOptions.None));
+ await Assert.ThrowsAsync(() => client.GetAll("owner", "", 1, ApiOptions.None));
+ }
+ }
+
+ public class TheGetMethod
+ {
+ [Fact]
+ public void RequestsCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ client.Get("owner", "name", 53, 2);
+
+ connection.Received().Get(
+ Arg.Is(u => u.ToString() == "repos/owner/name/pulls/53/reviews/2"));
+ }
+
+ [Fact]
+ public void RequestsCorrectUrlWithRepositoryId()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ client.Get(1, 53, 2);
+
+ connection.Received().Get(Arg.Is(u => u.ToString() == "repositories/1/pulls/53/reviews/2"));
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var client = new PullRequestReviewsClient(Substitute.For());
+
+ await Assert.ThrowsAsync(() => client.Get(null, "name", 1, 1));
+ await Assert.ThrowsAsync(() => client.Get("owner", null, 1, 1));
+
+ await Assert.ThrowsAsync(() => client.Get("", "name", 1, 1));
+ await Assert.ThrowsAsync(() => client.Get("owner", "", 1, 1));
+ }
+ }
+
+ public class TheCreateMethod
+ {
+ [Fact]
+ public void PostsToCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var comment = new DraftPullRequestReviewComment("Comment content", "file.css", 7);
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = "commit",
+ Body = "body",
+ Event = PullRequestReviewEvent.Approve
+ };
+ review.Comments.Add(comment);
+
+ client.Create("fakeOwner", "fakeRepoName", 13, review);
+
+ connection.Received().Post(Arg.Is(u => u.ToString() == "repos/fakeOwner/fakeRepoName/pulls/13/reviews"),
+ review, null, null);
+ }
+
+ [Fact]
+ public void PostsToCorrectUrlWithRepositoryId()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var comment = new DraftPullRequestReviewComment("Comment content", "file.css", 7);
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = "commit",
+ Body = "body",
+ Event = PullRequestReviewEvent.Approve
+ };
+ review.Comments.Add(comment);
+
+ client.Create(1, 13, review);
+
+ connection.Received().Post(Arg.Is(u => u.ToString() == "repositories/1/pulls/13/reviews"),
+ review, null, null);
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ string body = "Comment content";
+ string path = "file.css";
+ int position = 7;
+
+ var comment = new DraftPullRequestReviewComment(body, path, position);
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = "commit",
+ Body = "body",
+ Event = PullRequestReviewEvent.Approve
+ };
+
+ review.Comments.Add(comment);
+
+ await Assert.ThrowsAsync(() => client.Create(null, "fakeRepoName", 1, review));
+ await Assert.ThrowsAsync(() => client.Create("fakeOwner", null, 1, review));
+ await Assert.ThrowsAsync(() => client.Create("fakeOwner", "fakeRepoName", 1, null));
+
+ await Assert.ThrowsAsync(() => client.Create("", "fakeRepoName", 1, review));
+ await Assert.ThrowsAsync(() => client.Create("fakeOwner", "", 1, review));
+ }
+ }
+
+ public class TheDeleteMethod
+ {
+ [Fact]
+ public async Task PostsToCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ await client.Delete("owner", "name", 13, 13);
+
+ connection.Received().Delete(Arg.Is(u => u.ToString() == "repos/owner/name/pulls/13/reviews/13"));
+ }
+
+ [Fact]
+ public async Task PostsToCorrectUrlWithRepositoryId()
+ {
+
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ await client.Delete(1, 13, 13);
+
+ connection.Received().Delete(Arg.Is(u => u.ToString() == "repositories/1/pulls/13/reviews/13"));
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ await Assert.ThrowsAsync(() => client.Delete(null, "name", 1, 1));
+ await Assert.ThrowsAsync(() => client.Delete("owner", null, 1, 1));
+
+ await Assert.ThrowsAsync(() => client.Delete("", "name", 1, 1));
+ await Assert.ThrowsAsync(() => client.Delete("owner", "", 1, 1));
+ }
+ }
+
+ public class TheDismissMethod
+ {
+ [Fact]
+ public async Task PostsToCorrectUrl()
+ {
+
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var dismissMessage = new PullRequestReviewDismiss()
+ {
+ Message = "test message"
+ };
+ await client.Dismiss("owner", "name", 13, 13, dismissMessage);
+
+ connection.Received().Put(Arg.Is(u => u.ToString() == "repos/owner/name/pulls/13/reviews/13/dismissals"), dismissMessage);
+ }
+
+ [Fact]
+ public async Task PostsToCorrectUrlWithRepositoryId()
+ {
+
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var dismissMessage = new PullRequestReviewDismiss()
+ {
+ Message = "test message"
+ };
+ await client.Dismiss(1, 13, 13, dismissMessage);
+
+ connection.Received().Put(Arg.Is(u => u.ToString() == "repositories/1/pulls/13/reviews/13/dismissals"), dismissMessage);
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var dismissMessage = new PullRequestReviewDismiss()
+ {
+ Message = "test message"
+ };
+
+ await Assert.ThrowsAsync(() => client.Dismiss(null, "name", 1, 1, dismissMessage));
+ await Assert.ThrowsAsync(() => client.Dismiss("owner", null, 1, 1, dismissMessage));
+ await Assert.ThrowsAsync(() => client.Dismiss("owner", "name", 1, 1, null));
+
+ await Assert.ThrowsAsync(() => client.Dismiss("", "name", 1, 1, dismissMessage));
+ await Assert.ThrowsAsync(() => client.Dismiss("owner", "", 1, 1, dismissMessage));
+ }
+ }
+
+ public class TheGetAllCommentsMethod
+ {
+ [Fact]
+ public async Task RequestsCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ await client.GetAllComments("owner", "name", 13, 13);
+
+ connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/owner/name/pulls/13/reviews/13/comments"), null, Args.ApiOptions);
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlWithRepositoryId()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ await client.GetAllComments(1, 13, 13);
+
+ connection.Received().GetAll(Arg.Is(u => u.ToString() == "repositories/1/pulls/13/reviews/13/comments"), null, Args.ApiOptions);
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlWithApiOptions()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var options = new ApiOptions
+ {
+ StartPage = 1,
+ PageCount = 1,
+ PageSize = 1
+ };
+
+ await client.GetAllComments("owner", "name", 13, 13, options);
+
+ connection.Received().GetAll(Arg.Is(u => u.ToString() == "repos/owner/name/pulls/13/reviews/13/comments"), null, options);
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlWithApiOptionsWithRepositoryId()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var options = new ApiOptions
+ {
+ StartPage = 1,
+ PageCount = 1,
+ PageSize = 1
+ };
+
+ await client.GetAllComments(1, 13, 13, options);
+
+ connection.Received().GetAll(Arg.Is(u => u.ToString() == "repositories/1/pulls/13/reviews/13/comments"), null, Args.ApiOptions);
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ await Assert.ThrowsAsync(() => client.GetAllComments(null, "name", 1, 1));
+ await Assert.ThrowsAsync(() => client.GetAllComments("owner", null, 1, 1));
+
+ await Assert.ThrowsAsync(() => client.GetAllComments("", "name", 1, 1));
+ await Assert.ThrowsAsync(() => client.GetAllComments("owner", "", 1, 1));
+ }
+ }
+
+ public class TheSubmitMethod
+ {
+ [Fact]
+ public async Task PostsToCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var submitMessage = new PullRequestReviewSubmit()
+ {
+ Body = "string",
+ Event = PullRequestReviewEvent.Approve
+ };
+ await client.Submit("owner", "name", 13, 13, submitMessage);
+
+ connection.Received().Post(Arg.Is(u => u.ToString() == "repos/owner/name/pulls/13/reviews/13/events"), submitMessage, null, null);
+ }
+
+ [Fact]
+ public async Task PostsToCorrectUrlWithRepositoryId()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+ var submitMessage = new PullRequestReviewSubmit()
+ {
+ Body = "string",
+ Event = PullRequestReviewEvent.Approve
+ };
+ await client.Submit(1, 13, 13, submitMessage);
+
+ connection.Received().Post(Arg.Is(u => u.ToString() == "repositories/1/pulls/13/reviews/13/events"), submitMessage, null, null);
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new PullRequestReviewsClient(connection);
+
+ var submitMessage = new PullRequestReviewSubmit()
+ {
+ Body = "string",
+ Event = PullRequestReviewEvent.Approve
+ };
+
+ await Assert.ThrowsAsync(() => client.Submit(null, "name", 1, 1, submitMessage));
+ await Assert.ThrowsAsync(() => client.Submit("owner", null, 1, 1, submitMessage));
+ await Assert.ThrowsAsync(() => client.Submit("owner", "name", 1, 1, null));
+
+ await Assert.ThrowsAsync(() => client.Submit("", "name", 1, 1, submitMessage));
+ await Assert.ThrowsAsync(() => client.Submit("owner", "", 1, 1, submitMessage));
+ }
+ }
+}
diff --git a/Octokit.Tests/Reactive/ObservablePullRequestReviewCommentsClientTests.cs b/Octokit.Tests/Reactive/ObservablePullRequestReviewCommentsClientTests.cs
index 4afdee43b4..9266da83e6 100644
--- a/Octokit.Tests/Reactive/ObservablePullRequestReviewCommentsClientTests.cs
+++ b/Octokit.Tests/Reactive/ObservablePullRequestReviewCommentsClientTests.cs
@@ -179,8 +179,6 @@ public async Task RequestsCorrectUrlMultiWithRepositoryId()
}
);
- var acceptHeader = "application/vnd.github.squirrel-girl-preview";
-
var gitHubClient = Substitute.For();
gitHubClient.Connection.Get>(firstPageUrl, Args.EmptyDictionary, null)
.Returns(Task.Factory.StartNew>>(() => firstPageResponse));
diff --git a/Octokit.Tests/Reactive/ObservablePullRequestReviewsClientTests.cs b/Octokit.Tests/Reactive/ObservablePullRequestReviewsClientTests.cs
new file mode 100644
index 0000000000..8f327776e4
--- /dev/null
+++ b/Octokit.Tests/Reactive/ObservablePullRequestReviewsClientTests.cs
@@ -0,0 +1,679 @@
+using System;
+using System.Collections.Generic;
+using System.Reactive.Linq;
+using System.Threading.Tasks;
+using NSubstitute;
+using Octokit.Internal;
+using Octokit.Reactive;
+using Xunit;
+
+namespace Octokit.Tests.Reactive
+{
+ public class ObservablePullRequestReviewsClientTests
+ {
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(
+ () => new ObservablePullRequestReviewsClient(null));
+ }
+ }
+
+ static IResponse CreateResponseWithApiInfo(IDictionary links)
+ {
+ var response = Substitute.For();
+ response.ApiInfo.Returns(new ApiInfo(links, new List(), new List(), "etag", new RateLimit(new Dictionary())));
+ return response;
+ }
+
+ public class TheGetAllMethod
+ {
+ [Fact]
+ public void RequestsCorrectUrl()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ client.GetAll("fake", "repo", 1);
+
+ gitHubClient.Received().PullRequest.Review.GetAll("fake", "repo", 1);
+ }
+
+ [Fact]
+ public void RequestsCorrectUrlWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ client.GetAll(1, 1);
+
+ gitHubClient.Received().PullRequest.Review.GetAll(1, 1);
+ }
+
+ [Fact]
+ public void RequestsCorrectUrlWithApiOptions()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var options = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1,
+ StartPage = 1
+ };
+
+ client.GetAll("fake", "repo", 1, options);
+
+ gitHubClient.Received().PullRequest.Review.GetAll("fake", "repo", 1, options);
+ }
+
+ [Fact]
+ public void RequestsCorrectUrlWithApiOptionsWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var options = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1,
+ StartPage = 1
+ };
+
+ client.GetAll(1, 1, options);
+
+ gitHubClient.Received().PullRequest.Review.GetAll(1, 1, options);
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlMulti()
+ {
+
+ var firstPageUrl = new Uri("repos/owner/name/pulls/7/reviews", 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 PullRequestReview(1),
+ new PullRequestReview(2),
+ new PullRequestReview(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 PullRequestReview(4),
+ new PullRequestReview(5),
+ new PullRequestReview(6)
+ }
+ );
+ var lastPageResponse = new ApiResponse>
+ (
+ new Response(),
+ new List
+ {
+ new PullRequestReview(7)
+ }
+ );
+
+ var gitHubClient = Substitute.For();
+
+ gitHubClient.Connection.Get>(firstPageUrl, Args.EmptyDictionary, null)
+ .Returns(Task.Factory.StartNew>>(() => firstPageResponse));
+ gitHubClient.Connection.Get>(secondPageUrl, Args.EmptyDictionary, null)
+ .Returns(Task.Factory.StartNew>>(() => secondPageResponse));
+ gitHubClient.Connection.Get>(thirdPageUrl, Args.EmptyDictionary, null)
+ .Returns(Task.Factory.StartNew>>(() => lastPageResponse));
+
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var results = await client.GetAll("owner", "name", 7).ToArray();
+
+ Assert.Equal(7, results.Length);
+ gitHubClient.Connection.Received(1).Get>(firstPageUrl, Args.EmptyDictionary, null);
+ gitHubClient.Connection.Received(1).Get>(secondPageUrl, Args.EmptyDictionary, null);
+ gitHubClient.Connection.Received(1).Get>(thirdPageUrl, Args.EmptyDictionary, null);
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlMultiWithRepositoryId()
+ {
+ var firstPageUrl = new Uri("repositories/1/pulls/7/reviews", 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 PullRequestReview(1),
+ new PullRequestReview(2),
+ new PullRequestReview(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 PullRequestReview(4),
+ new PullRequestReview(5),
+ new PullRequestReview(6)
+ }
+ );
+ var lastPageResponse = new ApiResponse>
+ (
+ new Response(),
+ new List
+ {
+ new PullRequestReview(7)
+ }
+ );
+
+ var gitHubClient = Substitute.For();
+
+ gitHubClient.Connection.Get>(firstPageUrl, Args.EmptyDictionary, null)
+ .Returns(Task.Factory.StartNew>>(() => firstPageResponse));
+ gitHubClient.Connection.Get>(secondPageUrl, Args.EmptyDictionary, null)
+ .Returns(Task.Factory.StartNew>>(() => secondPageResponse));
+ gitHubClient.Connection.Get>(thirdPageUrl, Args.EmptyDictionary, null)
+ .Returns(Task.Factory.StartNew>>(() => lastPageResponse));
+
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var results = await client.GetAll(1, 7).ToArray();
+
+ Assert.Equal(7, results.Length);
+ gitHubClient.Connection.Received(1).Get>(firstPageUrl, Args.EmptyDictionary, null);
+ gitHubClient.Connection.Received(1).Get>(secondPageUrl, Args.EmptyDictionary, null);
+ gitHubClient.Connection.Received(1).Get>(thirdPageUrl, Args.EmptyDictionary, null);
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ Assert.Throws(() => client.GetAll(null, "name", 1));
+ Assert.Throws(() => client.GetAll("owner", null, 1));
+
+ Assert.Throws(() => client.GetAll(null, "name", 1, ApiOptions.None));
+ Assert.Throws(() => client.GetAll("owner", null, 1, ApiOptions.None));
+ Assert.Throws(() => client.GetAll("owner", "name", 1, null));
+
+ Assert.Throws(() => client.GetAll(1, 1, null));
+
+ Assert.Throws(() => client.GetAll("", "name", 1));
+ Assert.Throws(() => client.GetAll("owner", "", 1));
+
+ Assert.Throws(() => client.GetAll("", "name", 1, ApiOptions.None));
+ Assert.Throws(() => client.GetAll("owner", "", 1, ApiOptions.None));
+
+ }
+ }
+
+ public class TheGetMethod
+ {
+ [Fact]
+ public void RequestsCorrectUrl()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ client.Get("owner", "name", 53, 2);
+
+ gitHubClient.Received().PullRequest.Review.Get("owner", "name", 53, 2);
+ }
+
+ [Fact]
+ public void RequestsCorrectUrlWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ client.Get(1, 53, 2);
+
+ gitHubClient.Received().PullRequest.Review.Get(1, 53, 2);
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var client = new ObservablePullRequestReviewsClient(Substitute.For());
+
+ Assert.Throws(() => client.Get(null, "name", 1, 1));
+ Assert.Throws(() => client.Get("owner", null, 1, 1));
+
+ Assert.Throws(() => client.Get("", "name", 1, 1));
+ Assert.Throws(() => client.Get("owner", "", 1, 1));
+ }
+ }
+
+ public class TheCreateMethod
+ {
+ [Fact]
+ public void PostsToCorrectUrl()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var comment = new DraftPullRequestReviewComment("Comment content", "file.css", 7);
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = "commit",
+ Body = "body",
+ Event = PullRequestReviewEvent.Approve
+ };
+
+ review.Comments.Add(comment);
+
+ client.Create("owner", "name", 53, review);
+
+ gitHubClient.Received().PullRequest.Review.Create("owner", "name", 53, review);
+ }
+
+ [Fact]
+ public void PostsToCorrectUrlWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var comment = new DraftPullRequestReviewComment("Comment content", "file.css", 7);
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = "commit",
+ Body = "body",
+ Event = PullRequestReviewEvent.Approve
+ };
+
+ review.Comments.Add(comment);
+
+ client.Create(1, 13, review);
+
+ gitHubClient.Received().PullRequest.Review.Create(1, 53, review);
+ }
+
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ var client = new ObservablePullRequestReviewsClient(Substitute.For());
+
+ string body = "Comment content";
+ string path = "file.css";
+ int position = 7;
+
+ var comment = new DraftPullRequestReviewComment(body, path, position);
+
+ var review = new PullRequestReviewCreate()
+ {
+ CommitId = "commit",
+ Body = "body",
+ Event = PullRequestReviewEvent.Approve
+ };
+
+ review.Comments.Add(comment);
+
+ Assert.Throws(() => client.Create(null, "fakeRepoName", 1, review));
+ Assert.Throws(() => client.Create("fakeOwner", null, 1, review));
+ Assert.Throws(() => client.Create("fakeOwner", "fakeRepoName", 1, null));
+
+ Assert.Throws(() => client.Create("", "fakeRepoName", 1, review));
+ Assert.Throws(() => client.Create("fakeOwner", "", 1, review));
+ }
+ }
+
+ public class TheDeleteMethod
+ {
+ [Fact]
+ public void PostsToCorrectUrl()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ client.Delete("owner", "name", 13, 13);
+
+ gitHubClient.Received().PullRequest.Review.Delete("owner", "name", 13, 13);
+ }
+
+ [Fact]
+ public void PostsToCorrectUrlWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ client.Delete(1, 13, 13);
+
+ gitHubClient.Received().PullRequest.Review.Delete(1, 13, 13);
+ }
+
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ Assert.Throws(() => client.Delete(null, "name", 1, 1));
+ Assert.Throws(() => client.Delete("owner", null, 1, 1));
+
+ Assert.Throws(() => client.Delete("", "name", 1, 1));
+ Assert.Throws(() => client.Delete("owner", "", 1, 1));
+ }
+ }
+
+ public class TheDismissMethod
+ {
+ [Fact]
+ public void PostsToCorrectUrl()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var dismissMessage = new PullRequestReviewDismiss()
+ {
+ Message = "test message"
+ };
+
+ client.Dismiss("owner", "name", 13, 13, dismissMessage);
+
+ gitHubClient.Received().PullRequest.Review.Dismiss("owner", "name", 13, 13, dismissMessage);
+ }
+
+ [Fact]
+ public void PostsToCorrectUrlWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var dismissMessage = new PullRequestReviewDismiss()
+ {
+ Message = "test message"
+ };
+
+ client.Dismiss(1, 13, 13, dismissMessage);
+
+ gitHubClient.Received().PullRequest.Review.Dismiss(1, 13, 13, dismissMessage);
+ }
+
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var dismissMessage = new PullRequestReviewDismiss()
+ {
+ Message = "test message"
+ };
+
+ Assert.Throws(() => client.Dismiss(null, "name", 1, 1, dismissMessage));
+ Assert.Throws(() => client.Dismiss("owner", null, 1, 1, dismissMessage));
+ Assert.Throws(() => client.Dismiss("owner", "name", 1, 1, null));
+
+ Assert.Throws(() => client.Dismiss("", "name", 1, 1, dismissMessage));
+ Assert.Throws(() => client.Dismiss("owner", "", 1, 1, dismissMessage));
+ }
+ }
+
+ public class TheGetAllCommentsMethod
+ {
+ [Fact]
+ public void RequestsCorrectUrl()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ client.GetAllComments("fake", "repo", 1, 1);
+
+ gitHubClient.Received().PullRequest.Review.GetAllComments("fake", "repo", 1, 1);
+ }
+
+ [Fact]
+ public void RequestsCorrectUrlWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ client.GetAllComments(1, 1, 1);
+
+ gitHubClient.Received().PullRequest.Review.GetAllComments(1, 1, 1);
+ }
+
+ [Fact]
+ public void RequestsCorrectUrlWithApiOptions()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var options = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1,
+ StartPage = 1
+ };
+
+ client.GetAllComments("fake", "repo", 1, 1, options);
+
+ gitHubClient.Received().PullRequest.Review.GetAllComments("fake", "repo", 1, 1, options);
+ }
+
+ [Fact]
+ public void RequestsCorrectUrlWithApiOptionsWithRepositoryId()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservablePullRequestReviewsClient(gitHubClient);
+
+ var options = new ApiOptions
+ {
+ PageCount = 1,
+ PageSize = 1,
+ StartPage = 1
+ };
+
+ client.GetAllComments(1, 1, 1, options);
+
+ gitHubClient.Received().PullRequest.Review.GetAllComments(1, 1, 1, options);
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlMulti()
+ {
+ var firstPageUrl = new Uri("repos/owner/name/pulls/7/reviews/1/comments", 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 PullRequestReviewComment(1),
+ new PullRequestReviewComment(2),
+ new PullRequestReviewComment(3)
+ });
+ var thirdPageUrl = new Uri("https://example.com/page/3");
+ var secondPageLinks = new Dictionary