Repository: ctreminiom/go-atlassian
Pull request #75 (2021-11-09 04:32:20)

:zap: Added the agile.board.gets() method


Patch:
diff --git a/jira/agile/board.go b/jira/agile/board.go
index 08a0f73..2a94e10 100644
--- a/jira/agile/board.go
+++ b/jira/agile/board.go
@@ -81,6 +81,7 @@ func (b *BoardService) Create(ctx context.Context, payload *BoardPayloadScheme)
 type BoardPageScheme struct {
 	MaxResults int            `json:"maxResults"`
 	StartAt    int            `json:"startAt"`
+	Total      int            `json:"total"`
 	IsLast     bool           `json:"isLast"`
 	Values     []*BoardScheme `json:"values"`
 }
@@ -808,3 +809,84 @@ func (b *BoardService) Delete(ctx context.Context, boardID int) (response *Respo
 
 	return
 }
+
+type GetBoardsOptions struct {
+	BoardType               string
+	BoardName               string
+	ProjectKeyOrID          string
+	AccountIDLocation       string
+	ProjectIDLocation       string
+	IncludePrivate          bool
+	NegateLocationFiltering bool
+	OrderBy                 string
+	Expand                  string
+	FilterID                int
+}
+
+// Gets returns all boards. This only includes boards that the user has permission to view.
+// Docs: https://developer.atlassian.com/cloud/jira/software/rest/api-group-other-operations/#api-agile-1-0-board-get
+func (b *BoardService) Gets(ctx context.Context, opts *GetBoardsOptions, startAt, maxResults int) (result *BoardPageScheme, response *ResponseScheme, err error) {
+
+	params := url.Values{}
+	params.Add("startAt", strconv.Itoa(startAt))
+	params.Add("maxResults", strconv.Itoa(maxResults))
+
+	if opts != nil {
+
+		if opts.BoardType != "" {
+			params.Add("type", opts.BoardType)
+		}
+
+		if opts.BoardName != "" {
+			params.Add("name", opts.BoardName)
+		}
+
+		if opts.ProjectKeyOrID != "" {
+			params.Add("projectKeyOrId", opts.ProjectKeyOrID)
+		}
+
+		if opts.AccountIDLocation != "" {
+			params.Add("accountIdLocation", opts.AccountIDLocation)
+		}
+
+		if opts.ProjectIDLocation != "" {
+			params.Add("projectLocation", opts.ProjectIDLocation)
+		}
+
+		if opts.IncludePrivate {
+			params.Add("includePrivate", "true")
+		}
+
+		if opts.NegateLocationFiltering {
+			params.Add("negateLocationFiltering", "true")
+		}
+
+		if opts.OrderBy != "" {
+			params.Add("orderBy", opts.OrderBy)
+		}
+
+		if opts.Expand != "" {
+			params.Add("expand", opts.Expand)
+		}
+
+		if opts.FilterID != 0 {
+			params.Add("filterId", strconv.Itoa(opts.FilterID))
+		}
+	}
+
+	var endpoint = fmt.Sprintf("/rest/agile/1.0/board?%v", params.Encode())
+
+	request, err := b.client.newRequest(ctx, http.MethodGet, endpoint, nil)
+	if err != nil {
+		return
+	}
+
+	request.Header.Set("Accept", "application/json")
+
+	response, err = b.client.Call(request, &result)
+	if err != nil {
+		return nil, response, err
+	}
+
+	return
+}


Test patch:
diff --git a/jira/agile/board_test.go b/jira/agile/board_test.go
index c48b401..bf00ca7 100644
--- a/jira/agile/board_test.go
+++ b/jira/agile/board_test.go
@@ -339,6 +339,209 @@ func TestBoardService_Create(t *testing.T) {
 
 }
 
