Skip to content

Commit 520b63a

Browse files
committed
feature: add UpdateIssueWithOptions and add testing for addOptions to make clear what it does
Signed-off-by: rtweed <[email protected]>
1 parent 50d59fe commit 520b63a

File tree

5 files changed

+113
-6
lines changed

5 files changed

+113
-6
lines changed

cloud/issue.go

+20-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type IssueService service
3131

3232
// UpdateQueryOptions specifies the optional parameters to the Edit issue
3333
type UpdateQueryOptions struct {
34-
NotifyUsers bool `url:"notifyUsers,omitempty"`
34+
NotifyUsers bool `url:"notifyUsers"` // can't be omitted as this means it's omitted when false which isn't desired as this defaults to true
3535
OverrideScreenSecurity bool `url:"overrideScreenSecurity,omitempty"`
3636
OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"`
3737
}
@@ -559,7 +559,7 @@ type GetWorklogsQueryOptions struct {
559559
}
560560

561561
type AddWorklogQueryOptions struct {
562-
NotifyUsers bool `url:"notifyUsers,omitempty"`
562+
NotifyUsers bool `url:"notifyUsers"` // can't be omitted as this means it's omitted when false which isn't desired as this defaults to true
563563
AdjustEstimate string `url:"adjustEstimate,omitempty"`
564564
NewEstimate string `url:"newEstimate,omitempty"`
565565
ReduceBy string `url:"reduceBy,omitempty"`
@@ -868,8 +868,24 @@ func (s *IssueService) Update(ctx context.Context, issue *Issue, opts *UpdateQue
868868
// TODO Double check this method if this works as expected, is using the latest API and the response is complete
869869
// This double check effort is done for v2 - Remove this two lines if this is completed.
870870
func (s *IssueService) UpdateIssue(ctx context.Context, jiraID string, data map[string]interface{}) (*Response, error) {
871-
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%v", jiraID)
872-
req, err := s.client.NewRequest(ctx, http.MethodPut, apiEndpoint, data)
871+
return s.UpdateIssueWithOptions(ctx, jiraID, data, &UpdateQueryOptions{})
872+
}
873+
874+
// UpdateIssueWithOptions updates an issue from a JSON patch,
875+
// while also specifying query params. The issue is found by key.
876+
//
877+
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-issueidorkey-put
878+
// Caller must close resp.Body
879+
//
880+
// TODO Double check this method if this works as expected, is using the latest API and the response is complete
881+
// This double check effort is done for v2 - Remove this two lines if this is completed.
882+
func (s *IssueService) UpdateIssueWithOptions(ctx context.Context, jiraID string, data map[string]interface{}, opts *UpdateQueryOptions) (*Response, error) {
883+
a := fmt.Sprintf("rest/api/2/issue/%v", jiraID)
884+
url, err := addOptions(a, opts)
885+
if err != nil {
886+
return nil, err
887+
}
888+
req, err := s.client.NewRequest(ctx, http.MethodPut, url, data)
873889
if err != nil {
874890
return nil, err
875891
}

cloud/issue_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,30 @@ func TestIssueService_UpdateIssue(t *testing.T) {
178178

179179
}
180180

181+
func TestIssueService_UpdateIssueWithOptions(t *testing.T) {
182+
setup()
183+
defer teardown()
184+
testMux.HandleFunc("/rest/api/2/issue/PROJ-9001", func(w http.ResponseWriter, r *http.Request) {
185+
testMethod(t, r, http.MethodPut)
186+
testRequestURL(t, r, "/rest/api/2/issue/PROJ-9001")
187+
testRequestParams(t, r, map[string]string{"notifyUsers": "true"})
188+
189+
w.WriteHeader(http.StatusNoContent)
190+
})
191+
jID := "PROJ-9001"
192+
i := make(map[string]interface{})
193+
fields := make(map[string]interface{})
194+
i["fields"] = fields
195+
resp, err := testClient.Issue.client.Issue.UpdateIssueWithOptions(context.Background(), jID, i, &UpdateQueryOptions{NotifyUsers: false})
196+
if resp == nil {
197+
t.Error("Expected resp. resp is nil")
198+
}
199+
if err != nil {
200+
t.Errorf("Error given: %s", err)
201+
}
202+
203+
}
204+
181205
func TestIssueService_AddComment(t *testing.T) {
182206
setup()
183207
defer teardown()

cloud/jira_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@ func testRequestParams(t *testing.T, r *http.Request, want map[string]string) {
7373

7474
}
7575

76+
func Test_addOptions(t *testing.T) {
77+
v, err := addOptions("rest/api/2/issue/123", &UpdateQueryOptions{NotifyUsers: false})
78+
if err != nil {
79+
t.Errorf("Expected no error. Got: %+v", err)
80+
}
81+
82+
expectedOutput := "rest/api/2/issue/123?notifyUsers=false"
83+
if v != expectedOutput {
84+
t.Errorf("Expected: %+v, got: %+v", expectedOutput, v)
85+
}
86+
87+
}
88+
7689
func TestNewClient_WrongUrl(t *testing.T) {
7790
c, err := NewClient("://issues.apache.org/jira/", nil)
7891

onpremise/issue.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type IssueService service
3131

3232
// UpdateQueryOptions specifies the optional parameters to the Edit issue
3333
type UpdateQueryOptions struct {
34-
NotifyUsers bool `url:"notifyUsers,omitempty"`
34+
NotifyUsers bool `url:"notifyUsers"` // can't be omitted as this means it's omitted when false which isn't desired as this defaults to true
3535
OverrideScreenSecurity bool `url:"overrideScreenSecurity,omitempty"`
3636
OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"`
3737
}
@@ -839,7 +839,7 @@ func (s *IssueService) Create(ctx context.Context, issue *Issue) (*Issue, *Respo
839839
// This double check effort is done for v2 - Remove this two lines if this is completed.
840840
func (s *IssueService) Update(ctx context.Context, issue *Issue, opts *UpdateQueryOptions) (*Issue, *Response, error) {
841841
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%v", issue.Key)
842-
url, err := addOptions(apiEndpoint, opts)
842+
url, err := addOptions(apiEndpoint, *opts)
843843
if err != nil {
844844
return nil, nil, err
845845
}

onpremise/issue_test.go

+54
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,60 @@ func TestIssueService_Update(t *testing.T) {
155155
}
156156
}
157157

158+
func TestIssueService_Update_with_false_opts(t *testing.T) {
159+
setup()
160+
defer teardown()
161+
testMux.HandleFunc("/rest/api/2/issue/PROJ-9001", func(w http.ResponseWriter, r *http.Request) {
162+
testMethod(t, r, http.MethodPut)
163+
testRequestURL(t, r, "/rest/api/2/issue/PROJ-9001")
164+
testRequestParams(t, r, map[string]string{"notifyUsers": "false"})
165+
166+
w.WriteHeader(http.StatusNoContent)
167+
})
168+
169+
i := &Issue{
170+
Key: "PROJ-9001",
171+
Fields: &IssueFields{
172+
Description: "example bug report",
173+
},
174+
}
175+
issue, _, err := testClient.Issue.Update(context.Background(), i, &UpdateQueryOptions{NotifyUsers: false})
176+
if issue == nil {
177+
t.Error("Expected issue. Issue is nil")
178+
}
179+
if err != nil {
180+
t.Errorf("Error given: %s", err)
181+
}
182+
183+
}
184+
185+
func TestIssueService_Update_with_multiple_opts(t *testing.T) {
186+
setup()
187+
defer teardown()
188+
testMux.HandleFunc("/rest/api/2/issue/PROJ-9001", func(w http.ResponseWriter, r *http.Request) {
189+
testMethod(t, r, http.MethodPut)
190+
testRequestURL(t, r, "/rest/api/2/issue/PROJ-9001")
191+
testRequestParams(t, r, map[string]string{"notifyUsers": "false", "overrideScreenSecurity": "true"})
192+
193+
w.WriteHeader(http.StatusNoContent)
194+
})
195+
196+
i := &Issue{
197+
Key: "PROJ-9001",
198+
Fields: &IssueFields{
199+
Description: "example bug report",
200+
},
201+
}
202+
issue, _, err := testClient.Issue.Update(context.Background(), i, &UpdateQueryOptions{NotifyUsers: false, OverrideScreenSecurity: true})
203+
if issue == nil {
204+
t.Error("Expected issue. Issue is nil")
205+
}
206+
if err != nil {
207+
t.Errorf("Error given: %s", err)
208+
}
209+
210+
}
211+
158212
func TestIssueService_UpdateIssue(t *testing.T) {
159213
setup()
160214
defer teardown()

0 commit comments

Comments
 (0)