diff --git a/merge_requests.go b/merge_requests.go index 822b0ded6..e446da537 100644 --- a/merge_requests.go +++ b/merge_requests.go @@ -509,6 +509,40 @@ func (s *MergeRequestsService) GetMergeRequestParticipants(pid interface{}, merg return ps, resp, nil } +// MergeRequestReviewer represents a GitLab merge request reviewer. +// +// GitLab API docs: https://docs.gitlab.com/ee/api/merge_requests.html#get-single-merge-request-reviewers +type MergeRequestReviewer struct { + User *BasicUser `json:"user"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` +} + +// GetMergeRequestReviewers gets a list of merge request reviewers. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/merge_requests.html#get-single-merge-request-reviewers +func (s *MergeRequestsService) GetMergeRequestReviewers(pid interface{}, mergeRequest int, options ...RequestOptionFunc) ([]*MergeRequestReviewer, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/reviewers", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var ps []*MergeRequestReviewer + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + // ListMergeRequestPipelines gets all pipelines for the provided merge request. // // GitLab API docs: diff --git a/merge_requests_test.go b/merge_requests_test.go index ee6452bf3..2fee59844 100644 --- a/merge_requests_test.go +++ b/merge_requests_test.go @@ -245,6 +245,34 @@ func TestGetMergeRequestParticipants(t *testing.T) { } } +func TestGetMergeRequestReviewers(t *testing.T) { + mux, client := setup(t) + + mux.HandleFunc("/api/v4/projects/1/merge_requests/5/reviewers", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + testURL(t, r, "/api/v4/projects/1/merge_requests/5/reviewers") + + fmt.Fprint(w, `[{"user":{"id":1,"name":"John Doe1","username":"user1","state":"active","avatar_url":"http://www.gravatar.com/avatar/c922747a93b40d1ea88262bf1aebee62?s=80&d=identicon","web_url":"http://localhost/user1"},"state":"unreviewed","created_at":"2022-07-27T17:03:27.684Z"},{"user":{"id":2,"name":"John Doe2","username":"user2","state":"active","avatar_url":"http://www.gravatar.com/avatar/10fc7f102be8de7657fb4d80898bbfe3?s=80&d=identicon","web_url":"http://localhost/user2"},"state":"reviewed","created_at":"2022-07-27T17:03:27.684Z"}]`) + }) + + mergeRequestReviewers, _, err := client.MergeRequests.GetMergeRequestReviewers("1", 5) + if err != nil { + log.Fatal(err) + } + + createdAt := time.Date(2022, 07, 27, 17, 3, 27, 684000000, time.UTC) + user1 := BasicUser{ID: 1, Name: "John Doe1", Username: "user1", State: "active", AvatarURL: "http://www.gravatar.com/avatar/c922747a93b40d1ea88262bf1aebee62?s=80&d=identicon", WebURL: "http://localhost/user1"} + user2 := BasicUser{ID: 2, Name: "John Doe2", Username: "user2", State: "active", AvatarURL: "http://www.gravatar.com/avatar/10fc7f102be8de7657fb4d80898bbfe3?s=80&d=identicon", WebURL: "http://localhost/user2"} + + assert.Len(t, mergeRequestReviewers, 2) + assert.Equal(t, "unreviewed", mergeRequestReviewers[0].State) + require.Equal(t, &user1, mergeRequestReviewers[0].User) + require.Equal(t, &createdAt, mergeRequestReviewers[0].CreatedAt) + assert.Equal(t, "reviewed", mergeRequestReviewers[1].State) + require.Equal(t, &user2, mergeRequestReviewers[1].User) + require.Equal(t, &createdAt, mergeRequestReviewers[1].CreatedAt) +} + func TestGetIssuesClosedOnMerge_Jira(t *testing.T) { mux, client := setup(t) mux.HandleFunc("/api/v4/projects/1/merge_requests/1/closes_issues", func(w http.ResponseWriter, r *http.Request) {