diff --git a/gitlab.go b/gitlab.go index 4f308260a..322f1a4a0 100644 --- a/gitlab.go +++ b/gitlab.go @@ -137,6 +137,7 @@ type Client struct { GroupAccessTokens *GroupAccessTokensService GroupBadges *GroupBadgesService GroupCluster *GroupClustersService + GroupEpicBoards *GroupEpicBoardsService GroupImportExport *GroupImportExportService GroupIssueBoards *GroupIssueBoardsService GroupIterations *GroupIterationsService @@ -357,6 +358,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) { c.GroupAccessTokens = &GroupAccessTokensService{client: c} c.GroupBadges = &GroupBadgesService{client: c} c.GroupCluster = &GroupClustersService{client: c} + c.GroupEpicBoards = &GroupEpicBoardsService{client: c} c.GroupImportExport = &GroupImportExportService{client: c} c.GroupIssueBoards = &GroupIssueBoardsService{client: c} c.GroupIterations = &GroupIterationsService{client: c} diff --git a/group_epic_boards.go b/group_epic_boards.go new file mode 100644 index 000000000..d951fa8f1 --- /dev/null +++ b/group_epic_boards.go @@ -0,0 +1,79 @@ +// +// Copyright 2021, Patrick Webster +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +// GroupEpicBoardsService handles communication with the group epic board +// related methods of the GitLab API. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/group_epic_boards.html +type GroupEpicBoardsService struct { + client *Client +} + +// GroupEpicBoard represents a GitLab group epic board. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/group_epic_boards.html +type GroupEpicBoard struct { + ID int `json:"id"` + Name string `json:"name"` + Group *Group `json:"group"` + Labels []*LabelDetails `json:"labels"` + Lists []*BoardList `json:"lists"` +} + +func (b GroupEpicBoard) String() string { + return Stringify(b) +} + +// ListGroupEpicBoardsOptions represents the available +// ListGroupEpicBoards() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/group_epic_boards.html#list-all-epic-boards-in-a-group +type ListGroupEpicBoardsOptions ListOptions + +// ListGroupEpicBoards gets a list of all epic boards in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/group_epic_boards.html#list-all-epic-boards-in-a-group +func (s *GroupEpicBoardsService) ListGroupEpicBoards(gid interface{}, opt *ListGroupEpicBoardsOptions, options ...RequestOptionFunc) ([]*GroupEpicBoard, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epic_boards", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gs []*GroupEpicBoard + resp, err := s.client.Do(req, &gs) + if err != nil { + return nil, resp, err + } + + return gs, resp, nil +} diff --git a/group_epic_boards_test.go b/group_epic_boards_test.go new file mode 100644 index 000000000..ebced7b0a --- /dev/null +++ b/group_epic_boards_test.go @@ -0,0 +1,146 @@ +package gitlab + +import ( + "fmt" + "net/http" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGroupEpicBoardsService_ListGroupEpicBoards(t *testing.T) { + mux, client := setup(t) + + mux.HandleFunc("/api/v4/groups/5/epic_boards", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + fmt.Fprintf(w, ` + [ + { + "id": 1, + "name": "group epic board", + "group": { + "id": 5, + "name": "Documentcloud", + "web_url": "http://example.com/groups/documentcloud" + }, + "hide_backlog_list": false, + "hide_closed_list": false, + "labels": [ + { + "id": 1, + "name": "Board Label", + "color": "#c21e56", + "group_id": 5, + "description": "label applied to the epic board" + } + ], + "lists": [ + { + "id": 1, + "label": { + "id": 69, + "name": "Testing", + "color": "#F0AD4E", + "description": null + }, + "position": 1, + "list_type": "label" + }, + { + "id": 2, + "label": { + "id": 70, + "name": "Ready", + "color": "#FF0000", + "description": null + }, + "position": 2, + "list_type": "label" + }, + { + "id": 3, + "label": { + "id": 71, + "name": "Production", + "color": "#FF5F00", + "description": null + }, + "position": 3, + "list_type": "label" + } + ] + } + ] + `) + }) + + want := []*GroupEpicBoard{{ + ID: 1, + Name: "group epic board", + Group: &Group{ + ID: 5, + Name: "Documentcloud", + WebURL: "http://example.com/groups/documentcloud", + }, + Labels: []*LabelDetails{ + { + ID: 1, + Name: "Board Label", + Color: "#c21e56", + Description: "label applied to the epic board", + }, + }, + Lists: []*BoardList{ + { + ID: 1, + Label: &Label{ + ID: 69, + Name: "Testing", + Color: "#F0AD4E", + Description: "", + }, + Position: 1, + }, + { + ID: 2, + Label: &Label{ + ID: 70, + Name: "Ready", + Color: "#FF0000", + Description: "", + }, + Position: 2, + }, + { + ID: 3, + Label: &Label{ + ID: 71, + Name: "Production", + Color: "#FF5F00", + Description: "", + }, + Position: 3, + }, + }, + }} + + gibs, resp, err := client.GroupEpicBoards.ListGroupEpicBoards(5, nil, nil) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, want, gibs) + + gibs, resp, err = client.GroupEpicBoards.ListGroupEpicBoards(5.01, nil, nil) + require.EqualError(t, err, "invalid ID type 5.01, the ID must be an int or a string") + require.Nil(t, resp) + require.Nil(t, gibs) + + gibs, resp, err = client.GroupEpicBoards.ListGroupEpicBoards(5, nil, nil, errorOption) + require.EqualError(t, err, "RequestOptionFunc returns an error") + require.Nil(t, resp) + require.Nil(t, gibs) + + gibs, resp, err = client.GroupEpicBoards.ListGroupEpicBoards(3, nil, nil) + require.Error(t, err) + require.Nil(t, gibs) + require.Equal(t, http.StatusNotFound, resp.StatusCode) +}