Repository: ctreminiom/go-atlassian
Pull request #163 (2022-11-10 03:22:44)

:sparkles: Added the get the workflow status by ID or Name
1. Created a method called Get() under the WorkflowStatusConnector interface

2. Created a new implementation of the new interface method

3. Created a new dedicated error template


Patch:
diff --git a/jira/internal/workflow_status_impl.go b/jira/internal/workflow_status_impl.go
index 4afafd5..92a9940 100644
--- a/jira/internal/workflow_status_impl.go
+++ b/jira/internal/workflow_status_impl.go
@@ -81,11 +81,50 @@ func (w *WorkflowStatusService) Bulk(ctx context.Context) ([]*model.StatusDetail
 	return w.internalClient.Bulk(ctx)
 }
 
+// Get returns a status.
+//
+// The status must be associated with an active workflow to be returned.
+//
+// If a name is used on more than one status, only the status found first is returned.
+//
+// Therefore, identifying the status by its ID may be preferable.
+//
+// This operation can be accessed anonymously.
+//
+// GET /rest/api/{2-3}/status/{idOrName}
+//
+// https://docs.go-atlassian.io/jira-software-cloud/workflow/status#get-workflow-status
+func (w *WorkflowStatusService) Get(ctx context.Context, idOrName string) (*model.StatusDetailScheme, *model.ResponseScheme, error) {
+	return w.internalClient.Get(ctx, idOrName)
+}
+
 type internalWorkflowStatusImpl struct {
 	c       service.Client
 	version string
 }
 
+func (i *internalWorkflowStatusImpl) Get(ctx context.Context, idOrName string) (*model.StatusDetailScheme, *model.ResponseScheme, error) {
+
+	if idOrName == "" {
+		return nil, nil, model.ErrNoWorkflowStatusNameOrIdError
+	}
+
+	endpoint := fmt.Sprintf("/rest/api/%v/status/%v", i.version, idOrName)
+
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	workflowStatus := new(model.StatusDetailScheme)
+	response, err := i.c.Call(request, workflowStatus)
+	if err != nil {
+		return nil, response, err
+	}
+
+	return workflowStatus, response, nil
+}
+
 func (i *internalWorkflowStatusImpl) Bulk(ctx context.Context) ([]*model.StatusDetailScheme, *model.ResponseScheme, error) {
 
 	endpoint := fmt.Sprintf("/rest/api/%v/status", i.version)
diff --git a/pkg/infra/models/errors.go b/pkg/infra/models/errors.go
index b369696..eebc22b 100644
--- a/pkg/infra/models/errors.go
+++ b/pkg/infra/models/errors.go
@@ -67,6 +67,7 @@ var (
 	ErrNoFieldIDError                      = errors.New("jira: no field id set")
 	ErrNoWorkflowStatusesError             = errors.New("jira: no workflow statuses set")
 	ErrNoWorkflowScopeError                = errors.New("jira: no workflow scope set")
+	ErrNoWorkflowStatusNameOrIdError       = errors.New("jira: no workflow status name or id set")
 	ErrNoFieldContextIDError               = errors.New("jira: no field context id set")
 	ErrNoIssueTypesError                   = errors.New("jira: no issue types id's set")
 	ErrNoProjectsError                     = errors.New("jira: no projects set")
diff --git a/service/jira/workflow.go b/service/jira/workflow.go
index db5f7a6..139f5ef 100644
--- a/service/jira/workflow.go
+++ b/service/jira/workflow.go
@@ -161,4 +161,19 @@ type WorkflowStatusConnector interface {
 	//
 	// https://docs.go-atlassian.io/jira-software-cloud/workflow/status#bulk-workflow-statuses
 	Bulk(ctx context.Context) ([]*model.StatusDetailScheme, *model.ResponseScheme, error)
+
+	// Get returns a status.
+	//
+	// The status must be associated with an active workflow to be returned.
+	//
+	// If a name is used on more than one status, only the status found first is returned.
+	//
+	// Therefore, identifying the status by its ID may be preferable.
+	//
+	// This operation can be accessed anonymously.
+	//
+	// GET /rest/api/{2-3}/status/{idOrName}
+	//
+	// https://docs.go-atlassian.io/jira-software-cloud/workflow/status#get-workflow-status
+	Get(ctx context.Context, idOrName string) (*model.StatusDetailScheme, *model.ResponseScheme, error)
 }


Test patch:
diff --git a/jira/internal/workflow_status_impl_test.go b/jira/internal/workflow_status_impl_test.go
index a31cac3..f9a08ac 100644
--- a/jira/internal/workflow_status_impl_test.go
+++ b/jira/internal/workflow_status_impl_test.go
@@ -968,3 +968,137 @@ func Test_internalWorkflowStatusImpl_Bulk(t *testing.T) {
 		})
 	}
 }
+
+func Test_internalWorkflowStatusImpl_Get(t *testing.T) {
+
+	type fields struct {
+		c       service.Client
+		version string
+	}
+
+	type args struct {
+		ctx      context.Context
+		idOrName string
+	}
+
+	testCases := []struct {
+		name    string
+		fields  fields
+		args    args
+		on      func(*fields)
+		wantErr bool
+		Err     error
+	}{
+		{
+			name:   "when the api version is v3",
+			fields: fields{version: "3"},
+			args: args{
+				ctx:      context.TODO(),
+				idOrName: "TODO",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodGet,
+					"/rest/api/3/status/TODO",
+					nil).
+					Return(&http.Request{}, nil)
+
+				client.On("Call",
+					&http.Request{},
+					&model.StatusDetailScheme{}).
+					Return(&model.ResponseScheme{}, nil)
+
+				fields.c = client
+			},
+			wantErr: false,
+			Err:     nil,
+		},
+
+		{
+			name:   "when the api version is v2",
+			fields: fields{version: "2"},
+			args: args{
+				ctx:      context.TODO(),
+				idOrName: "TODO",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodGet,
+					"/rest/api/2/status/TODO",
+					nil).
+					Return(&http.Request{}, nil)
+
+				client.On("Call",
+					&http.Request{},
+					&model.StatusDetailScheme{}).
+					Return(&model.ResponseScheme{}, nil)
+
+				fields.c = client
+			},
+			wantErr: false,
+			Err:     nil,
+		},
+
+		{
+			name:   "when the http request cannot be created",
+			fields: fields{version: "3"},
+			args: args{
+				ctx:      context.TODO(),
+				idOrName: "TODO",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodGet,
+					"/rest/api/3/status/TODO",
+					nil).
+					Return(&http.Request{}, errors.New("error, unable to create the http request"))
+
+				fields.c = client
+			},
+			wantErr: true,
+			Err:     errors.New("error, unable to create the http request"),
+		},
+	}
+
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+
+			if testCase.on != nil {
+				testCase.on(&testCase.fields)
+			}
+
+			newService, err := NewWorkflowStatusService(testCase.fields.c, testCase.fields.version)
+			assert.NoError(t, err)
+
+			gotResult, gotResponse, err := newService.Get(testCase.args.ctx, testCase.args.idOrName)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.EqualError(t, err, testCase.Err.Error())
+
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+			}
+
+		})
+	}
+}