+func TestBoardService_Gets(t *testing.T) {
+
+	testCases := []struct {
+		name                string
+		opts                *GetBoardsOptions
+		startAt, maxResults int
+		mockFile            string
+		wantHTTPMethod      string
+		endpoint            string
+		context             context.Context
+		wantHTTPCodeReturn  int
+		wantErr             bool
+	}{
+		{
+			name: "GetBoardsTheParametersAreCorrect",
+			opts: &GetBoardsOptions{
+				BoardType:               "scrum",
+				BoardName:               "board-name",
+				ProjectKeyOrID:          "CID",
+				AccountIDLocation:       "account-id-sample",
+				ProjectIDLocation:       "2345",
+				IncludePrivate:          true,
+				NegateLocationFiltering: true,
+				OrderBy:                 "name",
+				Expand:                  "permissions",
+				FilterID:                111234,
+			},
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-boards-by-filter-id.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/agile/1.0/board?accountIdLocation=account-id-sample&expand=permissions&filterId=111234&includePrivate=true&maxResults=50&name=board-name&negateLocationFiltering=true&orderBy=name&projectKeyOrId=CID&projectLocation=2345&startAt=0&type=scrum",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name: "GetBoardByFilterWhenTheRequestMethodIsIncorrect",
+			opts: &GetBoardsOptions{
+				BoardType:               "scrum",
+				BoardName:               "board-name",
+				ProjectKeyOrID:          "CID",
+				AccountIDLocation:       "account-id-sample",
+				ProjectIDLocation:       "2345",
+				IncludePrivate:          true,
+				NegateLocationFiltering: true,
+				OrderBy:                 "name",
+				Expand:                  "permissions",
+				FilterID:                111234,
+			},
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-board.json",
+			wantHTTPCodeReturn: http.StatusOK,
+			wantHTTPMethod:     http.MethodHead,
+			endpoint:           "/rest/agile/1.0/board?accountIdLocation=account-id-sample&expand=permissions&filterId=111234&includePrivate=true&maxResults=50&name=board-name&negateLocationFiltering=true&orderBy=name&projectKeyOrId=CID&projectLocation=2345&startAt=0&type=scrum",
+			context:            context.Background(),
+			wantErr:            true,
+		},
+
+		{
+			name: "GetBoardByFilterWhenTheContextIsNil",
+			opts: &GetBoardsOptions{
+				BoardType:               "scrum",
+				BoardName:               "board-name",
+				ProjectKeyOrID:          "CID",
+				AccountIDLocation:       "account-id-sample",
+				ProjectIDLocation:       "2345",
+				IncludePrivate:          true,
+				NegateLocationFiltering: true,
+				OrderBy:                 "name",
+				Expand:                  "permissions",
+				FilterID:                111234,
+			},
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-board.json",
+			wantHTTPCodeReturn: http.StatusOK,
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/agile/1.0/board?accountIdLocation=account-id-sample&expand=permissions&filterId=111234&includePrivate=true&maxResults=50&name=board-name&negateLocationFiltering=true&orderBy=name&projectKeyOrId=CID&projectLocation=2345&startAt=0&type=scrum",
+			context:            nil,
+			wantErr:            true,
+		},
+
+		{
+			name: "GetBoardByFilterWhenTheResponseStatusCodeIsIncorrect",
+			opts: &GetBoardsOptions{
+				BoardType:               "scrum",
+				BoardName:               "board-name",
+				ProjectKeyOrID:          "CID",
+				AccountIDLocation:       "account-id-sample",
+				ProjectIDLocation:       "2345",
+				IncludePrivate:          true,
+				NegateLocationFiltering: true,
+				OrderBy:                 "name",
+				Expand:                  "permissions",
+				FilterID:                111234,
+			},
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/get-board.json",
+			wantHTTPCodeReturn: http.StatusBadGateway,
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/agile/1.0/board?accountIdLocation=account-id-sample&expand=permissions&filterId=111234&includePrivate=true&maxResults=50&name=board-name&negateLocationFiltering=true&orderBy=name&projectKeyOrId=CID&projectLocation=2345&startAt=0&type=scrum",
+			context:            context.Background(),
+			wantErr:            true,
+		},
+
+		{
+			name: "GetBoardByFilterWhenTheResponseBodyIsEmpty",
+			opts: &GetBoardsOptions{
+				BoardType:               "scrum",
+				BoardName:               "board-name",
+				ProjectKeyOrID:          "CID",
+				AccountIDLocation:       "account-id-sample",
+				ProjectIDLocation:       "2345",
+				IncludePrivate:          true,
+				NegateLocationFiltering: true,
+				OrderBy:                 "name",
+				Expand:                  "permissions",
+				FilterID:                111234,
+			},
+			startAt:            0,
+			maxResults:         50,
+			mockFile:           "./mocks/empty-json.json",
+			wantHTTPCodeReturn: http.StatusOK,
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/agile/1.0/board?accountIdLocation=account-id-sample&expand=permissions&filterId=111234&includePrivate=true&maxResults=50&name=board-name&negateLocationFiltering=true&orderBy=name&projectKeyOrId=CID&projectLocation=2345&startAt=0&type=scrum",
+			context:            context.Background(),
+			wantErr:            true,
+		},
+	}
+
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+
+			//Init a new HTTP mock server
+			mockOptions := mockServerOptions{
+				Endpoint:           testCase.endpoint,
+				MockFilePath:       testCase.mockFile,
+				MethodAccepted:     testCase.wantHTTPMethod,
+				ResponseCodeWanted: testCase.wantHTTPCodeReturn,
+			}
+
+			mockServer, err := startMockServer(&mockOptions)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			defer mockServer.Close()
+
+			//Init the library instance
+			mockClient, err := startMockClient(mockServer.URL)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			service := &BoardService{client: mockClient}
+			gotResult, gotResponse, err := service.Gets(testCase.context, testCase.opts,
+				testCase.startAt, testCase.maxResults)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.Error(t, err)
+
+				if gotResponse != nil {
+					t.Logf("HTTP Code Wanted: %v, HTTP Code Returned: %v", testCase.wantHTTPCodeReturn, gotResponse.Code)
+				}
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+
+				apiEndpoint, err := url.Parse(gotResponse.Endpoint)
+				if err != nil {
+					t.Fatal(err)
+				}
+
+				var endpointToAssert string
+
+				if apiEndpoint.Query().Encode() != "" {
+					endpointToAssert = fmt.Sprintf("%v?%v", apiEndpoint.Path, apiEndpoint.Query().Encode())
+				} else {
+					endpointToAssert = apiEndpoint.Path
+				}
+
+				t.Logf("HTTP Endpoint Wanted: %v, HTTP Endpoint Returned: %v", testCase.endpoint, endpointToAssert)
+				assert.Equal(t, testCase.endpoint, endpointToAssert)
+
+				t.Logf("HTTP Code Wanted: %v, HTTP Code Returned: %v", testCase.wantHTTPCodeReturn, gotResponse.Code)
+				assert.Equal(t, gotResponse.Code, testCase.wantHTTPCodeReturn)
+			}
+		})
+	}
+
+}
+
 func TestBoardService_Filter(t *testing.T) {
 
 	testCases := []struct {