Repository: ctreminiom/go-atlassian
Pull request #73 (2021-11-05 04:35:43)

:sparkles: Added the v2.Project.Gets() method


Patch:
diff --git a/jira/mocks/get-projects-v2.json b/jira/mocks/get-projects-v2.json
new file mode 100644
index 0000000..ad82985
--- /dev/null
+++ b/jira/mocks/get-projects-v2.json
@@ -0,0 +1,50 @@
+[
+  {
+    "self": "https://your-domain.atlassian.net/rest/api/2/project/EX",
+    "id": "10000",
+    "key": "EX",
+    "name": "Example",
+    "avatarUrls": {
+      "48x48": "https://your-domain.atlassian.net/secure/projectavatar?size=large&pid=10000",
+      "24x24": "https://your-domain.atlassian.net/secure/projectavatar?size=small&pid=10000",
+      "16x16": "https://your-domain.atlassian.net/secure/projectavatar?size=xsmall&pid=10000",
+      "32x32": "https://your-domain.atlassian.net/secure/projectavatar?size=medium&pid=10000"
+    },
+    "projectCategory": {
+      "self": "https://your-domain.atlassian.net/rest/api/2/projectCategory/10000",
+      "id": "10000",
+      "name": "FIRST",
+      "description": "First Project Category"
+    },
+    "simplified": false,
+    "style": "classic",
+    "insight": {
+      "totalIssueCount": 100,
+      "lastIssueUpdateTime": "2021-11-03T02:38:47.060+0000"
+    }
+  },
+  {
+    "self": "https://your-domain.atlassian.net/rest/api/2/project/ABC",
+    "id": "10001",
+    "key": "ABC",
+    "name": "Alphabetical",
+    "avatarUrls": {
+      "48x48": "https://your-domain.atlassian.net/secure/projectavatar?size=large&pid=10001",
+      "24x24": "https://your-domain.atlassian.net/secure/projectavatar?size=small&pid=10001",
+      "16x16": "https://your-domain.atlassian.net/secure/projectavatar?size=xsmall&pid=10001",
+      "32x32": "https://your-domain.atlassian.net/secure/projectavatar?size=medium&pid=10001"
+    },
+    "projectCategory": {
+      "self": "https://your-domain.atlassian.net/rest/api/2/projectCategory/10000",
+      "id": "10000",
+      "name": "FIRST",
+      "description": "First Project Category"
+    },
+    "simplified": false,
+    "style": "classic",
+    "insight": {
+      "totalIssueCount": 100,
+      "lastIssueUpdateTime": "2021-11-03T02:38:47.060+0000"
+    }
+  }
+]
\ No newline at end of file
diff --git a/jira/v2/project.go b/jira/v2/project.go
index cbada08..3274c39 100644
--- a/jira/v2/project.go
+++ b/jira/v2/project.go
@@ -104,6 +104,39 @@ func (p *ProjectService) Search(ctx context.Context, options *models.ProjectSear
 	return
 }
 
+// Gets returns all projects visible to the user.
+// Deprecated, use Get projects paginated that supports search and pagination.
+// Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-projects/#api-rest-api-2-project-get
+// Note: available on the Data Center versions
+func (p *ProjectService) Gets(ctx context.Context, expand []string) (result []*models.ProjectScheme, response *ResponseScheme, err error) {
+
+	params := url.Values{}
+	if len(expand) != 0 {
+		params.Add("expand", strings.Join(expand, ","))
+	}
+
+	var endpoint strings.Builder
+	endpoint.WriteString("rest/api/2/project")
+
+	if params.Encode() != "" {
+		endpoint.WriteString(fmt.Sprintf("?%v", params.Encode()))
+	}
+
+	request, err := p.client.newRequest(ctx, http.MethodGet, endpoint.String(), nil)
+	if err != nil {
+		return
+	}
+
+	request.Header.Set("Accept", "application/json")
+
+	response, err = p.client.call(request, &result)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
 // Get returns the project details for a project.
 // Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-projects/#api-rest-api-2-project-projectidorkey-get
 // Atlassian Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-projects/#api-rest-api-2-project-projectidorkey-get


Test patch:
diff --git a/jira/v2/project_test.go b/jira/v2/project_test.go
index cf6334d..0af9ff8 100644
--- a/jira/v2/project_test.go
+++ b/jira/v2/project_test.go
@@ -645,6 +645,149 @@ func TestProjectService_DeleteAsynchronously(t *testing.T) {
 
 }
 
+func TestProjectService_Gets(t *testing.T) {
+
+	testCases := []struct {
+		name               string
+		expands            []string
+		mockFile           string
+		wantHTTPMethod     string
+		endpoint           string
+		context            context.Context
+		wantHTTPCodeReturn int
+		wantErr            bool
+	}{
+		{
+			name:               "GetProjectsWhenTheParametersAreCorrect",
+			expands:            []string{"issueTypes", "lead", "description"},
+			mockFile:           "../mocks/get-projects-v2.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/2/project?expand=issueTypes%2Clead%2Cdescription",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name:               "GetProjectsWhenTheProjectExpandIsNil",
+			expands:            nil,
+			mockFile:           "../mocks/get-projects-v2.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/2/project",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            false,
+		},
+
+		{
+			name:               "GetProjectsWhenTheRequestMethodIsIncorrect",
+			expands:            []string{"issueTypes", "lead", "description"},
+			mockFile:           "../mocks/get-projects-v2.json",
+			wantHTTPMethod:     http.MethodDelete,
+			endpoint:           "/rest/api/2/project?expand=issueTypes%2Clead%2Cdescription",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetProjectsWhenTheStatusCodeIsIncorrect",
+			expands:            []string{"issueTypes", "lead", "description"},
+			mockFile:           "../mocks/get-projects-v2.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/2/project?expand=issueTypes%2Clead%2Cdescription",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusBadRequest,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetProjectsWhenTheContextIsNil",
+			expands:            []string{"issueTypes", "lead", "description"},
+			mockFile:           "../mocks/get-projects-v2.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/2/project?expand=issueTypes%2Clead%2Cdescription",
+			context:            nil,
+			wantHTTPCodeReturn: http.StatusOK,
+			wantErr:            true,
+		},
+
+		{
+			name:               "GetProjectsWhenTheResponseBodyHasADifferentFormat",
+			expands:            []string{"issueTypes", "lead", "description"},
+			mockFile:           "../v3/mocks/empty_json.json",
+			wantHTTPMethod:     http.MethodGet,
+			endpoint:           "/rest/api/2/project?expand=issueTypes%2Clead%2Cdescription",
+			context:            context.Background(),
+			wantHTTPCodeReturn: http.StatusOK,
+			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)
+			}
+
+			i := &ProjectService{client: mockClient}
+
+			gotResult, gotResponse, err := i.Gets(testCase.context, testCase.expands)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.Error(t, err)
+			} 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)
+			}
+		})
+
+	}
+
+}
+
 func TestProjectService_Get(t *testing.T) {
 
 	testCases := []struct {