Repository: ctreminiom/go-atlassian
Pull request #291 (2024-07-15 09:41:44)

add watcher that is another user as this looks not implemented on Add()


Patch:
diff --git a/jira/internal/watcher_impl.go b/jira/internal/watcher_impl.go
index ea860bf..9aa8414 100644
--- a/jira/internal/watcher_impl.go
+++ b/jira/internal/watcher_impl.go
@@ -42,8 +42,8 @@ func (w *WatcherService) Gets(ctx context.Context, issueKeyOrID string) (*model.
 // POST /rest/api/{2-3}/issue/{issueKeyOrID}/watchers
 //
 // https://docs.go-atlassian.io/jira-software-cloud/issues/watcher#add-watcher
-func (w *WatcherService) Add(ctx context.Context, issueKeyOrID string) (*model.ResponseScheme, error) {
-	return w.internalClient.Add(ctx, issueKeyOrID)
+func (w *WatcherService) Add(ctx context.Context, issueKeyOrID string, accountID ...string) (*model.ResponseScheme, error) {
+	return w.internalClient.Add(ctx, issueKeyOrID, accountID...)
 }
 
 // Delete deletes a user as a watcher of an issue.
@@ -82,7 +82,7 @@ func (i *internalWatcherImpl) Gets(ctx context.Context, issueKeyOrID string) (*m
 	return watchers, response, nil
 }
 
-func (i *internalWatcherImpl) Add(ctx context.Context, issueKeyOrID string) (*model.ResponseScheme, error) {
+func (i *internalWatcherImpl) Add(ctx context.Context, issueKeyOrID string, accountID ...string) (*model.ResponseScheme, error) {
 
 	if issueKeyOrID == "" {
 		return nil, model.ErrNoIssueKeyOrIDError
@@ -90,7 +90,11 @@ func (i *internalWatcherImpl) Add(ctx context.Context, issueKeyOrID string) (*mo
 
 	endpoint := fmt.Sprintf("rest/api/%v/issue/%v/watchers", i.version, issueKeyOrID)
 
-	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, "", nil)
+	var payload []byte = nil // add self user
+	if len(accountID) > 0 {
+		payload = []byte(accountID[0]) // add another user
+	}
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, "", payload)
 	if err != nil {
 		return nil, err
 	}
diff --git a/service/jira/watcher.go b/service/jira/watcher.go
index 29150fa..db0609d 100644
--- a/service/jira/watcher.go
+++ b/service/jira/watcher.go
@@ -14,7 +14,7 @@ type WatcherConnector interface {
 	// GET /rest/api/{2-3}/issue/{issueIdOrKey}/watchers
 	//
 	// https://docs.go-atlassian.io/jira-software-cloud/issues/watcher#get-issue-watchers
-	Gets(ctx context.Context, issueKeyOrId string) (*model.IssueWatcherScheme, *model.ResponseScheme, error)
+	Gets(ctx context.Context, issueKeyOrID string) (*model.IssueWatcherScheme, *model.ResponseScheme, error)
 
 	// Add adds a user as a watcher of an issue by passing the account ID of the user.
 	//
@@ -23,12 +23,12 @@ type WatcherConnector interface {
 	// POST /rest/api/{2-3}/issue/{issueIdOrKey}/watchers
 	//
 	// https://docs.go-atlassian.io/jira-software-cloud/issues/watcher#add-watcher
-	Add(ctx context.Context, issueKeyOrId string) (*model.ResponseScheme, error)
+	Add(ctx context.Context, issueKeyOrID string, accountID ...string) (*model.ResponseScheme, error)
 
 	// Delete deletes a user as a watcher of an issue.
 	//
 	// DELETE /rest/api/{2-3}/issue/{issueIdOrKey}/watchers
 	//
 	// https://docs.go-atlassian.io/jira-software-cloud/issues/watcher#delete-watcher
-	Delete(ctx context.Context, issueKeyOrId, accountId string) (*model.ResponseScheme, error)
+	Delete(ctx context.Context, issueKeyOrID, accountID string) (*model.ResponseScheme, error)
 }


Test patch:
diff --git a/jira/internal/watcher_impl_test.go b/jira/internal/watcher_impl_test.go
index 9b42699..8f0034c 100644
--- a/jira/internal/watcher_impl_test.go
+++ b/jira/internal/watcher_impl_test.go
@@ -171,6 +171,7 @@ func Test_internalWatcherImpl_Add(t *testing.T) {
 	type args struct {
 		ctx          context.Context
 		issueKeyOrID string
+		accountID    []string
 	}
 
 	testCases := []struct {
@@ -187,6 +188,7 @@ func Test_internalWatcherImpl_Add(t *testing.T) {
 			args: args{
 				ctx:          context.Background(),
 				issueKeyOrID: "DUMMY-5",
+				accountID:    nil,
 			},
 			on: func(fields *fields) {
 
@@ -197,7 +199,38 @@ func Test_internalWatcherImpl_Add(t *testing.T) {
 					http.MethodPost,
 					"rest/api/3/issue/DUMMY-5/watchers",
 					"",
+					[]byte(nil)).
+					Return(&http.Request{}, nil)
+
+				client.On("Call",
+					&http.Request{},
 					nil).
+					Return(&model.ResponseScheme{}, nil)
+
+				fields.c = client
+			},
+			wantErr: false,
+			Err:     nil,
+		},
+
+		{
+			name:   "when the api version is v3 and the watcher accountId is set",
+			fields: fields{version: "3"},
+			args: args{
+				ctx:          context.Background(),
+				issueKeyOrID: "DUMMY-5",
+				accountID:    []string{"someAccountID"},
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewConnector(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodPost,
+					"rest/api/3/issue/DUMMY-5/watchers",
+					"",
+					[]byte("someAccountID")).
 					Return(&http.Request{}, nil)
 
 				client.On("Call",
@@ -217,6 +250,7 @@ func Test_internalWatcherImpl_Add(t *testing.T) {
 			args: args{
 				ctx:          context.Background(),
 				issueKeyOrID: "DUMMY-5",
+				accountID:    nil,
 			},
 			on: func(fields *fields) {
 
@@ -227,7 +261,39 @@ func Test_internalWatcherImpl_Add(t *testing.T) {
 					http.MethodPost,
 					"rest/api/2/issue/DUMMY-5/watchers",
 					"",
+					[]byte(nil),
+				).
+					Return(&http.Request{}, nil)
+
+				client.On("Call",
+					&http.Request{},
 					nil).
+					Return(&model.ResponseScheme{}, nil)
+
+				fields.c = client
+			},
+			wantErr: false,
+			Err:     nil,
+		},
+
+		{
+			name:   "when the api version is v2 and the watcher accountId is set",
+			fields: fields{version: "2"},
+			args: args{
+				ctx:          context.Background(),
+				issueKeyOrID: "DUMMY-5",
+				accountID:    []string{"someAccountID"},
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewConnector(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodPost,
+					"rest/api/2/issue/DUMMY-5/watchers",
+					"",
+					[]byte("someAccountID")).
 					Return(&http.Request{}, nil)
 
 				client.On("Call",
@@ -258,6 +324,7 @@ func Test_internalWatcherImpl_Add(t *testing.T) {
 			args: args{
 				ctx:          context.Background(),
 				issueKeyOrID: "DUMMY-5",
+				accountID:    nil,
 			},
 			on: func(fields *fields) {
 
@@ -268,7 +335,7 @@ func Test_internalWatcherImpl_Add(t *testing.T) {
 					http.MethodPost,
 					"rest/api/3/issue/DUMMY-5/watchers",
 					"",
-					nil).
+					[]byte(nil)).
 					Return(&http.Request{}, errors.New("error, unable to create the http request"))
 
 				fields.c = client
@@ -288,7 +355,7 @@ func Test_internalWatcherImpl_Add(t *testing.T) {
 			newService, err := NewWatcherService(testCase.fields.c, testCase.fields.version)
 			assert.NoError(t, err)
 
-			gotResponse, err := newService.Add(testCase.args.ctx, testCase.args.issueKeyOrID)
+			gotResponse, err := newService.Add(testCase.args.ctx, testCase.args.issueKeyOrID, testCase.args.accountID...)
 
 			if testCase.wantErr {