Skip to content
117 changes: 95 additions & 22 deletions github/reactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,28 +116,16 @@ func (s ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo
func (s *ReactionsService) DeleteCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions/%v", owner, repo, commentID, reactionID)

return s.deleteCommentReaction(ctx, u)
return s.deleteReaction(ctx, u)
}

// DeleteCommentReactionByRepoID deletes the reaction for a commit comment by repository ID.
// DeleteCommentReactionByID deletes the reaction for a commit comment by repository ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-commit-comment-reaction
func (s *ReactionsService) DeleteCommentReactionByRepoID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) {
func (s *ReactionsService) DeleteCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) {
u := fmt.Sprintf("repositories/%v/comments/%v/reactions/%v", repoID, commentID, reactionID)

return s.deleteCommentReaction(ctx, u)
}

func (s ReactionsService) deleteCommentReaction(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest(http.MethodDelete, url, nil)
if err != nil {
return nil, err
}

// TODO: remove custom Accept headers when APIs fully launch.
req.Header.Set("Accept", mediaTypeReactionsPreview)

return s.client.Do(ctx, req, nil)
return s.deleteReaction(ctx, u)
}

// ListIssueReactions lists the reactions for an issue.
Expand Down Expand Up @@ -194,6 +182,24 @@ func (s ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo s
return m, resp, nil
}

// DeleteIssueReaction deletes the reaction to an issue.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction
func (s *ReactionsService) DeleteIssueReaction(ctx context.Context, owner, repo string, issueNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repos/%v/%v/issues/%v/reactions/%v", owner, repo, issueNumber, reactionID)

return s.deleteReaction(ctx, url)
}

// DeleteIssueReactionByID deletes the reaction to an issue by repository ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-reaction
func (s *ReactionsService) DeleteIssueReactionByID(ctx context.Context, repoID, issueNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repositories/%v/issues/%v/reactions/%v", repoID, issueNumber, reactionID)

return s.deleteReaction(ctx, url)
}

// ListIssueCommentReactions lists the reactions for an issue comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment
Expand Down Expand Up @@ -248,6 +254,24 @@ func (s ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner,
return m, resp, nil
}

// DeleteIssueCommentReaction deletes the reaction to an issue comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction
func (s *ReactionsService) DeleteIssueCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions/%v", owner, repo, commentID, reactionID)

return s.deleteReaction(ctx, url)
}

// DeleteIssueCommentReactionByID deletes the reaction to an issue comment by repository ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-an-issue-comment-reaction
func (s *ReactionsService) DeleteIssueCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repositories/%v/issues/comments/%v/reactions/%v", repoID, commentID, reactionID)

return s.deleteReaction(ctx, url)
}

// ListPullRequestCommentReactions lists the reactions for a pull request review comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment
Expand Down Expand Up @@ -302,6 +326,24 @@ func (s ReactionsService) CreatePullRequestCommentReaction(ctx context.Context,
return m, resp, nil
}

// DeletePullRequestCommentReaction deletes the reaction to a pull request review comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction
func (s *ReactionsService) DeletePullRequestCommentReaction(ctx context.Context, owner, repo string, commentID, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions/%v", owner, repo, commentID, reactionID)

return s.deleteReaction(ctx, url)
}

// DeletePullRequestCommentReactionByID deletes the reaction to a pull request review comment by repository ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-a-pull-request-comment-reaction
func (s *ReactionsService) DeletePullRequestCommentReactionByID(ctx context.Context, repoID, commentID, reactionID int64) (*Response, error) {
url := fmt.Sprintf("repositories/%v/pulls/comments/%v/reactions/%v", repoID, commentID, reactionID)

return s.deleteReaction(ctx, url)
}

// ListTeamDiscussionReactions lists the reactions for a team discussion.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion
Expand Down Expand Up @@ -352,6 +394,24 @@ func (s *ReactionsService) CreateTeamDiscussionReaction(ctx context.Context, tea
return m, resp, nil
}

// DeleteTeamDiscussionReaction deletes the reaction to a team discussion.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction
func (s *ReactionsService) DeleteTeamDiscussionReaction(ctx context.Context, org, teamSlug string, discussionNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/reactions/%v", org, teamSlug, discussionNumber, reactionID)

return s.deleteReaction(ctx, url)
}

// DeleteTeamDiscussionReactionByOrgIDAndTeamID deletes the reaction to a team discussion by organization ID and team ID.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-reaction
func (s *ReactionsService) DeleteTeamDiscussionReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/reactions/%v", orgID, teamID, discussionNumber, reactionID)

return s.deleteReaction(ctx, url)
}

// ListTeamDiscussionCommentReactions lists the reactions for a team discussion comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-team-discussion-comment
Expand Down Expand Up @@ -401,18 +461,31 @@ func (s *ReactionsService) CreateTeamDiscussionCommentReaction(ctx context.Conte
return m, resp, nil
}

// DeleteReaction deletes a reaction.
// DeleteTeamDiscussionCommentReaction deletes the reaction to a team discussion comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction
func (s *ReactionsService) DeleteTeamDiscussionCommentReaction(ctx context.Context, org, teamSlug string, discussionNumber, commentNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v/reactions/%v", org, teamSlug, discussionNumber, commentNumber, reactionID)

return s.deleteReaction(ctx, url)
}

// DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID deletes the reaction to a team discussion comment by organization ID and team ID.
//
// GitHub API docs: https://developer.github.com/v3/reaction/reactions/#delete-a-reaction-archive
func (s *ReactionsService) DeleteReaction(ctx context.Context, id int64) (*Response, error) {
u := fmt.Sprintf("reactions/%v", id)
// GitHub API docs: https://developer.github.com/v3/reactions/#delete-team-discussion-comment-reaction
func (s *ReactionsService) DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID(ctx context.Context, orgID, teamID, discussionNumber, commentNumber int, reactionID int64) (*Response, error) {
url := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v/reactions/%v", orgID, teamID, discussionNumber, commentNumber, reactionID)

return s.deleteReaction(ctx, url)
}

req, err := s.client.NewRequest("DELETE", u, nil)
func (s ReactionsService) deleteReaction(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest(http.MethodDelete, url, nil)
if err != nil {
return nil, err
}

// TODO: remove custom Accept header when this API fully launches.
// TODO: remove custom Accept headers when APIs fully launch.
req.Header.Set("Accept", mediaTypeReactionsPreview)

return s.client.Do(ctx, req, nil)
Expand Down
168 changes: 156 additions & 12 deletions github/reactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,50 +325,194 @@ func TestReactionService_CreateTeamDiscussionCommentReaction(t *testing.T) {
}
}

func TestReactionsService_DeleteReaction(t *testing.T) {
func TestReactionsService_DeleteCommitCommentReaction(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/reactions/1", func(w http.ResponseWriter, r *http.Request) {
mux.HandleFunc("/repos/o/r/comments/1/reactions/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteReaction(context.Background(), 1); err != nil {
t.Errorf("DeleteReaction returned error: %v", err)
if _, err := client.Reactions.DeleteCommentReaction(context.Background(), "o", "r", 1, 2); err != nil {
t.Errorf("DeleteCommentReaction returned error: %v", err)
}
}

func TestReactionsService_DeleteCommitCommentReaction(t *testing.T) {
func TestReactionsService_DeleteCommitCommentReactionByRepoID(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/comments/1/reactions/2", func(w http.ResponseWriter, r *http.Request) {
mux.HandleFunc("/repositories/1/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteCommentReaction(context.Background(), "o", "r", 1, 2); err != nil {
t.Errorf("DeleteCommentReaction returned error: %v", err)
if _, err := client.Reactions.DeleteCommentReactionByID(context.Background(), 1, 2, 3); err != nil {
t.Errorf("DeleteCommentReactionByRepoID returned error: %v", err)
}
}

func TestReactionsService_DeleteCommitCommentReactionByRepoID(t *testing.T) {
func TestReactionsService_DeleteIssueReaction(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repositories/1/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) {
mux.HandleFunc("/repos/o/r/issues/1/reactions/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteCommentReactionByRepoID(context.Background(), 1, 2, 3); err != nil {
t.Errorf("DeleteCommentReactionByRepoID returned error: %v", err)
if _, err := client.Reactions.DeleteIssueReaction(context.Background(), "o", "r", 1, 2); err != nil {
t.Errorf("DeleteIssueReaction returned error: %v", err)
}
}

func TestReactionsService_DeleteIssueReactionByRepoID(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repositories/1/issues/2/reactions/3", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteIssueReactionByID(context.Background(), 1, 2, 3); err != nil {
t.Errorf("DeleteIssueReactionByRepoID returned error: %v", err)
}
}

func TestReactionsService_DeleteIssueCommentReaction(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/issues/comments/1/reactions/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteIssueCommentReaction(context.Background(), "o", "r", 1, 2); err != nil {
t.Errorf("DeleteIssueCommentReaction returned error: %v", err)
}
}

func TestReactionsService_DeleteIssueCommentReactionByRepoID(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repositories/1/issues/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteIssueCommentReactionByID(context.Background(), 1, 2, 3); err != nil {
t.Errorf("DeleteIssueCommentReactionByRepoID returned error: %v", err)
}
}

func TestReactionsService_DeletePullRequestCommentReaction(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/pulls/comments/1/reactions/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeletePullRequestCommentReaction(context.Background(), "o", "r", 1, 2); err != nil {
t.Errorf("DeletePullRequestCommentReaction returned error: %v", err)
}
}

func TestReactionsService_DeletePullRequestCommentReactionByRepoID(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repositories/1/pulls/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeletePullRequestCommentReactionByID(context.Background(), 1, 2, 3); err != nil {
t.Errorf("DeletePullRequestCommentReactionByRepoID returned error: %v", err)
}
}

func TestReactionsService_DeleteTeamDiscussionReaction(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/orgs/o/teams/s/discussions/1/reactions/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteTeamDiscussionReaction(context.Background(), "o", "s", 1, 2); err != nil {
t.Errorf("DeleteTeamDiscussionReaction returned error: %v", err)
}
}

func TestReactionsService_DeleteTeamDiscussionReactionByTeamIDAndOrgID(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/organizations/1/team/2/discussions/3/reactions/4", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteTeamDiscussionReactionByOrgIDAndTeamID(context.Background(), 1, 2, 3, 4); err != nil {
t.Errorf("DeleteTeamDiscussionReactionByTeamIDAndOrgID returned error: %v", err)
}
}

func TestReactionsService_DeleteTeamDiscussionCommentReaction(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/orgs/o/teams/s/discussions/1/comments/2/reactions/3", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteTeamDiscussionCommentReaction(context.Background(), "o", "s", 1, 2, 3); err != nil {
t.Errorf("DeleteTeamDiscussionCommentReaction returned error: %v", err)
}
}

func TestReactionsService_DeleteTeamDiscussionCommentReactionByTeamIDAndOrgID(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/organizations/1/team/2/discussions/3/comments/4/reactions/5", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)

w.WriteHeader(http.StatusNoContent)
})

if _, err := client.Reactions.DeleteTeamDiscussionCommentReactionByOrgIDAndTeamID(context.Background(), 1, 2, 3, 4, 5); err != nil {
t.Errorf("DeleteTeamDiscussionCommentReactionByTeamIDAndOrgID returned error: %v", err)
}
}