Repository: xanzy/go-gitlab
Pull request #1794 (2023-09-14 13:32:03)

Add GetMergeRequestReviewers
This adds support for [Get single merge request reviewers](https://docs.gitlab.com/ee/api/merge_requests.html#get-single-merge-request-reviewers).


Patch:
diff --git a/merge_requests.go b/merge_requests.go
index 822b0de..e446da5 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:


Test patch:
diff --git a/merge_requests_test.go b/merge_requests_test.go
index ee6452b..2fee598 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) {