Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#368 Added warningMessages to issue.search() response #369

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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