Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1278 from zerok/feature/listmergerequests-approve…
Browse files Browse the repository at this point in the history
…dbyids

Add ApprovedByIDs field to ListMergeRequestsOptions
  • Loading branch information
svanharmelen authored Jan 4, 2022
2 parents 4224dba + 0d3ef19 commit 65e314f
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 26 deletions.
53 changes: 27 additions & 26 deletions merge_requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,32 +140,33 @@ func (m MergeRequestDiffVersion) String() string {
// https://docs.gitlab.com/ce/api/merge_requests.html#list-merge-requests
type ListMergeRequestsOptions struct {
ListOptions
State *string `url:"state,omitempty" json:"state,omitempty"`
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"`
View *string `url:"view,omitempty" json:"view,omitempty"`
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
NotLabels Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"`
WithLabelsDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"`
WithMergeStatusRecheck *bool `url:"with_merge_status_recheck,omitempty" json:"with_merge_status_recheck,omitempty"`
CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"`
AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"`
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
ReviewerID *int `url:"reviewer_id,omitempty" json:"reviewer_id,omitempty"`
ReviewerUsername *string `url:"reviewer_username,omitempty" json:"reviewer_username,omitempty"`
MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"`
TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"`
Search *string `url:"search,omitempty" json:"search,omitempty"`
In *string `url:"in,omitempty" json:"in,omitempty"`
Draft *bool `url:"draft,omitempty" json:"draft,omitempty"`
WIP *string `url:"wip,omitempty" json:"wip,omitempty"`
State *string `url:"state,omitempty" json:"state,omitempty"`
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"`
View *string `url:"view,omitempty" json:"view,omitempty"`
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
NotLabels Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"`
WithLabelsDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"`
WithMergeStatusRecheck *bool `url:"with_merge_status_recheck,omitempty" json:"with_merge_status_recheck,omitempty"`
CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"`
AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"`
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
ApprovedByIDs *ApproverIDsValue `url:"approved_by_ids,omitempty" json:"approved_by_ids,omitempty"`
ReviewerID *int `url:"reviewer_id,omitempty" json:"reviewer_id,omitempty"`
ReviewerUsername *string `url:"reviewer_username,omitempty" json:"reviewer_username,omitempty"`
MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"`
TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"`
Search *string `url:"search,omitempty" json:"search,omitempty"`
In *string `url:"in,omitempty" json:"in,omitempty"`
Draft *bool `url:"draft,omitempty" json:"draft,omitempty"`
WIP *string `url:"wip,omitempty" json:"wip,omitempty"`
}

// ListMergeRequests gets all merge requests. The state parameter can be used
Expand Down
26 changes: 26 additions & 0 deletions merge_requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"testing"
"time"

"github.com/google/go-querystring/query"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -245,3 +246,28 @@ func TestGetIssuesClosedOnMerge_Jira(t *testing.T) {
assert.Equal(t, "PROJECT-123", issues[0].ExternalID)
assert.Equal(t, "Title of this issue", issues[0].Title)
}

func TestIntSliceOrString(t *testing.T) {
t.Run("any", func(t *testing.T) {
opts := &ListMergeRequestsOptions{}
opts.ApprovedByIDs = ApproverIDs(ApproverIDAny)
q, err := query.Values(opts)
assert.NoError(t, err)
assert.Equal(t, "Any", q.Get("approved_by_ids"))
})
t.Run("none", func(t *testing.T) {
opts := &ListMergeRequestsOptions{}
opts.ApprovedByIDs = ApproverIDs(ApproverIDNone)
q, err := query.Values(opts)
assert.NoError(t, err)
assert.Equal(t, "None", q.Get("approved_by_ids"))
})
t.Run("ids", func(t *testing.T) {
opts := &ListMergeRequestsOptions{}
opts.ApprovedByIDs = ApproverIDs([]int{1, 2, 3})
q, err := query.Values(opts)
assert.NoError(t, err)
includedIDs := q["approved_by_ids[]"]
assert.Equal(t, []string{"1", "2", "3"}, includedIDs)
})
}
47 changes: 47 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"errors"
"fmt"
"net/url"
"strconv"
"time"
)

Expand Down Expand Up @@ -78,6 +79,52 @@ func AccessLevel(v AccessLevelValue) *AccessLevelValue {
return p
}

// ApproverIDValue represents an approver ID value within GitLab.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-requests
type ApproverIDValue string

// List of available approver ID values.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-requests
const (
ApproverIDAny ApproverIDValue = "Any"
ApproverIDNone ApproverIDValue = "None"
)

// ApproverIDsValue represents an approvers ID value within GitLab.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-requests
type ApproverIDsValue struct {
value interface{}
}

func ApproverIDs(v interface{}) *ApproverIDsValue {
switch v.(type) {
case ApproverIDValue, []int:
return &ApproverIDsValue{value: v}
default:
panic("Unsupported value passed as approver ID")
}
}

func (a *ApproverIDsValue) EncodeValues(key string, v *url.Values) error {
switch value := a.value.(type) {
case ApproverIDValue:
v.Set(key, string(value))
case []int:
v.Del(key)
v.Del(key + "[]")
for _, id := range value {
v.Add(key+"[]", strconv.Itoa(id))
}
}
return nil
}

// AvailabilityValue represents an availability value within GitLab.
type AvailabilityValue string

Expand Down

0 comments on commit 65e314f

Please sign in to comment.