Skip to content

Commit

Permalink
andygrunwald#368 Added warningMessages to issue.search() response
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelbcd committed Mar 23, 2021
1 parent e8880eb commit 829c8e1
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 28 deletions.
16 changes: 13 additions & 3 deletions examples/jql/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ func main() {

jql := "project = Mesos and type = Bug and Status NOT IN (Resolved)"
fmt.Printf("Usecase: Running a JQL query '%s'\n", jql)
issues, resp, err := jiraClient.Issue.Search(jql, nil)
issues, resp, warningMessages, err := jiraClient.Issue.Search(jql, nil)
if err != nil {
panic(err)
}
checkWarnings(warningMessages)
outputResponse(issues, resp)

fmt.Println("")
Expand All @@ -25,18 +26,27 @@ func main() {
// Running an empty JQL query to get all tickets
jql = ""
fmt.Printf("Usecase: Running an empty JQL query to get all tickets\n")
issues, resp, err = jiraClient.Issue.Search(jql, nil)
issues, resp, warningMessages, err = jiraClient.Issue.Search(jql, nil)
if err != nil {
panic(err)
}
checkWarnings(warningMessages)
outputResponse(issues, resp)
}

func outputResponse(issues []jira.Issue, resp *jira.Response) {
fmt.Printf("Call to %s\n", resp.Request.URL)
fmt.Printf("Response Code: %d\n", resp.StatusCode)
fmt.Println("==================================")
for _, i := range issues {
fmt.Printf("%s (%s/%s): %+v\n", i.Key, i.Fields.Type.Name, i.Fields.Priority.Name, i.Fields.Summary)
}
}

func checkWarnings(warningMessages []jira.WarningMsg) {
if len(warningMessages) > 0 {
fmt.Printf("Warning messages in response:\n")
for i, warn := range warningMessages {
fmt.Printf("Warning %d: %s\n", i, warn)
}
}
}
13 changes: 12 additions & 1 deletion examples/pagination/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ func GetAllIssues(client *jira.Client, searchString string) ([]jira.Issue, error
StartAt: last,
}

chunk, resp, err := client.Issue.Search(searchString, opt)
chunk, resp, warningMessages, err := client.Issue.Search(searchString, opt)
if err != nil {
return nil, err
}

checkWarnings(warningMessages)

total := resp.Total
if issues == nil {
issues = make([]jira.Issue, 0, total)
Expand Down Expand Up @@ -53,3 +55,12 @@ func main() {
fmt.Println(issues)

}

func checkWarnings(warningMessages []jira.WarningMsg) {
if len(warningMessages) > 0 {
fmt.Printf("Warning messages in response:\n")
for i, warn := range warningMessages {
fmt.Printf("Warning %d: %s\n", i, warn)
}
}
}
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ require (
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135
github.com/pkg/errors v0.9.1
github.com/trivago/tgo v1.0.7
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d
)
13 changes: 3 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,17 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0=
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM=
github.com/trivago/tgo v1.0.7/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
24 changes: 14 additions & 10 deletions issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,12 +513,15 @@ type SearchOptions struct {
// searchResult is only a small wrapper around the Search (with JQL) method
// to be able to parse the results
type searchResult struct {
Issues []Issue `json:"issues" structs:"issues"`
StartAt int `json:"startAt" structs:"startAt"`
MaxResults int `json:"maxResults" structs:"maxResults"`
Total int `json:"total" structs:"total"`
Issues []Issue `json:"issues" structs:"issues"`
StartAt int `json:"startAt" structs:"startAt"`
MaxResults int `json:"maxResults" structs:"maxResults"`
Total int `json:"total" structs:"total"`
WarningMessages []WarningMsg `json:"warningMessages,omitempty" structs:"warningMessages,omitempty"`
}

type WarningMsg string

// GetQueryOptions specifies the optional parameters for the Get Issue methods
type GetQueryOptions struct {
// Fields is the list of fields to return for the issue. By default, all fields are returned.
Expand Down Expand Up @@ -1058,7 +1061,7 @@ func (s *IssueService) AddLink(issueLink *IssueLink) (*Response, error) {
// SearchWithContext will search for tickets according to the jql
//
// Jira API docs: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-query-issues
func (s *IssueService) SearchWithContext(ctx context.Context, jql string, options *SearchOptions) ([]Issue, *Response, error) {
func (s *IssueService) SearchWithContext(ctx context.Context, jql string, options *SearchOptions) ([]Issue, *Response, []WarningMsg, error) {
u := url.URL{
Path: "rest/api/2/search",
}
Expand Down Expand Up @@ -1089,19 +1092,20 @@ func (s *IssueService) SearchWithContext(ctx context.Context, jql string, option

req, err := s.client.NewRequestWithContext(ctx, "GET", u.String(), nil)
if err != nil {
return []Issue{}, nil, err
return []Issue{}, nil, nil, err
}

v := new(searchResult)
resp, err := s.client.Do(req, v)
if err != nil {
err = NewJiraError(resp, err)
}
return v.Issues, resp, err

return v.Issues, resp, v.WarningMessages, err
}

// Search wraps SearchWithContext using the background context.
func (s *IssueService) Search(jql string, options *SearchOptions) ([]Issue, *Response, error) {
func (s *IssueService) Search(jql string, options *SearchOptions) ([]Issue, *Response, []WarningMsg, error) {
return s.SearchWithContext(context.Background(), jql, options)
}

Expand All @@ -1120,7 +1124,7 @@ func (s *IssueService) SearchPagesWithContext(ctx context.Context, jql string, o
options.MaxResults = 50
}

issues, resp, err := s.SearchWithContext(ctx, jql, options)
issues, resp, _, err := s.SearchWithContext(ctx, jql, options)
if err != nil {
return err
}
Expand All @@ -1142,7 +1146,7 @@ func (s *IssueService) SearchPagesWithContext(ctx context.Context, jql string, o
}

options.StartAt += resp.MaxResults
issues, resp, err = s.SearchWithContext(ctx, jql, options)
issues, resp, _, err = s.SearchWithContext(ctx, jql, options)
if err != nil {
return err
}
Expand Down
31 changes: 28 additions & 3 deletions issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ func TestIssueService_Search(t *testing.T) {
})

opt := &SearchOptions{StartAt: 1, MaxResults: 40, Expand: "foo"}
_, resp, err := testClient.Issue.Search("type = Bug and Status NOT IN (Resolved)", opt)
_, resp, _, err := testClient.Issue.Search("type = Bug and Status NOT IN (Resolved)", opt)

if resp == nil {
t.Errorf("Response given: %+v", resp)
Expand All @@ -647,6 +647,31 @@ func TestIssueService_Search(t *testing.T) {
}
}

func TestIssueService_SearchWithWarnings(t *testing.T) {
setup()
defer teardown()
testMux.HandleFunc("/rest/api/2/search", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testRequestURL(t, r, "/rest/api/2/search?expand=foo&jql=worklogauthor+%3D+123+and+type+%3D+Bug+and+Status+NOT+IN+%28Resolved%29&maxResults=10&startAt=1")
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, `{"expand": "schema,names","startAt": 1,"maxResults": 10,"total": 6,"issues": [],"warningMessages": ["The value '123' does not exist for the field 'worklogAuthor'."]}`)
})

opt := &SearchOptions{StartAt: 1, MaxResults: 10, Expand: "foo"}
_, resp, warningMessages, err := testClient.Issue.Search("worklogauthor = 123 and type = Bug and Status NOT IN (Resolved)", opt)

if resp == nil {
t.Errorf("Response given: %+v", resp)
}
if err != nil {
t.Errorf("Error given: %s", err)
}

if len(warningMessages) != 1 {
t.Errorf("Expected 1 warning message, %v given", len(warningMessages))
}
}

func TestIssueService_SearchEmptyJQL(t *testing.T) {
setup()
defer teardown()
Expand All @@ -658,7 +683,7 @@ func TestIssueService_SearchEmptyJQL(t *testing.T) {
})

opt := &SearchOptions{StartAt: 1, MaxResults: 40, Expand: "foo"}
_, resp, err := testClient.Issue.Search("", opt)
_, resp, _, err := testClient.Issue.Search("", opt)

if resp == nil {
t.Errorf("Response given: %+v", resp)
Expand Down Expand Up @@ -687,7 +712,7 @@ func TestIssueService_Search_WithoutPaging(t *testing.T) {
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, `{"expand": "schema,names","startAt": 0,"maxResults": 50,"total": 6,"issues": [{"expand": "html","id": "10230","self": "http://kelpie9:8081/rest/api/2/issue/BULK-62","key": "BULK-62","fields": {"summary": "testing","timetracking": null,"issuetype": {"self": "http://kelpie9:8081/rest/api/2/issuetype/5","id": "5","description": "The sub-task of the issue","iconUrl": "http://kelpie9:8081/images/icons/issue_subtask.gif","name": "Sub-task","subtask": true},"customfield_10071": null}},{"expand": "html","id": "10004","self": "http://kelpie9:8081/rest/api/2/issue/BULK-47","key": "BULK-47","fields": {"summary": "Cheese v1 2.0 issue","timetracking": null,"issuetype": {"self": "http://kelpie9:8081/rest/api/2/issuetype/3","id": "3","description": "A task that needs to be done.","iconUrl": "http://kelpie9:8081/images/icons/task.gif","name": "Task","subtask": false}}}]}`)
})
_, resp, err := testClient.Issue.Search("something", nil)
_, resp, _, err := testClient.Issue.Search("something", nil)

if resp == nil {
t.Errorf("Response given: %+v", resp)
Expand Down

0 comments on commit 829c8e1

Please sign in to comment.