Repository: xanzy/go-gitlab
Pull request #1764 (2023-07-26 14:58:36)

Epic Boards
See #1763


Patch:
diff --git a/gitlab.go b/gitlab.go
index 4f30826..322f1a4 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 0000000..fd8cfd8
--- /dev/null
+++ b/group_epic_boards.go
@@ -0,0 +1,104 @@
+//
+// 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
+}
+
+// GetGroupEpicBoard gets a single epic board of a group.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/group_epic_boards.html#single-group-epic-board
+func (s *GroupEpicBoardsService) GetGroupEpicBoard(gid interface{}, board int, options ...RequestOptionFunc) (*GroupEpicBoard, *Response, error) {
+	group, err := parseID(gid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf("groups/%s/epic_boards/%d", PathEscape(group), board)
+
+	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	gib := new(GroupEpicBoard)
+	resp, err := s.client.Do(req, gib)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gib, resp, nil
+}


Test patch:
diff --git a/group_epic_boards_test.go b/group_epic_boards_test.go
new file mode 100644
index 0000000..680558e
--- /dev/null
+++ b/group_epic_boards_test.go
@@ -0,0 +1,279 @@
+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)
+}
+
+func TestGroupEpicBoardsService_GetGroupEpicBoard(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/groups/5/epic_boards/1", 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"
+			},
+			"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,
+			},
+		},
+	}
+
+	gib, resp, err := client.GroupEpicBoards.GetGroupEpicBoard(5, 1, nil, nil)
+	require.NoError(t, err)
+	require.NotNil(t, resp)
+	require.Equal(t, want, gib)
+
+	gib, resp, err = client.GroupEpicBoards.GetGroupEpicBoard(5.01, 1, 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, gib)
+
+	gib, resp, err = client.GroupEpicBoards.GetGroupEpicBoard(5, 1, nil, nil, errorOption)
+	require.EqualError(t, err, "RequestOptionFunc returns an error")
+	require.Nil(t, resp)
+	require.Nil(t, gib)
+
+	gib, resp, err = client.GroupEpicBoards.GetGroupEpicBoard(3, 1, nil, nil)
+	require.Error(t, err)
+	require.Nil(t, gib)
+	require.Equal(t, http.StatusNotFound, resp.StatusCode)
+}