diff --git a/lib/octokit/client/reactions.rb b/lib/octokit/client/reactions.rb index 0505cb0b3..438998bd9 100644 --- a/lib/octokit/client/reactions.rb +++ b/lib/octokit/client/reactions.rb @@ -150,6 +150,55 @@ def create_pull_request_review_comment_reaction(repo, id, reaction, options = {} def delete_issue_reaction(repo, issue_id, reaction_id, options = {}) boolean_from_response :delete, "#{Repository.path repo}/issues/#{issue_id}/reactions/#{reaction_id}", options end + + # List reactions for a release + # + # @param repo [Integer, String, Hash, Repository] A GitHub repository + # @param id [Integer] The Release id + # + # @see https://docs.github.com/en/free-pro-team@latest/rest/reactions/reactions?apiVersion=2022-11-28#list-reactions-for-a-release + # + # @example + # @client.release_reactions("octokit/octokit.rb", 1) + # + # @return [Array] Array of Hashes representing the reactions. + def release_reactions(repo, release_id, options = {}) + get "#{Repository.path repo}/releases/#{release_id}/reactions", options + end + + # Create reaction for a release + # + # @param repo [Integer, String, Hash, Repository] A GitHub repository + # @param id [Integer] The Release id + # @param reaction [String] The Reaction + # + # @see https://docs.github.com/en/free-pro-team@latest/rest/reactions/reactions?apiVersion=2022-11-28#create-reaction-for-a-release + # @see https://developer.github.com/v3/reactions/#reaction-types + # + # @example + # @client.create_release_reaction("octokit/octokit.rb", 1) + # + # @return [] Hash representing the reaction. + def create_release_reaction(repo, release_id, reaction, options = {}) + options = options.merge(content: reaction) + post "#{Repository.path repo}/releases/#{release_id}/reactions", options + end + + # Delete a reaction for a release + # + # @param repo [Integer, String, Hash, Repository] A GitHub repository + # @param issue_id [Integer] The Release id + # @param reaction_id [Integer] The Reaction id + # + # @see https://docs.github.com/en/free-pro-team@latest/rest/reactions/reactions?apiVersion=2022-11-28#delete-a-release-reaction + # + # @example + # @client.delete_release_reaction("octokit/octokit.rb", 1, 2) + # + # @return [Boolean] Return true if reaction was deleted, false otherwise. + def delete_release_reaction(repo, release_id, reaction_id, options = {}) + boolean_from_response :delete, "#{Repository.path repo}/releases/#{release_id}/reactions/#{reaction_id}", options + end end end end diff --git a/spec/cassettes/Octokit_Client_Reactions/with_repository/with_release/_create_release_reaction/creates_a_reaction.json b/spec/cassettes/Octokit_Client_Reactions/with_repository/with_release/_create_release_reaction/creates_a_reaction.json new file mode 100644 index 000000000..99c3032a1 --- /dev/null +++ b/spec/cassettes/Octokit_Client_Reactions/with_repository/with_release/_create_release_reaction/creates_a_reaction.json @@ -0,0 +1,105 @@ +{ + "http_interactions": [ + { + "request": { + "method": "post", + "uri": "https://api.github.com/user/repos", + "body": { + "encoding": "UTF-8", + "base64_string": "eyJhdXRvX2luaXQiOnRydWUsIm5hbWUiOiJhbi1yZXBvIn0=\n" + }, + "headers": { + "Accept": [ + "application/vnd.github.v3+json" + ], + "User-Agent": [ + "Octokit Ruby Gem 7.2.0" + ], + "Content-Type": [ + "application/json" + ], + "Authorization": [ + "token <>" + ], + "Accept-Encoding": [ + "gzip;q=1.0,deflate;q=0.6,identity;q=0.3" + ] + } + }, + "response": { + "status": { + "code": 401, + "message": "Unauthorized" + }, + "headers": { + "Server": [ + "GitHub.com" + ], + "Date": [ + "Fri, 06 Oct 2023 19:31:44 GMT" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Content-Length": [ + "80" + ], + "X-Github-Media-Type": [ + "github.v3; format=json" + ], + "X-Ratelimit-Limit": [ + "60" + ], + "X-Ratelimit-Remaining": [ + "54" + ], + "X-Ratelimit-Reset": [ + "1696623381" + ], + "X-Ratelimit-Used": [ + "6" + ], + "X-Ratelimit-Resource": [ + "core" + ], + "Access-Control-Expose-Headers": [ + "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" + ], + "Access-Control-Allow-Origin": [ + "*" + ], + "Strict-Transport-Security": [ + "max-age=31536000; includeSubdomains; preload" + ], + "X-Frame-Options": [ + "deny" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Xss-Protection": [ + "0" + ], + "Referrer-Policy": [ + "origin-when-cross-origin, strict-origin-when-cross-origin" + ], + "Content-Security-Policy": [ + "default-src 'none'" + ], + "Vary": [ + "Accept-Encoding, Accept, X-Requested-With" + ], + "X-Github-Request-Id": [ + "EB06:EFB1:18C28C6:18FEB91:652060A0" + ] + }, + "body": { + "encoding": "UTF-8", + "base64_string": "eyJtZXNzYWdlIjoiQmFkIGNyZWRlbnRpYWxzIiwiZG9jdW1lbnRhdGlvbl91\ncmwiOiJodHRwczovL2RvY3MuZ2l0aHViLmNvbS9yZXN0In0=\n" + } + }, + "recorded_at": "Fri, 06 Oct 2023 19:31:44 GMT" + } + ], + "recorded_with": "VCR 6.2.0" +} \ No newline at end of file diff --git a/spec/cassettes/Octokit_Client_Reactions/with_repository/with_release/_delete_release_reaction/deletes_the_reaction.json b/spec/cassettes/Octokit_Client_Reactions/with_repository/with_release/_delete_release_reaction/deletes_the_reaction.json new file mode 100644 index 000000000..5e129fb5b --- /dev/null +++ b/spec/cassettes/Octokit_Client_Reactions/with_repository/with_release/_delete_release_reaction/deletes_the_reaction.json @@ -0,0 +1,105 @@ +{ + "http_interactions": [ + { + "request": { + "method": "post", + "uri": "https://api.github.com/user/repos", + "body": { + "encoding": "UTF-8", + "base64_string": "eyJhdXRvX2luaXQiOnRydWUsIm5hbWUiOiJhbi1yZXBvIn0=\n" + }, + "headers": { + "Accept": [ + "application/vnd.github.v3+json" + ], + "User-Agent": [ + "Octokit Ruby Gem 7.2.0" + ], + "Content-Type": [ + "application/json" + ], + "Authorization": [ + "token <>" + ], + "Accept-Encoding": [ + "gzip;q=1.0,deflate;q=0.6,identity;q=0.3" + ] + } + }, + "response": { + "status": { + "code": 401, + "message": "Unauthorized" + }, + "headers": { + "Server": [ + "GitHub.com" + ], + "Date": [ + "Fri, 06 Oct 2023 19:31:43 GMT" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Content-Length": [ + "80" + ], + "X-Github-Media-Type": [ + "github.v3; format=json" + ], + "X-Ratelimit-Limit": [ + "60" + ], + "X-Ratelimit-Remaining": [ + "56" + ], + "X-Ratelimit-Reset": [ + "1696623381" + ], + "X-Ratelimit-Used": [ + "4" + ], + "X-Ratelimit-Resource": [ + "core" + ], + "Access-Control-Expose-Headers": [ + "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" + ], + "Access-Control-Allow-Origin": [ + "*" + ], + "Strict-Transport-Security": [ + "max-age=31536000; includeSubdomains; preload" + ], + "X-Frame-Options": [ + "deny" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Xss-Protection": [ + "0" + ], + "Referrer-Policy": [ + "origin-when-cross-origin, strict-origin-when-cross-origin" + ], + "Content-Security-Policy": [ + "default-src 'none'" + ], + "Vary": [ + "Accept-Encoding, Accept, X-Requested-With" + ], + "X-Github-Request-Id": [ + "EB02:5F08:1AAEBB1:1AEAE30:6520609F" + ] + }, + "body": { + "encoding": "UTF-8", + "base64_string": "eyJtZXNzYWdlIjoiQmFkIGNyZWRlbnRpYWxzIiwiZG9jdW1lbnRhdGlvbl91\ncmwiOiJodHRwczovL2RvY3MuZ2l0aHViLmNvbS9yZXN0In0=\n" + } + }, + "recorded_at": "Fri, 06 Oct 2023 19:31:44 GMT" + } + ], + "recorded_with": "VCR 6.2.0" +} \ No newline at end of file diff --git a/spec/cassettes/Octokit_Client_Reactions/with_repository/with_release/_release_reactions/returns_an_Array_of_reactions.json b/spec/cassettes/Octokit_Client_Reactions/with_repository/with_release/_release_reactions/returns_an_Array_of_reactions.json new file mode 100644 index 000000000..551282e15 --- /dev/null +++ b/spec/cassettes/Octokit_Client_Reactions/with_repository/with_release/_release_reactions/returns_an_Array_of_reactions.json @@ -0,0 +1,105 @@ +{ + "http_interactions": [ + { + "request": { + "method": "post", + "uri": "https://api.github.com/user/repos", + "body": { + "encoding": "UTF-8", + "base64_string": "eyJhdXRvX2luaXQiOnRydWUsIm5hbWUiOiJhbi1yZXBvIn0=\n" + }, + "headers": { + "Accept": [ + "application/vnd.github.v3+json" + ], + "User-Agent": [ + "Octokit Ruby Gem 7.2.0" + ], + "Content-Type": [ + "application/json" + ], + "Authorization": [ + "token <>" + ], + "Accept-Encoding": [ + "gzip;q=1.0,deflate;q=0.6,identity;q=0.3" + ] + } + }, + "response": { + "status": { + "code": 401, + "message": "Unauthorized" + }, + "headers": { + "Server": [ + "GitHub.com" + ], + "Date": [ + "Fri, 06 Oct 2023 19:31:44 GMT" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Content-Length": [ + "80" + ], + "X-Github-Media-Type": [ + "github.v3; format=json" + ], + "X-Ratelimit-Limit": [ + "60" + ], + "X-Ratelimit-Remaining": [ + "55" + ], + "X-Ratelimit-Reset": [ + "1696623381" + ], + "X-Ratelimit-Used": [ + "5" + ], + "X-Ratelimit-Resource": [ + "core" + ], + "Access-Control-Expose-Headers": [ + "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" + ], + "Access-Control-Allow-Origin": [ + "*" + ], + "Strict-Transport-Security": [ + "max-age=31536000; includeSubdomains; preload" + ], + "X-Frame-Options": [ + "deny" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Xss-Protection": [ + "0" + ], + "Referrer-Policy": [ + "origin-when-cross-origin, strict-origin-when-cross-origin" + ], + "Content-Security-Policy": [ + "default-src 'none'" + ], + "Vary": [ + "Accept-Encoding, Accept, X-Requested-With" + ], + "X-Github-Request-Id": [ + "EB04:0FCF:186EA04:18AA590:652060A0" + ] + }, + "body": { + "encoding": "UTF-8", + "base64_string": "eyJtZXNzYWdlIjoiQmFkIGNyZWRlbnRpYWxzIiwiZG9jdW1lbnRhdGlvbl91\ncmwiOiJodHRwczovL2RvY3MuZ2l0aHViLmNvbS9yZXN0In0=\n" + } + }, + "recorded_at": "Fri, 06 Oct 2023 19:31:44 GMT" + } + ], + "recorded_with": "VCR 6.2.0" +} \ No newline at end of file diff --git a/spec/octokit/client/reactions_spec.rb b/spec/octokit/client/reactions_spec.rb index 738c998df..ef7e74035 100644 --- a/spec/octokit/client/reactions_spec.rb +++ b/spec/octokit/client/reactions_spec.rb @@ -144,5 +144,35 @@ end # .create_pull_request_review_comment_reaction end # with pull request review comment end # with pull request + + context 'with release' do + before do + @release = @client.create_release(@repo.full_name, 'v1.0.0') + @reaction = @client.create_release_reaction(@repo.full_name, @release.id, '+1') + end + + describe '.release_reactions' do + it 'returns an Array of reactions' do + reactions = @client.release_reactions(@repo.full_name, @release.id) + expect(reactions).to be_kind_of Array + assert_requested :get, github_url("/repos/#{@repo.full_name}/releases/#{@release.id}/reactions") + end + end # .release_reactions + + describe '.create_release_reaction' do + it 'creates a reaction' do + reaction = @client.create_release_reaction(@repo.full_name, @release.id, '+1') + expect(reaction.content).to eql('+1') + assert_requested :post, github_url("/repos/#{@repo.full_name}/releases/#{@release.id}/reactions") + end + end # .create_release_reaction + + describe '.delete_release_reaction' do + it 'deletes the reaction' do + @client.delete_issue_reaction(@repo.full_name, @release.id, @reaction.id) + assert_requested :delete, github_url("/repos/#{@repo.full_name}/releases/#{@release.id}/reactions/#{@reaction.id}") + end + end # .delete_release_reaction + end # with release end # with repository end