diff --git a/lib/Github/Api/AbstractReactionsApi.php b/lib/Github/Api/AbstractReactionsApi.php new file mode 100644 index 00000000000..891546ba3fe --- /dev/null +++ b/lib/Github/Api/AbstractReactionsApi.php @@ -0,0 +1,68 @@ +get($this->getReactionsPath($username, $repository, $id), $params); + } + + /** + * Create a reaction for a resource. + * + * @param string $username + * @param string $repository + * @param string $id + * @param array $params + * + * @throws MissingArgumentException + * + * @return array + */ + public function create($username, $repository, $id, array $params) + { + if (!isset($params['content'])) { + throw new MissingArgumentException('content'); + } + + return $this->post($this->getReactionsPath($username, $repository, $id), $params); + } + + /** + * Delete a reaction from a resource. + * + * @param string $username + * @param string $repository + * @param string $id + * @param string $reaction + * + * @return array|string + */ + public function remove($username, $repository, $id, $reaction) + { + return $this->delete($this->getReactionsPath($username, $repository, $id).'/'.rawurlencode($reaction)); + } + + /** + * @param string $username + * @param string $repository + * @param string $id + * + * @return string + */ + abstract protected function getReactionsPath($username, $repository, $id); +} diff --git a/lib/Github/Api/Issue.php b/lib/Github/Api/Issue.php index 764f5e442a9..e938325005b 100644 --- a/lib/Github/Api/Issue.php +++ b/lib/Github/Api/Issue.php @@ -7,6 +7,7 @@ use Github\Api\Issue\Events; use Github\Api\Issue\Labels; use Github\Api\Issue\Milestones; +use Github\Api\Issue\Reactions; use Github\Api\Issue\Timeline; use Github\Exception\MissingArgumentException; @@ -179,6 +180,18 @@ public function comments() return new Comments($this->getClient()); } + /** + * Manage issue reactions. + * + * @link https://docs.github.com/en/rest/reactions/reactions#list-reactions-for-an-issue + * + * @return Reactions + */ + public function reactions() + { + return new Reactions($this->getClient()); + } + /** * List all project events. * diff --git a/lib/Github/Api/Issue/Comments.php b/lib/Github/Api/Issue/Comments.php index b0fe878797f..2fc9162bec0 100644 --- a/lib/Github/Api/Issue/Comments.php +++ b/lib/Github/Api/Issue/Comments.php @@ -4,6 +4,7 @@ use Github\Api\AbstractApi; use Github\Api\AcceptHeaderTrait; +use Github\Api\Issue\Comments\Reactions; use Github\Exception\MissingArgumentException; /** @@ -130,4 +131,16 @@ public function remove($username, $repository, $comment) { return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.$comment); } + + /** + * Manage issue comment reactions. + * + * @link https://docs.github.com/en/rest/reactions/reactions#list-reactions-for-an-issue-comment + * + * @return Reactions + */ + public function reactions() + { + return new Reactions($this->getClient()); + } } diff --git a/lib/Github/Api/Issue/Comments/Reactions.php b/lib/Github/Api/Issue/Comments/Reactions.php new file mode 100644 index 00000000000..5835a57cf42 --- /dev/null +++ b/lib/Github/Api/Issue/Comments/Reactions.php @@ -0,0 +1,20 @@ +delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/comments/'.$comment); } + + /** + * Manage pull request review comment reactions. + * + * @link https://docs.github.com/en/rest/reactions/reactions#list-reactions-for-a-pull-request-review-comment + * + * @return Reactions + */ + public function reactions() + { + return new Reactions($this->getClient()); + } } diff --git a/lib/Github/Api/PullRequest/Comments/Reactions.php b/lib/Github/Api/PullRequest/Comments/Reactions.php new file mode 100644 index 00000000000..edd7b1455d3 --- /dev/null +++ b/lib/Github/Api/PullRequest/Comments/Reactions.php @@ -0,0 +1,20 @@ +delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/comments/'.rawurlencode($comment)); } + + /** + * Manage commit comment reactions. + * + * @link https://docs.github.com/en/rest/reactions/reactions#list-reactions-for-a-commit-comment + * + * @return Reactions + */ + public function reactions() + { + return new Reactions($this->getClient()); + } } diff --git a/lib/Github/Api/Repository/Comments/Reactions.php b/lib/Github/Api/Repository/Comments/Reactions.php new file mode 100644 index 00000000000..04c92dc7738 --- /dev/null +++ b/lib/Github/Api/Repository/Comments/Reactions.php @@ -0,0 +1,20 @@ +getClient()); } + + /** + * Manage release reactions. + * + * @link https://docs.github.com/en/rest/reactions/reactions#list-reactions-for-a-release + * + * @return Reactions + */ + public function reactions() + { + return new Reactions($this->getClient()); + } } diff --git a/lib/Github/Api/Repository/Releases/Reactions.php b/lib/Github/Api/Repository/Releases/Reactions.php new file mode 100644 index 00000000000..edfbffef95d --- /dev/null +++ b/lib/Github/Api/Repository/Releases/Reactions.php @@ -0,0 +1,20 @@ + 'rocket']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/issues/comments/123/reactions', $parameters) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->all('KnpLabs', 'php-github-api', 123, $parameters)); + } + + /** + * @test + */ + public function shouldNotCreateIssueCommentReactionWithoutContent() + { + $this->expectException(MissingArgumentException::class); + + $api = $this->getApiMock(); + $api->expects($this->never()) + ->method('post'); + + $api->create('KnpLabs', 'php-github-api', 123, []); + } + + /** + * @test + */ + public function shouldCreateIssueCommentReaction() + { + $expectedValue = ['reaction1data']; + $data = ['content' => 'rocket']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/issues/comments/123/reactions', $data) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->create('KnpLabs', 'php-github-api', 123, $data)); + } + + /** + * @test + */ + public function shouldRemoveIssueCommentReaction() + { + $expectedValue = ['someOutput']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/repos/KnpLabs/php-github-api/issues/comments/123/reactions/456') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', 123, 456)); + } + + /** + * @return string + */ + protected function getApiClass() + { + return \Github\Api\Issue\Comments\Reactions::class; + } +} diff --git a/test/Github/Tests/Api/Issue/CommentsTest.php b/test/Github/Tests/Api/Issue/CommentsTest.php index 3a8db85a922..8f23745dd6f 100644 --- a/test/Github/Tests/Api/Issue/CommentsTest.php +++ b/test/Github/Tests/Api/Issue/CommentsTest.php @@ -137,6 +137,16 @@ public function shouldRemoveComment() $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', 123)); } + /** + * @test + */ + public function shouldGetReactionsApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\Issue\Comments\Reactions::class, $api->reactions()); + } + /** * @return string */ diff --git a/test/Github/Tests/Api/Issue/ReactionsTest.php b/test/Github/Tests/Api/Issue/ReactionsTest.php new file mode 100644 index 00000000000..56aff22fc51 --- /dev/null +++ b/test/Github/Tests/Api/Issue/ReactionsTest.php @@ -0,0 +1,81 @@ + 'heart']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/issues/123/reactions', $parameters) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->all('KnpLabs', 'php-github-api', 123, $parameters)); + } + + /** + * @test + */ + public function shouldNotCreateIssueReactionWithoutContent() + { + $this->expectException(MissingArgumentException::class); + + $api = $this->getApiMock(); + $api->expects($this->never()) + ->method('post'); + + $api->create('KnpLabs', 'php-github-api', 123, []); + } + + /** + * @test + */ + public function shouldCreateIssueReaction() + { + $expectedValue = ['reaction1data']; + $data = ['content' => 'heart']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/issues/123/reactions', $data) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->create('KnpLabs', 'php-github-api', 123, $data)); + } + + /** + * @test + */ + public function shouldRemoveIssueReaction() + { + $expectedValue = ['someOutput']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/repos/KnpLabs/php-github-api/issues/123/reactions/456') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', 123, 456)); + } + + /** + * @return string + */ + protected function getApiClass() + { + return \Github\Api\Issue\Reactions::class; + } +} diff --git a/test/Github/Tests/Api/IssueTest.php b/test/Github/Tests/Api/IssueTest.php index a151076ce1f..02edaa0b5fd 100644 --- a/test/Github/Tests/Api/IssueTest.php +++ b/test/Github/Tests/Api/IssueTest.php @@ -166,6 +166,16 @@ public function shouldGetCommentsApiObject() $this->assertInstanceOf(\Github\Api\Issue\Comments::class, $api->comments()); } + /** + * @test + */ + public function shouldGetReactionsApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\Issue\Reactions::class, $api->reactions()); + } + /** * @test */ diff --git a/test/Github/Tests/Api/PullRequest/Comments/ReactionsTest.php b/test/Github/Tests/Api/PullRequest/Comments/ReactionsTest.php new file mode 100644 index 00000000000..90b5be3b2bd --- /dev/null +++ b/test/Github/Tests/Api/PullRequest/Comments/ReactionsTest.php @@ -0,0 +1,81 @@ + 'eyes']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/pulls/comments/123/reactions', $parameters) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->all('KnpLabs', 'php-github-api', 123, $parameters)); + } + + /** + * @test + */ + public function shouldNotCreatePullRequestReviewCommentReactionWithoutContent() + { + $this->expectException(MissingArgumentException::class); + + $api = $this->getApiMock(); + $api->expects($this->never()) + ->method('post'); + + $api->create('KnpLabs', 'php-github-api', 123, []); + } + + /** + * @test + */ + public function shouldCreatePullRequestReviewCommentReaction() + { + $expectedValue = ['reaction1data']; + $data = ['content' => 'eyes']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/pulls/comments/123/reactions', $data) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->create('KnpLabs', 'php-github-api', 123, $data)); + } + + /** + * @test + */ + public function shouldRemovePullRequestReviewCommentReaction() + { + $expectedValue = ['someOutput']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/repos/KnpLabs/php-github-api/pulls/comments/123/reactions/456') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', 123, 456)); + } + + /** + * @return string + */ + protected function getApiClass() + { + return \Github\Api\PullRequest\Comments\Reactions::class; + } +} diff --git a/test/Github/Tests/Api/PullRequest/CommentsTest.php b/test/Github/Tests/Api/PullRequest/CommentsTest.php index c180607e837..ab765efd079 100644 --- a/test/Github/Tests/Api/PullRequest/CommentsTest.php +++ b/test/Github/Tests/Api/PullRequest/CommentsTest.php @@ -488,6 +488,16 @@ public function shouldDeleteReviewComment() $api->remove('octocat', 'Hello-World', 1); } + /** + * @test + */ + public function shouldGetReactionsApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\PullRequest\Comments\Reactions::class, $api->reactions()); + } + protected function getApiClass() { return Comments::class; diff --git a/test/Github/Tests/Api/Repository/Comments/ReactionsTest.php b/test/Github/Tests/Api/Repository/Comments/ReactionsTest.php new file mode 100644 index 00000000000..d2ae44b7413 --- /dev/null +++ b/test/Github/Tests/Api/Repository/Comments/ReactionsTest.php @@ -0,0 +1,89 @@ + 'hooray']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/comments/123/reactions', $parameters) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->all('KnpLabs', 'php-github-api', 123, $parameters)); + } + + /** + * @test + */ + public function shouldNotCreateCommitCommentReactionWithoutContent() + { + $this->expectException(MissingArgumentException::class); + + $api = $this->getApiMock(); + $api->expects($this->never()) + ->method('post'); + + $api->create('KnpLabs', 'php-github-api', 123, []); + } + + /** + * @test + */ + public function shouldCreateCommitCommentReaction() + { + $expectedValue = ['reaction1data']; + $data = ['content' => 'hooray']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/comments/123/reactions', $data) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->create('KnpLabs', 'php-github-api', 123, $data)); + } + + /** + * @test + */ + public function shouldRemoveCommitCommentReaction() + { + $expectedValue = ['someOutput']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/repos/KnpLabs/php-github-api/comments/123/reactions/456') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', 123, 456)); + } + + /** + * @return string + */ + protected function getApiClass() + { + return \Github\Api\Repository\Comments\Reactions::class; + } + + /** + * @return \Github\Api\Repository\Comments\Reactions|\PHPUnit\Framework\MockObject\MockObject + */ + protected function getApiMock() + { + return parent::getApiMock(); + } +} diff --git a/test/Github/Tests/Api/Repository/CommentsTest.php b/test/Github/Tests/Api/Repository/CommentsTest.php index 949bf4e231d..499c2c5ab04 100644 --- a/test/Github/Tests/Api/Repository/CommentsTest.php +++ b/test/Github/Tests/Api/Repository/CommentsTest.php @@ -150,6 +150,16 @@ public function shouldRemoveComment() $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', 123)); } + /** + * @test + */ + public function shouldGetReactionsApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\Repository\Comments\Reactions::class, $api->reactions()); + } + /** * @return string */ diff --git a/test/Github/Tests/Api/Repository/Releases/ReactionsTest.php b/test/Github/Tests/Api/Repository/Releases/ReactionsTest.php new file mode 100644 index 00000000000..f0bc942b2e8 --- /dev/null +++ b/test/Github/Tests/Api/Repository/Releases/ReactionsTest.php @@ -0,0 +1,81 @@ + 'laugh']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/releases/123/reactions', $parameters) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->all('KnpLabs', 'php-github-api', 123, $parameters)); + } + + /** + * @test + */ + public function shouldNotCreateReleaseReactionWithoutContent() + { + $this->expectException(MissingArgumentException::class); + + $api = $this->getApiMock(); + $api->expects($this->never()) + ->method('post'); + + $api->create('KnpLabs', 'php-github-api', 123, []); + } + + /** + * @test + */ + public function shouldCreateReleaseReaction() + { + $expectedValue = ['reaction1data']; + $data = ['content' => 'laugh']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/releases/123/reactions', $data) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->create('KnpLabs', 'php-github-api', 123, $data)); + } + + /** + * @test + */ + public function shouldRemoveReleaseReaction() + { + $expectedValue = ['someOutput']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/repos/KnpLabs/php-github-api/releases/123/reactions/456') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', 123, 456)); + } + + /** + * @return string + */ + protected function getApiClass() + { + return \Github\Api\Repository\Releases\Reactions::class; + } +} diff --git a/test/Github/Tests/Api/Repository/ReleasesTest.php b/test/Github/Tests/Api/Repository/ReleasesTest.php index dda8999a163..6ccc88598f3 100644 --- a/test/Github/Tests/Api/Repository/ReleasesTest.php +++ b/test/Github/Tests/Api/Repository/ReleasesTest.php @@ -173,6 +173,16 @@ public function shouldGetAssetsApiObject() $this->assertInstanceOf('Github\Api\Repository\Assets', $api->assets()); } + /** + * @test + */ + public function shouldGetReactionsApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf('Github\Api\Repository\Releases\Reactions', $api->reactions()); + } + /** * @return string */