Repository: ankitpokhrel/jira-cli
Pull request #60 (2021-01-08 21:20:58)

feat: Add option to limit results


Patch:
diff --git a/README.md b/README.md
index c3b4cae..a860175 100644
--- a/README.md
+++ b/README.md
@@ -23,11 +23,6 @@ the UI as much as possible.
 This tool mostly focuses on issue search and navigation at the moment. However, it also includes features like issue creation,
 updating a ticket status, and so on.
 
-#### Note
-The tool:
-- Doesn't yet support pagination and returns 100 records by default.
-- Is only tested with the latest Jira cloud.
-
 ## Installation
 Install the runnable binary to your `$GOPATH/bin`.
 
@@ -45,8 +40,7 @@ Releases and other installation options will be available later.
 #### Shell completion
 Check `jira completion --help` for more info on setting up a bash/zsh shell completion. 
 
-## Known Limitations
-- The tool doesn't support pagination and returns 100 records by default.
+#### Known Limitations
 - The tool is only tested with the latest Jira cloud.
 - A key event is lost in mac OS when switching back and forth from view mode to list mode - [tcell/issues#194](https://github.com/gdamore/tcell/issues/194)
 
@@ -410,7 +404,6 @@ Sprint 1:   3
 - [x] Issue creation.
 - [x] Ability to view issue details.
 - [x] Possibility to change issue status.
-- [ ] Pagination support.
 - [ ] Historical data can be cached locally for faster execution.
 
 ## Development
diff --git a/internal/cmd/epic/list/list.go b/internal/cmd/epic/list/list.go
index b60aff7..bf4a52b 100644
--- a/internal/cmd/epic/list/list.go
+++ b/internal/cmd/epic/list/list.go
@@ -101,7 +101,7 @@ func singleEpicView(flags query.FlagParser, key, project, server string, client
 		q, err := query.NewIssue(project, flags)
 		cmdutil.ExitIfError(err)
 
-		resp, err := client.EpicIssues(key, q.Get())
+		resp, err := client.EpicIssues(key, q.Get(), q.Params().Limit)
 		cmdutil.ExitIfError(err)
 
 		return resp.Issues, resp.Total
@@ -145,14 +145,14 @@ func singleEpicView(flags query.FlagParser, key, project, server string, client
 }
 
 func epicExplorerView(flags query.FlagParser, project, server string, client *jira.Client) {
+	q, err := query.NewIssue(project, flags)
+	cmdutil.ExitIfError(err)
+
 	epics, total := func() ([]*jira.Issue, int) {
 		s := cmdutil.Info("Fetching epics...")
 		defer s.Stop()
 
-		q, err := query.NewIssue(project, flags)
-		cmdutil.ExitIfError(err)
-
-		resp, err := client.Search(q.Get())
+		resp, err := client.Search(q.Get(), q.Params().Limit)
 		cmdutil.ExitIfError(err)
 
 		return resp.Issues, resp.Total
@@ -168,7 +168,7 @@ func epicExplorerView(flags query.FlagParser, project, server string, client *ji
 		Server:  server,
 		Data:    epics,
 		Issues: func(key string) []*jira.Issue {
-			resp, err := client.EpicIssues(key, "")
+			resp, err := client.EpicIssues(key, "", q.Params().Limit)
 			if err != nil {
 				return []*jira.Issue{}
 			}
diff --git a/internal/cmd/issue/list/list.go b/internal/cmd/issue/list/list.go
index 3cb1c05..0f6505d 100644
--- a/internal/cmd/issue/list/list.go
+++ b/internal/cmd/issue/list/list.go
@@ -65,7 +65,7 @@ func List(cmd *cobra.Command, _ []string) {
 		q, err := query.NewIssue(project, cmd.Flags())
 		cmdutil.ExitIfError(err)
 
-		resp, err := api.Client(jira.Config{Debug: debug}).Search(q.Get())
+		resp, err := api.Client(jira.Config{Debug: debug}).Search(q.Get(), q.Params().Limit)
 		cmdutil.ExitIfError(err)
 
 		return resp.Issues, resp.Total
@@ -135,6 +135,7 @@ func SetFlags(cmd *cobra.Command) {
 	cmd.Flags().String("created-before", "", "Filter by issues created before certain date")
 	cmd.Flags().String("updated-before", "", "Filter by issues updated before certain date")
 	cmd.Flags().Bool("reverse", false, "Reverse the display order (default is DESC)")
+	cmd.Flags().Uint("limit", 100, "Number of results to return")
 	cmd.Flags().Bool("plain", false, "Display output in plain mode")
 	cmd.Flags().Bool("no-headers", false, "Don't display table headers in plain mode. Works only with --plain")
 	cmd.Flags().Bool("no-truncate", false, "Show all available columns in plain mode. Works only with --plain")
diff --git a/internal/cmd/sprint/list/list.go b/internal/cmd/sprint/list/list.go
index b48f0ef..fc454c1 100644
--- a/internal/cmd/sprint/list/list.go
+++ b/internal/cmd/sprint/list/list.go
@@ -96,7 +96,7 @@ func singleSprintView(flags query.FlagParser, boardID, sprintID int, project, se
 		q, err := query.NewIssue(project, flags)
 		cmdutil.ExitIfError(err)
 
-		resp, err := client.SprintIssues(boardID, sprintID, q.Get())
+		resp, err := client.SprintIssues(boardID, sprintID, q.Get(), q.Params().Limit)
 		cmdutil.ExitIfError(err)
 
 		return resp.Issues, resp.Total
@@ -194,7 +194,7 @@ func sprintExplorerView(flags query.FlagParser, boardID int, project, server str
 		Server:  server,
 		Data:    sprints,
 		Issues: func(boardID, sprintID int) []*jira.Issue {
-			resp, err := client.SprintIssues(boardID, sprintID, "")
+			resp, err := client.SprintIssues(boardID, sprintID, "", q.Params().Limit)
 			if err != nil {
 				return []*jira.Issue{}
 			}
diff --git a/internal/query/issue.go b/internal/query/issue.go
index 60ea4a3..f141239 100644
--- a/internal/query/issue.go
+++ b/internal/query/issue.go
@@ -11,12 +11,12 @@ import (
 type Issue struct {
 	Project string
 	Flags   FlagParser
-	params  *issueParams
+	params  *IssueParams
 }
 
 // NewIssue creates and initializes a new Issue type.
 func NewIssue(project string, flags FlagParser) (*Issue, error) {
-	ip := issueParams{}
+	ip := IssueParams{}
 	if err := ip.init(flags); err != nil {
 		return nil, err
 	}
@@ -30,35 +30,35 @@ func NewIssue(project string, flags FlagParser) (*Issue, error) {
 // Get returns constructed jql query.
 func (i *Issue) Get() string {
 	q, obf := jql.NewJQL(i.Project), "created"
-	if (i.params.updated != "" || i.params.updatedBefore != "" || i.params.updatedAfter != "") &&
-		(i.params.created == "" && i.params.createdBefore == "" && i.params.createdAfter == "") {
+	if (i.params.Updated != "" || i.params.UpdatedBefore != "" || i.params.UpdatedAfter != "") &&
+		(i.params.Created == "" && i.params.CreatedBefore == "" && i.params.CreatedAfter == "") {
 		obf = "updated"
 	}
 	q.And(func() {
-		if i.params.latest {
+		if i.params.Latest {
 			q.History()
 			obf = "lastViewed"
 		}
-		if i.params.watching {
+		if i.params.Watching {
 			q.Watching()
 		}
 
-		q.FilterBy("type", i.params.issueType).
-			FilterBy("resolution", i.params.resolution).
-			FilterBy("status", i.params.status).
-			FilterBy("priority", i.params.priority).
-			FilterBy("reporter", i.params.reporter).
-			FilterBy("assignee", i.params.assignee).
-			FilterBy("component", i.params.component)
+		q.FilterBy("type", i.params.IssueType).
+			FilterBy("resolution", i.params.Resolution).
+			FilterBy("status", i.params.Status).
+			FilterBy("priority", i.params.Priority).
+			FilterBy("reporter", i.params.Reporter).
+			FilterBy("assignee", i.params.Assignee).
+			FilterBy("component", i.params.Component)
 
 		i.setCreatedFilters(q)
 		i.setUpdatedFilters(q)
 
-		if len(i.params.labels) > 0 {
-			q.In("labels", i.params.labels...)
+		if len(i.params.Labels) > 0 {
+			q.In("labels", i.params.Labels...)
 		}
 	})
-	if i.params.reverse {
+	if i.params.Reverse {
 		q.OrderBy(obf, jql.DirectionAscending)
 	} else {
 		q.OrderBy(obf, jql.DirectionDescending)
@@ -69,6 +69,11 @@ func (i *Issue) Get() string {
 	return q.String()
 }
 
+// Params returns issue command params.
+func (i *Issue) Params() *IssueParams {
+	return i.params
+}
+
 func (i *Issue) setDateFilters(q *jql.JQL, field, value string) {
 	switch value {
 	case "today":
@@ -90,73 +95,55 @@ func (i *Issue) setDateFilters(q *jql.JQL, field, value string) {
 }
 
 func (i *Issue) setCreatedFilters(q *jql.JQL) {
-	if i.params.created != "" {
-		i.setDateFilters(q, "createdDate", i.params.created)
+	if i.params.Created != "" {
+		i.setDateFilters(q, "createdDate", i.params.Created)
 		return
 	}
-	if i.params.createdAfter != "" {
-		q.Gt("createdDate", i.params.createdAfter, true)
+	if i.params.CreatedAfter != "" {
+		q.Gt("createdDate", i.params.CreatedAfter, true)
 	}
-	if i.params.createdBefore != "" {
-		q.Lt("createdDate", i.params.createdBefore, true)
+	if i.params.CreatedBefore != "" {
+		q.Lt("createdDate", i.params.CreatedBefore, true)
 	}
 }
 
 func (i *Issue) setUpdatedFilters(q *jql.JQL) {
-	if i.params.updated != "" {
-		i.setDateFilters(q, "updatedDate", i.params.updated)
+	if i.params.Updated != "" {
+		i.setDateFilters(q, "updatedDate", i.params.Updated)
 		return
 	}
-	if i.params.updatedAfter != "" {
-		q.Gt("updatedDate", i.params.updatedAfter, true)
+	if i.params.UpdatedAfter != "" {
+		q.Gt("updatedDate", i.params.UpdatedAfter, true)
 	}
-	if i.params.updatedBefore != "" {
-		q.Lt("updatedDate", i.params.updatedBefore, true)
+	if i.params.UpdatedBefore != "" {
+		q.Lt("updatedDate", i.params.UpdatedBefore, true)
 	}
 }
 
-func isValidDate(date string) (time.Time, string, bool) {
-	supportedFormats := []string{
-		"2006-01-02",
-		"2006/01/02",
-		"2006-01-02 03:04",
-		"2006/01/02 03:04",
-	}
-	for _, format := range supportedFormats {
-		dt, err := time.Parse(format, date)
-		if err == nil {
-			return dt, format, true
-		}
-	}
-	return time.Now(), "", false
-}
-
-func addDay(dt time.Time, format string) string {
-	return dt.AddDate(0, 0, 1).Format(format)
-}
-
-type issueParams struct {
-	latest        bool
-	watching      bool
-	resolution    string
-	issueType     string
-	status        string
-	priority      string
-	reporter      string
-	assignee      string
-	component     string
-	created       string
-	updated       string
-	createdAfter  string
-	updatedAfter  string
-	createdBefore string
-	updatedBefore string
-	labels        []string
-	reverse       bool
+// IssueParams is issue command parameters.
+type IssueParams struct {
+	Latest        bool
+	Watching      bool
+	Resolution    string
+	IssueType     string
+	Status        string
+	Priority      string
+	Reporter      string
+	Assignee      string
+	Component     string
+	Created       string
+	Updated       string
+	CreatedAfter  string
+	UpdatedAfter  string
+	CreatedBefore string
+	UpdatedBefore string
+	Labels        []string
+	Reverse       bool
+	Limit         uint
 	debug         bool
 }
 
-func (ip *issueParams) init(flags FlagParser) error {
+func (ip *IssueParams) init(flags FlagParser) error {
 	var err error
 
 	boolParams := []string{"history", "watching", "reverse", "debug"}
@@ -183,58 +170,83 @@ func (ip *issueParams) init(flags FlagParser) error {
 	if err != nil {
 		return err
 	}
+	limit, err := flags.GetUint("limit")
+	if err != nil {
+		return err
+	}
 
-	ip.labels = labels
 	ip.setBoolParams(boolParamsMap)
 	ip.setStringParams(stringParamsMap)
+	ip.Labels = labels
+	ip.Limit = limit
 
 	return nil
 }
 
-func (ip *issueParams) setBoolParams(paramsMap map[string]bool) {
+func (ip *IssueParams) setBoolParams(paramsMap map[string]bool) {
 	for k, v := range paramsMap {
 		switch k {
 		case "history":
-			ip.latest = v
+			ip.Latest = v
 		case "watching":
-			ip.watching = v
+			ip.Watching = v
 		case "reverse":
-			ip.reverse = v
+			ip.Reverse = v
 		case "debug":
 			ip.debug = v
 		}
 	}
 }
 
-func (ip *issueParams) setStringParams(paramsMap map[string]string) {
+func (ip *IssueParams) setStringParams(paramsMap map[string]string) {
 	for k, v := range paramsMap {
 		switch k {
 		case "resolution":
-			ip.resolution = v
+			ip.Resolution = v
 		case "type":
-			ip.issueType = v
+			ip.IssueType = v
 		case "status":
-			ip.status = v
+			ip.Status = v
 		case "priority":
-			ip.priority = v
+			ip.Priority = v
 		case "reporter":
-			ip.reporter = v
+			ip.Reporter = v
 		case "assignee":
-			ip.assignee = v
+			ip.Assignee = v
 		case "component":
-			ip.component = v
+			ip.Component = v
 		case "created":
-			ip.created = v
+			ip.Created = v
 		case "created-after":
-			ip.createdAfter = v
+			ip.CreatedAfter = v
 		case "created-before":
-			ip.createdBefore = v
+			ip.CreatedBefore = v
 		case "updated":
-			ip.updated = v
+			ip.Updated = v
 		case "updated-after":
-			ip.updatedAfter = v
+			ip.UpdatedAfter = v
 		case "updated-before":
-			ip.updatedBefore = v
+			ip.UpdatedBefore = v
+		}
+	}
+}
+
+func isValidDate(date string) (time.Time, string, bool) {
+	supportedFormats := []string{
+		"2006-01-02",
+		"2006/01/02",
+		"2006-01-02 03:04",
+		"2006/01/02 03:04",
+	}
+	for _, format := range supportedFormats {
+		dt, err := time.Parse(format, date)
+		if err == nil {
+			return dt, format, true
 		}
 	}
+	return time.Now(), "", false
+}
+
+func addDay(dt time.Time, format string) string {
+	return dt.AddDate(0, 0, 1).Format(format)
 }
diff --git a/internal/query/query.go b/internal/query/query.go
index 24984e7..30e3206 100644
--- a/internal/query/query.go
+++ b/internal/query/query.go
@@ -5,5 +5,6 @@ type FlagParser interface {
 	GetBool(string) (bool, error)
 	GetString(string) (string, error)
 	GetStringArray(string) ([]string, error)
+	GetUint(name string) (uint, error)
 	Set(name, value string) error
 }
diff --git a/internal/query/sprint.go b/internal/query/sprint.go
index fc41f13..d0035c4 100644
--- a/internal/query/sprint.go
+++ b/internal/query/sprint.go
@@ -56,6 +56,7 @@ type SprintParams struct {
 	Current bool
 	Prev    bool
 	Next    bool
+	Limit   uint
 	debug   bool
 }
 
@@ -84,6 +85,12 @@ func (sp *SprintParams) init(flags FlagParser) error {
 	}
 	sp.Next = next
 
+	limit, err := flags.GetUint("limit")
+	if err != nil {
+		return err
+	}
+	sp.Limit = limit
+
 	debug, err := flags.GetBool("debug")
 	if err != nil {
 		return err
diff --git a/pkg/jira/epic.go b/pkg/jira/epic.go
index 3a73e3d..345ee4b 100644
--- a/pkg/jira/epic.go
+++ b/pkg/jira/epic.go
@@ -31,10 +31,10 @@ func (c *Client) Epic(jql string) (*SearchResult, error) {
 }
 
 // EpicIssues fetches issues in the given epic.
-func (c *Client) EpicIssues(key, jql string) (*SearchResult, error) {
-	path := fmt.Sprintf("/epic/%s/issue", key)
+func (c *Client) EpicIssues(key, jql string, limit uint) (*SearchResult, error) {
+	path := fmt.Sprintf("/epic/%s/issue?maxResults=%d", key, limit)
 	if jql != "" {
-		path += fmt.Sprintf("?jql=%s", url.QueryEscape(jql))
+		path += fmt.Sprintf("&jql=%s", url.QueryEscape(jql))
 	}
 
 	res, err := c.GetV1(context.Background(), path, nil)
diff --git a/pkg/jira/search.go b/pkg/jira/search.go
index a22f958..83b6228 100644
--- a/pkg/jira/search.go
+++ b/pkg/jira/search.go
@@ -8,8 +8,6 @@ import (
 	"net/url"
 )
 
-const maxResults = 100
-
 // SearchResult struct holds response from /search endpoint.
 type SearchResult struct {
 	StartAt    int      `json:"startAt"`
@@ -19,8 +17,8 @@ type SearchResult struct {
 }
 
 // Search fetches response from /search endpoint.
-func (c *Client) Search(jql string) (*SearchResult, error) {
-	path := fmt.Sprintf("/search?jql=%s&maxResults=%d", url.QueryEscape(jql), maxResults)
+func (c *Client) Search(jql string, limit uint) (*SearchResult, error) {
+	path := fmt.Sprintf("/search?jql=%s&maxResults=%d", url.QueryEscape(jql), limit)
 
 	res, err := c.Get(context.Background(), path, nil)
 	if err != nil {
diff --git a/pkg/jira/sprint.go b/pkg/jira/sprint.go
index 284020f..297f6a3 100644
--- a/pkg/jira/sprint.go
+++ b/pkg/jira/sprint.go
@@ -86,10 +86,10 @@ func (c *Client) SprintsInBoards(boardIDs []int, qp string, limit int) []*Sprint
 }
 
 // SprintIssues fetches issues in the given sprint.
-func (c *Client) SprintIssues(boardID, sprintID int, jql string) (*SearchResult, error) {
-	path := fmt.Sprintf("/board/%d/sprint/%d/issue", boardID, sprintID)
+func (c *Client) SprintIssues(boardID, sprintID int, jql string, limit uint) (*SearchResult, error) {
+	path := fmt.Sprintf("/board/%d/sprint/%d/issue?maxResults=%d", boardID, sprintID, limit)
 	if jql != "" {
-		path += fmt.Sprintf("?jql=%s", url.QueryEscape(jql))
+		path += fmt.Sprintf("&jql=%s", url.QueryEscape(jql))
 	}
 
 	res, err := c.GetV1(context.Background(), path, nil)


Test patch:
diff --git a/internal/query/issue_test.go b/internal/query/issue_test.go
index 3ca6a36..42431d8 100644
--- a/internal/query/issue_test.go
+++ b/internal/query/issue_test.go
@@ -100,9 +100,8 @@ func (tfp issueFlagParser) GetStringArray(name string) ([]string, error) {
 	return tfp.labels, nil
 }
 
-func (tfp issueFlagParser) Set(string, string) error {
-	return nil
-}
+func (tfp issueFlagParser) GetUint(string) (uint, error) { return 100, nil }
+func (tfp issueFlagParser) Set(string, string) error     { return nil }
 
 func TestIssueGet(t *testing.T) {
 	cases := []struct {
diff --git a/internal/query/sprint_test.go b/internal/query/sprint_test.go
index e01b07a..35b3847 100644
--- a/internal/query/sprint_test.go
+++ b/internal/query/sprint_test.go
@@ -20,36 +20,32 @@ type sprintFlagParser struct {
 	next    bool
 }
 
-func (tfp sprintFlagParser) GetBool(name string) (bool, error) {
-	if tfp.err.current && name == "current" {
+func (sfp sprintFlagParser) GetBool(name string) (bool, error) {
+	if sfp.err.current && name == "current" {
 		return true, fmt.Errorf("oops! couldn't fetch current flag")
 	}
-	if tfp.current && name == "current" {
+	if sfp.current && name == "current" {
 		return true, nil
 	}
-	if tfp.prev && name == "prev" {
+	if sfp.prev && name == "prev" {
 		return true, nil
 	}
-	if tfp.next && name == "next" {
+	if sfp.next && name == "next" {
 		return true, nil
 	}
 	return false, nil
 }
 
-func (tfp sprintFlagParser) GetString(name string) (string, error) {
-	if tfp.err.state && name == "state" {
+func (sfp sprintFlagParser) GetString(name string) (string, error) {
+	if sfp.err.state && name == "state" {
 		return "", fmt.Errorf("oops! couldn't fetch state flag")
 	}
-	return tfp.state, nil
+	return sfp.state, nil
 }
 
-func (tfp sprintFlagParser) GetStringArray(string) ([]string, error) {
-	return []string{}, nil
-}
-
-func (tfp sprintFlagParser) Set(string, string) error {
-	return nil
-}
+func (sfp sprintFlagParser) GetStringArray(string) ([]string, error) { return []string{}, nil }
+func (sfp sprintFlagParser) GetUint(string) (uint, error)            { return 100, nil }
+func (sfp sprintFlagParser) Set(string, string) error                { return nil }
 
 func TestSprintGet(t *testing.T) {
 	cases := []struct {
diff --git a/pkg/jira/epic_test.go b/pkg/jira/epic_test.go
index 484b80e..f3d5269 100644
--- a/pkg/jira/epic_test.go
+++ b/pkg/jira/epic_test.go
@@ -118,7 +118,8 @@ func TestEpicIssues(t *testing.T) {
 			w.WriteHeader(400)
 		} else {
 			assert.Equal(t, url.Values{
-				"jql": []string{"project=TEST AND status=Done ORDER BY created DESC"},
+				"jql":        []string{"project=TEST AND status=Done ORDER BY created DESC"},
+				"maxResults": []string{"100"},
 			}, qs)
 
 			resp, err := ioutil.ReadFile("./testdata/search.json")
@@ -133,7 +134,7 @@ func TestEpicIssues(t *testing.T) {
 
 	client := NewClient(Config{Server: server.URL}, WithTimeout(3))
 
-	actual, err := client.EpicIssues("TEST-0", "project=TEST AND status=Done ORDER BY created DESC")
+	actual, err := client.EpicIssues("TEST-0", "project=TEST AND status=Done ORDER BY created DESC", 100)
 	assert.NoError(t, err)
 
 	expected := &SearchResult{
@@ -228,6 +229,6 @@ func TestEpicIssues(t *testing.T) {
 
 	unexpectedStatusCode = true
 
-	_, err = client.EpicIssues("TEST-0", "project=TEST")
+	_, err = client.EpicIssues("TEST-0", "project=TEST", 100)
 	assert.Error(t, ErrUnexpectedStatusCode, err)
 }
diff --git a/pkg/jira/search_test.go b/pkg/jira/search_test.go
index 81eaeb7..1b68e5a 100644
--- a/pkg/jira/search_test.go
+++ b/pkg/jira/search_test.go
@@ -39,7 +39,7 @@ func TestSearch(t *testing.T) {
 
 	client := NewClient(Config{Server: server.URL}, WithTimeout(3))
 
-	actual, err := client.Search("project=TEST AND status=Done ORDER BY created DESC")
+	actual, err := client.Search("project=TEST AND status=Done ORDER BY created DESC", 100)
 	assert.NoError(t, err)
 
 	expected := &SearchResult{
@@ -134,6 +134,6 @@ func TestSearch(t *testing.T) {
 
 	unexpectedStatusCode = true
 
-	_, err = client.Search("project=TEST")
+	_, err = client.Search("project=TEST", 100)
 	assert.Error(t, ErrUnexpectedStatusCode, err)
 }
diff --git a/pkg/jira/sprint_test.go b/pkg/jira/sprint_test.go
index 41e4efa..b4f4ec6 100644
--- a/pkg/jira/sprint_test.go
+++ b/pkg/jira/sprint_test.go
@@ -195,7 +195,8 @@ func TestSprintIssues(t *testing.T) {
 			w.WriteHeader(400)
 		} else {
 			assert.Equal(t, url.Values{
-				"jql": []string{"project=TEST AND status=Done ORDER BY created DESC"},
+				"jql":        []string{"project=TEST AND status=Done ORDER BY created DESC"},
+				"maxResults": []string{"100"},
 			}, qs)
 
 			resp, err := ioutil.ReadFile("./testdata/search.json")
@@ -210,7 +211,7 @@ func TestSprintIssues(t *testing.T) {
 
 	client := NewClient(Config{Server: server.URL}, WithTimeout(3))
 
-	actual, err := client.SprintIssues(1, 2, "project=TEST AND status=Done ORDER BY created DESC")
+	actual, err := client.SprintIssues(1, 2, "project=TEST AND status=Done ORDER BY created DESC", 100)
 	assert.NoError(t, err)
 
 	expected := &SearchResult{
@@ -305,6 +306,6 @@ func TestSprintIssues(t *testing.T) {
 
 	unexpectedStatusCode = true
 
-	_, err = client.SprintIssues(1, 2, "project=TEST")
+	_, err = client.SprintIssues(1, 2, "project=TEST", 100)
 	assert.Error(t, ErrUnexpectedStatusCode, err)
 }