diff --git a/lib/Github/Api/PullRequest.php b/lib/Github/Api/PullRequest.php index b7df369b99d..52cc77fe348 100644 --- a/lib/Github/Api/PullRequest.php +++ b/lib/Github/Api/PullRequest.php @@ -3,6 +3,7 @@ namespace Github\Api; use Github\Api\PullRequest\Comments; +use Github\Api\PullRequest\Review; use Github\Exception\MissingArgumentException; /** @@ -65,6 +66,11 @@ public function comments() return new Comments($this->client); } + public function reviews() + { + return new Review($this->client); + } + /** * Create a pull request. * diff --git a/lib/Github/Api/PullRequest/Comments.php b/lib/Github/Api/PullRequest/Comments.php index 971f38cee9e..b2de809ed7a 100644 --- a/lib/Github/Api/PullRequest/Comments.php +++ b/lib/Github/Api/PullRequest/Comments.php @@ -11,9 +11,13 @@ */ class Comments extends AbstractApi { - public function all($username, $repository, $pullRequest) + public function all($username, $repository, $pullRequest = null) { - return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($pullRequest).'/comments'); + if (null !== $pullRequest) { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($pullRequest).'/comments'); + } + + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/comments'); } public function show($username, $repository, $comment) diff --git a/lib/Github/Api/PullRequest/Review.php b/lib/Github/Api/PullRequest/Review.php new file mode 100644 index 00000000000..8977bddf8dd --- /dev/null +++ b/lib/Github/Api/PullRequest/Review.php @@ -0,0 +1,161 @@ + + */ +class Review extends AbstractApi +{ + /** + * Get a listing of a pull request's reviews by the username, repository and pull request number. + * + * @link https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request + * + * @param string $username the username + * @param string $repository the repository + * @param int $pullRequest the pull request number + * @param array $params a list of extra parameters. + * + * @return array array of pull request reviews for the pull request + */ + public function all($username, $repository, $pullRequest, array $params = []) + { + $parameters = array_merge([ + 'page' => 1, + 'per_page' => 30 + ], $params); + + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/reviews', $parameters); + } + + /** + * Get a single pull request review by the username, repository, pull request number and the review id. + * + * @link https://developer.github.com/v3/pulls/reviews/#get-a-single-review + * + * @param string $username the username + * @param string $repository the repository + * @param int $pullRequest the pull request number + * @param int $id the review id + * + * @return array the pull request review + */ + public function show($username, $repository, $pullRequest, $id) + { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/reviews/'.$id); + } + + /** + * Delete a single pull request review by the username, repository, pull request number and the review id. + * + * @link https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review + * + * @param string $username the username + * @param string $repository the repository + * @param int $pullRequest the pull request number + * @param int $id the review id + * + * @return array|string + */ + public function remove($username, $repository, $pullRequest, $id) + { + return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/reviews/'.$id); + } + + /** + * Get comments for a single pull request review. + * + * @link https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review + * + * @param string $username the username + * @param string $repository the repository + * @param int $pullRequest the pull request number + * @param int $id the review id + * + * @return array|string + */ + public function comments($username, $repository, $pullRequest, $id) + { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($pullRequest).'/reviews/'.rawurlencode($id).'/comments'); + } + + /** + * Create a pull request review by the username, repository and pull request number. + * + * @link https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review + * + * @param string $username the username + * @param string $repository the repository + * @param int $pullRequest the pull request number + * @param array $params a list of extra parameters. + * + * @throws MissingArgumentException + * + * @return array the pull request review + */ + public function create($username, $repository, $pullRequest, array $params = []) + { + if (!isset($params['event'])) { + throw new MissingArgumentException('event'); + } + + if (!in_array($params['event'], ["APPROVE", "REQUEST_CHANGES", "COMMENT"], true)) { + throw new InvalidArgumentException(sprintf('"event" must be one of ["APPROVE", "REQUEST_CHANGES", "COMMENT"] ("%s" given).', $params['event'])); + } + + return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/reviews', $params); + } + + /** + * Submit a pull request review by the username, repository, pull request number and the review id. + * + * @link https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review + * + * @param string $username the username + * @param string $repository the repository + * @param int $pullRequest the pull request number + * @param int $id the review id + * @param array $params a list of extra parameters. + * + * @throws MissingArgumentException + * + * @return array the pull request review + */ + public function submit($username, $repository, $pullRequest, $id, array $params = []) + { + if (!isset($params['event'])) { + throw new MissingArgumentException('event'); + } + + if (!in_array($params['event'], ["APPROVE", "REQUEST_CHANGES", "COMMENT"], true)) { + throw new InvalidArgumentException(sprintf('"event" must be one of ["APPROVE", "REQUEST_CHANGES", "COMMENT"] ("%s" given).', $params['event'])); + } + + return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/reviews/'.$id.'/events', $params); + } + + /** + * Dismiss a pull request review by the username, repository, pull request number and the review id. + * + * @link https://developer.github.com/v3/pulls/reviews/#dismiss-a-pull-request-review + * + * @param string $username the username + * @param string $repository the repository + * @param int $pullRequest the pull request number + * @param int $id the review id + * + * @return array|string + */ + public function dismiss($username, $repository, $pullRequest, $id) + { + return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/reviews/'.$id.'/dismissals'); + } +} diff --git a/lib/Github/Client.php b/lib/Github/Client.php index eb7f3e727dd..af0cf58efab 100644 --- a/lib/Github/Client.php +++ b/lib/Github/Client.php @@ -127,7 +127,7 @@ public function __construct(Builder $httpClientBuilder = null, $apiVersion = nul ))); $this->apiVersion = $apiVersion ?: 'v3'; - $builder->addHeaders(['Accept' => sprintf('application/vnd.github.%s+json', $this->apiVersion)]); + $builder->addHeaderValue('Accept', sprintf('application/vnd.github.%s+json', $this->apiVersion)); if ($enterpriseUrl) { $this->setEnterpriseUrl($enterpriseUrl); diff --git a/lib/Github/HttpClient/Builder.php b/lib/Github/HttpClient/Builder.php index f67c2c9dd08..7d2052498e6 100644 --- a/lib/Github/HttpClient/Builder.php +++ b/lib/Github/HttpClient/Builder.php @@ -157,6 +157,19 @@ public function addHeaders(array $headers) $this->addPlugin(new Plugin\HeaderAppendPlugin($this->headers)); } + /** + * @param string $header + * @param string $headerValue + */ + public function addHeaderValue($header, $headerValue) + { + if (!isset($this->headers[$header])) { + $this->headers[$header] = $headerValue; + } else { + $this->headers[$header] = array_merge((array)$this->headers[$header], array($headerValue)); + } + } + /** * Add a cache plugin to cache responses locally. * diff --git a/test/Github/Tests/Api/PullRequest/CommentsTest.php b/test/Github/Tests/Api/PullRequest/CommentsTest.php new file mode 100644 index 00000000000..a6213a168cc --- /dev/null +++ b/test/Github/Tests/Api/PullRequest/CommentsTest.php @@ -0,0 +1,495 @@ + 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + 'id' => 1, + 'pull_request_review_id' => 42, + 'diff_hunk' => '@@ -16,33 +16,40 @@ public class Connection => IConnection...', + 'path' => 'file1.txt', + 'position' => 1, + 'original_position' => 4, + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'original_commit_id' => '9c48853fa3dc5c1c3d6f1f1cd1f2743e72652840', + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following[/other_user]', + 'gists_url' => 'https://api.github.com/users/octocat/gists[/gist_id]', + 'starred_url' => 'https://api.github.com/users/octocat/starred[/owner][/repo]', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events[/privacy]', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false, + ], + 'body' => 'Great stuff', + 'created_at' => '2011-04-14T16:00:49Z', + 'updated_at' => '2011-04-14T16:00:49Z', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + '_links' => [ + 'self' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + ], + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + ], + ], + ], + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/octocat/Hello-World/pulls/12/comments') + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->all('octocat', 'Hello-World', 12)); + } + + /** + * @test + */ + public function shouldGetAllReviewComments() + { + $expectedValue = [ + [ + 'url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + 'id' => 1, + 'pull_request_review_id' => 42, + 'diff_hunk' => '@@ -16,33 +16,40 @@ public class Connection => IConnection...', + 'path' => 'file1.txt', + 'position' => 1, + 'original_position' => 4, + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'original_commit_id' => '9c48853fa3dc5c1c3d6f1f1cd1f2743e72652840', + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following[/other_user]', + 'gists_url' => 'https://api.github.com/users/octocat/gists[/gist_id]', + 'starred_url' => 'https://api.github.com/users/octocat/starred[/owner][/repo]', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events[/privacy]', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false, + ], + 'body' => 'Great stuff', + 'created_at' => '2011-04-14T16:00:49Z', + 'updated_at' => '2011-04-14T16:00:49Z', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + '_links' => [ + 'self' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + ], + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + ], + ], + ], + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/octocat/Hello-World/pulls/comments') + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->all('octocat', 'Hello-World')); + } + + /** + * @test + */ + public function shouldShowReviewComment() + { + $expectedValue = [ + 'url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + 'id' => 1, + 'pull_request_review_id' => 42, + 'diff_hunk' => '@@ -16,33 +16,40 @@ public class Connection => IConnection...', + 'path' => 'file1.txt', + 'position' => 1, + 'original_position' => 4, + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'original_commit_id' => '9c48853fa3dc5c1c3d6f1f1cd1f2743e72652840', + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following[/other_user]', + 'gists_url' => 'https://api.github.com/users/octocat/gists[/gist_id]', + 'starred_url' => 'https://api.github.com/users/octocat/starred[/owner][/repo]', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events[/privacy]', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false, + ], + 'body' => 'Great stuff', + 'created_at' => '2011-04-14T16:00:49Z', + 'updated_at' => '2011-04-14T16:00:49Z', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + '_links' => [ + 'self' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + ], + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + ], + ], + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/octocat/Hello-World/pulls/comments/1') + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->show('octocat', 'Hello-World', 1)); + } + + /** + * @test + */ + public function shouldCreateReviewComment() + { + $expectedValue = [ + 'url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + 'id' => 1, + 'pull_request_review_id' => 42, + 'diff_hunk' => '@@ -16,33 +16,40 @@ public class Connection => IConnection...', + 'path' => 'file1.txt', + 'position' => 1, + 'original_position' => 4, + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'original_commit_id' => '9c48853fa3dc5c1c3d6f1f1cd1f2743e72652840', + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following[/other_user]', + 'gists_url' => 'https://api.github.com/users/octocat/gists[/gist_id]', + 'starred_url' => 'https://api.github.com/users/octocat/starred[/owner][/repo]', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events[/privacy]', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false, + ], + 'body' => 'Great stuff', + 'created_at' => '2011-04-14T16:00:49Z', + 'updated_at' => '2011-04-14T16:00:49Z', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + '_links' => [ + 'self' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + ], + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + ], + ], + ]; + $data = [ + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'path' => 'file1.txt', + 'position' => 4, + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/octocat/Hello-World/pulls/1/comments', $data) + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->create('octocat', 'Hello-World', 1, $data)); + } + + /** + * @test + * @expectedException \Github\Exception\MissingArgumentException + */ + public function shouldNotCreateReviewCommentWithoutCommitId() + { + $data = [ + 'path' => 'file1.txt', + 'position' => 4, + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->never()) + ->method('post') + ; + + $api->create('octocat', 'Hello-World', 1, $data); + } + + /** + * @test + * @expectedException \Github\Exception\MissingArgumentException + */ + public function shouldNotCreateReviewCommentWithoutPath() + { + $data = [ + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'position' => 4, + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->never()) + ->method('post') + ; + + $api->create('octocat', 'Hello-World', 1, $data); + } + + /** + * @test + * @expectedException \Github\Exception\MissingArgumentException + */ + public function shouldNotCreateReviewCommentWithoutPosition() + { + $data = [ + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'path' => 'file1.txt', + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->never()) + ->method('post') + ; + + $api->create('octocat', 'Hello-World', 1, $data); + } + + /** + * @test + * @expectedException \Github\Exception\MissingArgumentException + */ + public function shouldNotCreateReviewCommentWithoutBody() + { + $data = [ + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'path' => 'file1.txt', + 'position' => 4, + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->never()) + ->method('post') + ; + + $api->create('octocat', 'Hello-World', 1, $data); + } + + /** + * @test + */ + public function shouldUpdateReviewComment() + { + $expectedValue = [ + 'url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + 'id' => 1, + 'pull_request_review_id' => 42, + 'diff_hunk' => '@@ -16,33 +16,40 @@ public class Connection => IConnection...', + 'path' => 'file1.txt', + 'position' => 1, + 'original_position' => 4, + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'original_commit_id' => '9c48853fa3dc5c1c3d6f1f1cd1f2743e72652840', + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following[/other_user]', + 'gists_url' => 'https://api.github.com/users/octocat/gists[/gist_id]', + 'starred_url' => 'https://api.github.com/users/octocat/starred[/owner][/repo]', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events[/privacy]', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false, + ], + 'body' => 'Great stuff', + 'created_at' => '2011-04-14T16:00:49Z', + 'updated_at' => '2011-04-14T16:00:49Z', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + '_links' => [ + 'self' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + ], + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + ], + ], + ]; + $data = [ + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('patch') + ->with('/repos/octocat/Hello-World/pulls/comments/1', $data) + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->update('octocat', 'Hello-World', 1, $data)); + } + + /** + * @test + * @expectedException \Github\Exception\MissingArgumentException + */ + public function shouldNotUpdateReviewCommentWithoutBody() + { + $expectedValue = [ + 'url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + 'id' => 1, + 'pull_request_review_id' => 42, + 'diff_hunk' => '@@ -16,33 +16,40 @@ public class Connection => IConnection...', + 'path' => 'file1.txt', + 'position' => 1, + 'original_position' => 4, + 'commit_id' => '6dcb09b5b57875f334f61aebed695e2e4193db5e', + 'original_commit_id' => '9c48853fa3dc5c1c3d6f1f1cd1f2743e72652840', + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following[/other_user]', + 'gists_url' => 'https://api.github.com/users/octocat/gists[/gist_id]', + 'starred_url' => 'https://api.github.com/users/octocat/starred[/owner][/repo]', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events[/privacy]', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false, + ], + 'body' => 'Great stuff', + 'created_at' => '2011-04-14T16:00:49Z', + 'updated_at' => '2011-04-14T16:00:49Z', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + '_links' => [ + 'self' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/comments/1', + ], + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/1#discussion-diff-1', + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1', + ], + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->never()) + ->method('patch') + ; + + $this->assertSame($expectedValue, $api->update('octocat', 'Hello-World', 1, [])); + } + + /** + * @test + */ + public function shouldDeleteReviewComment() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/repos/octocat/Hello-World/pulls/comments/1') + ; + + $api->remove('octocat', 'Hello-World', 1); + } + + protected function getApiClass() + { + return Comments::class; + } +} diff --git a/test/Github/Tests/Api/PullRequest/ReviewTest.php b/test/Github/Tests/Api/PullRequest/ReviewTest.php new file mode 100644 index 00000000000..54b8d55aafe --- /dev/null +++ b/test/Github/Tests/Api/PullRequest/ReviewTest.php @@ -0,0 +1,401 @@ + 80, + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following{/other_user}', + 'gists_url' => 'https://api.github.com/users/octocat/gists{/gist_id}', + 'starred_url' => 'https://api.github.com/users/octocat/starred{/owner}{/repo}', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events{/privacy}', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false + ], + 'body' => 'Here is the body for the review.', + 'commit_id' => 'ecdd80bb57125d7ba9641ffaa4d7d2c19d3f3091', + 'state' => 'APPROVED', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/12', + '_links' => [ + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80' + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/12' + ], + ], + ], + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/octocat/Hello-World/pulls/12/reviews') + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->all('octocat', 'Hello-World', 12)); + } + + /** + * @test + */ + public function shouldShowReview() + { + $expectedValue = [ + 'id' => 80, + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following{/other_user}', + 'gists_url' => 'https://api.github.com/users/octocat/gists{/gist_id}', + 'starred_url' => 'https://api.github.com/users/octocat/starred{/owner}{/repo}', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events{/privacy}', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false + ], + 'body' => 'Here is the body for the review.', + 'commit_id' => 'ecdd80bb57125d7ba9641ffaa4d7d2c19d3f3091', + 'state' => 'APPROVED', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/12', + '_links' => [ + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80' + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/12' + ], + ], + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/octocat/Hello-World/pulls/12/reviews/80') + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->show('octocat', 'Hello-World', 12, 80)); + } + + /** + * @test + */ + public function shouldDeleteReview() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/repos/octocat/Hello-World/pulls/12/reviews/80') + ; + + $api->remove('octocat', 'Hello-World', 12, 80); + } + + /** + * @test + */ + public function shouldShowReviewComments() + { + $expectedValue = [ + [ + "url" => "https://api.github.com/repos/octocat/Hello-World/pulls/comments/1", + "id" => 1, + "pull_request_review_id" => 42, + "diff_hunk" => "@@ -16,33 +16,40 @@ public class Connection => IConnection...", + "path" => "file1.txt", + "position" => 1, + "original_position" => 4, + "commit_id" => "6dcb09b5b57875f334f61aebed695e2e4193db5e", + "original_commit_id" => "9c48853fa3dc5c1c3d6f1f1cd1f2743e72652840", + "user" => [ + "login" => "octocat", + "id" => 1, + "avatar_url" => "https://github.com/images/error/octocat_happy.gif", + "gravatar_id" => "", + "url" => "https://api.github.com/users/octocat", + "html_url" => "https://github.com/octocat", + "followers_url" => "https://api.github.com/users/octocat/followers", + "following_url" => "https://api.github.com/users/octocat/following[/other_user]", + "gists_url" => "https://api.github.com/users/octocat/gists[/gist_id]", + "starred_url" => "https://api.github.com/users/octocat/starred[/owner][/repo]", + "subscriptions_url" => "https://api.github.com/users/octocat/subscriptions", + "organizations_url" => "https://api.github.com/users/octocat/orgs", + "repos_url" => "https://api.github.com/users/octocat/repos", + "events_url" => "https://api.github.com/users/octocat/events[/privacy]", + "received_events_url" => "https://api.github.com/users/octocat/received_events", + "type" => "User", + "site_admin" => false, + ], + "body" => "Great stuff", + "created_at" => "2011-04-14T16:00:49Z", + "updated_at" => "2011-04-14T16:00:49Z", + "html_url" => "https://github.com/octocat/Hello-World/pull/1#discussion-diff-1", + "pull_request_url" => "https://api.github.com/repos/octocat/Hello-World/pulls/1", + "_links" => [ + "self" => [ + "href" => "https://api.github.com/repos/octocat/Hello-World/pulls/comments/1", + ], + "html" => [ + "href" => "https://github.com/octocat/Hello-World/pull/1#discussion-diff-1", + ], + "pull_request" => [ + "href" => "https://api.github.com/repos/octocat/Hello-World/pulls/1", + ], + ], + ], + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/octocat/Hello-World/pulls/1/reviews/42/comments') + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->comments('octocat', 'Hello-World', 1, 42)); + } + + /** + * @test + */ + public function shouldCreateReviewComment() + { + $data = [ + 'event' => 'APPROVE', + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->once()) + ->method('post') + ->with('/repos/octocat/Hello-World/pulls/12/reviews') + ; + + $api->create('octocat', 'Hello-World', 12, $data); + } + + /** + * @test + * @expectedException \Github\Exception\MissingArgumentException + */ + public function shouldNotCreateReviewWithoutEvent() + { + $data = [ + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->never()) + ->method('post') + ; + + $api->create('octocat', 'Hello-World', 12, $data); + } + + /** + * @test + * @expectedException \Github\Exception\InvalidArgumentException + */ + public function shouldNotCreateReviewWithInvalidEvent() + { + $data = [ + 'event' => 'DISMISSED', + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->never()) + ->method('post') + ; + + $api->create('octocat', 'Hello-World', 12, $data); + } + + /** + * @test + */ + public function shouldSubmitReviewComment() + { + $expectedValue = [ + 'id' => 80, + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following{/other_user}', + 'gists_url' => 'https://api.github.com/users/octocat/gists{/gist_id}', + 'starred_url' => 'https://api.github.com/users/octocat/starred{/owner}{/repo}', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events{/privacy}', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false + ], + 'body' => 'Here is the body for the review.', + 'commit_id' => 'ecdd80bb57125d7ba9641ffaa4d7d2c19d3f3091', + 'state' => 'APPROVED', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/12', + '_links' => [ + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80' + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/12' + ], + ], + ]; + $data = [ + 'event' => 'APPROVE', + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->once()) + ->method('post') + ->with('/repos/octocat/Hello-World/pulls/12/reviews/80/events') + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->submit('octocat', 'Hello-World', 12, 80, $data)); + } + + /** + * @test + * @expectedException \Github\Exception\MissingArgumentException + */ + public function shouldNotSubmitReviewWithoutEvent() + { + $data = [ + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->never()) + ->method('post') + ; + + $api->submit('octocat', 'Hello-World', 12, 80, $data); + } + + /** + * @test + * @expectedException \Github\Exception\InvalidArgumentException + */ + public function shouldNotSubmitReviewWithInvalidEvent() + { + $data = [ + 'event' => 'DISMISSED', + 'body' => 'Nice change', + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->never()) + ->method('post') + ; + + $api->submit('octocat', 'Hello-World', 12, 80, $data); + } + + /** + * @test + */ + public function shouldDismissReview() + { + $expectedValue = [ + 'id' => 80, + 'user' => [ + 'login' => 'octocat', + 'id' => 1, + 'avatar_url' => 'https://github.com/images/error/octocat_happy.gif', + 'gravatar_id' => '', + 'url' => 'https://api.github.com/users/octocat', + 'html_url' => 'https://github.com/octocat', + 'followers_url' => 'https://api.github.com/users/octocat/followers', + 'following_url' => 'https://api.github.com/users/octocat/following{/other_user}', + 'gists_url' => 'https://api.github.com/users/octocat/gists{/gist_id}', + 'starred_url' => 'https://api.github.com/users/octocat/starred{/owner}{/repo}', + 'subscriptions_url' => 'https://api.github.com/users/octocat/subscriptions', + 'organizations_url' => 'https://api.github.com/users/octocat/orgs', + 'repos_url' => 'https://api.github.com/users/octocat/repos', + 'events_url' => 'https://api.github.com/users/octocat/events{/privacy}', + 'received_events_url' => 'https://api.github.com/users/octocat/received_events', + 'type' => 'User', + 'site_admin' => false + ], + 'body' => 'Here is the body for the review.', + 'commit_id' => 'ecdd80bb57125d7ba9641ffaa4d7d2c19d3f3091', + 'state' => 'APPROVED', + 'html_url' => 'https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80', + 'pull_request_url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/12', + '_links' => [ + 'html' => [ + 'href' => 'https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80' + ], + 'pull_request' => [ + 'href' => 'https://api.github.com/repos/octocat/Hello-World/pulls/12' + ], + ], + ]; + + $api = $this->getApiMock(); + $api + ->expects($this->once()) + ->method('put') + ->with('/repos/octocat/Hello-World/pulls/12/reviews/80/dismissals') + ->willReturn($expectedValue); + + $this->assertSame($expectedValue, $api->dismiss('octocat', 'Hello-World', 12, 80)); + } + + protected function getApiClass() + { + return Review::class; + } +} diff --git a/test/Github/Tests/Api/PullRequestTest.php b/test/Github/Tests/Api/PullRequestTest.php index 8bb3bcb1f72..672093f5cda 100644 --- a/test/Github/Tests/Api/PullRequestTest.php +++ b/test/Github/Tests/Api/PullRequestTest.php @@ -305,6 +305,16 @@ public function shouldGetCommentsApiObject() $this->assertInstanceOf(\Github\Api\PullRequest\Comments::class, $api->comments()); } + /** + * @test + */ + public function shouldGetReviewApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\PullRequest\Review::class, $api->reviews()); + } + /** * @return string */