jira-ruby 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +7 -1
  3. data/Guardfile +1 -1
  4. data/Rakefile +4 -5
  5. data/http-basic-example.rb +13 -12
  6. data/jira-ruby.gemspec +9 -10
  7. data/lib/jira-ruby.rb +5 -2
  8. data/lib/jira/base.rb +49 -48
  9. data/lib/jira/base_factory.rb +1 -4
  10. data/lib/jira/client.rb +29 -20
  11. data/lib/jira/has_many_proxy.rb +0 -1
  12. data/lib/jira/http_client.rb +9 -10
  13. data/lib/jira/http_error.rb +3 -5
  14. data/lib/jira/oauth_client.rb +19 -20
  15. data/lib/jira/request_client.rb +3 -4
  16. data/lib/jira/resource/agile.rb +10 -8
  17. data/lib/jira/resource/applinks.rb +5 -8
  18. data/lib/jira/resource/attachment.rb +1 -2
  19. data/lib/jira/resource/board.rb +84 -0
  20. data/lib/jira/resource/comment.rb +0 -2
  21. data/lib/jira/resource/component.rb +1 -3
  22. data/lib/jira/resource/createmeta.rb +12 -14
  23. data/lib/jira/resource/field.rb +22 -22
  24. data/lib/jira/resource/filter.rb +2 -2
  25. data/lib/jira/resource/issue.rb +41 -39
  26. data/lib/jira/resource/issuelink.rb +3 -5
  27. data/lib/jira/resource/issuelinktype.rb +0 -1
  28. data/lib/jira/resource/issuetype.rb +1 -3
  29. data/lib/jira/resource/priority.rb +1 -3
  30. data/lib/jira/resource/project.rb +5 -7
  31. data/lib/jira/resource/rapidview.rb +28 -7
  32. data/lib/jira/resource/remotelink.rb +1 -4
  33. data/lib/jira/resource/resolution.rb +2 -4
  34. data/lib/jira/resource/serverinfo.rb +1 -2
  35. data/lib/jira/resource/sprint.rb +82 -18
  36. data/lib/jira/resource/sprint_report.rb +8 -0
  37. data/lib/jira/resource/status.rb +1 -3
  38. data/lib/jira/resource/transition.rb +2 -6
  39. data/lib/jira/resource/user.rb +12 -2
  40. data/lib/jira/resource/version.rb +1 -3
  41. data/lib/jira/resource/watcher.rb +1 -5
  42. data/lib/jira/resource/webhook.rb +3 -6
  43. data/lib/jira/resource/worklog.rb +3 -5
  44. data/lib/jira/version.rb +1 -1
  45. data/lib/tasks/generate.rake +4 -4
  46. data/spec/integration/attachment_spec.rb +15 -16
  47. data/spec/integration/comment_spec.rb +31 -34
  48. data/spec/integration/component_spec.rb +21 -24
  49. data/spec/integration/field_spec.rb +15 -18
  50. data/spec/integration/issue_spec.rb +44 -48
  51. data/spec/integration/issuelinktype_spec.rb +8 -11
  52. data/spec/integration/issuetype_spec.rb +5 -7
  53. data/spec/integration/priority_spec.rb +5 -8
  54. data/spec/integration/project_spec.rb +13 -20
  55. data/spec/integration/rapidview_spec.rb +17 -10
  56. data/spec/integration/resolution_spec.rb +7 -10
  57. data/spec/integration/status_spec.rb +5 -8
  58. data/spec/integration/transition_spec.rb +17 -20
  59. data/spec/integration/user_spec.rb +24 -8
  60. data/spec/integration/version_spec.rb +21 -25
  61. data/spec/integration/watcher_spec.rb +28 -34
  62. data/spec/integration/webhook.rb +8 -17
  63. data/spec/integration/worklog_spec.rb +30 -34
  64. data/spec/jira/base_factory_spec.rb +11 -12
  65. data/spec/jira/base_spec.rb +204 -228
  66. data/spec/jira/client_spec.rb +26 -28
  67. data/spec/jira/has_many_proxy_spec.rb +11 -12
  68. data/spec/jira/http_client_spec.rb +51 -52
  69. data/spec/jira/http_error_spec.rb +7 -9
  70. data/spec/jira/oauth_client_spec.rb +44 -46
  71. data/spec/jira/request_client_spec.rb +5 -5
  72. data/spec/jira/resource/agile_spec.rb +5 -7
  73. data/spec/jira/resource/attachment_spec.rb +25 -26
  74. data/spec/jira/resource/board_spec.rb +175 -0
  75. data/spec/jira/resource/createmeta_spec.rb +29 -32
  76. data/spec/jira/resource/field_spec.rb +42 -48
  77. data/spec/jira/resource/filter_spec.rb +40 -40
  78. data/spec/jira/resource/issue_spec.rb +87 -89
  79. data/spec/jira/resource/issuelink_spec.rb +1 -1
  80. data/spec/jira/resource/project_factory_spec.rb +2 -4
  81. data/spec/jira/resource/project_spec.rb +33 -33
  82. data/spec/jira/resource/sprint_spec.rb +78 -0
  83. data/spec/jira/resource/user_factory_spec.rb +6 -8
  84. data/spec/jira/resource/worklog_spec.rb +9 -11
  85. data/spec/spec_helper.rb +8 -9
  86. data/spec/support/clients_helper.rb +4 -4
  87. data/spec/support/shared_examples/integration.rb +60 -77
  88. metadata +59 -53
@@ -1,6 +1,5 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class CommentFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
@@ -9,6 +8,5 @@ module JIRA
9
8
 
10
9
  nested_collections true
11
10
  end
12
-
13
11
  end
14
12
  end
@@ -1,10 +1,8 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class ComponentFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
7
- class Component < JIRA::Base ; end
8
-
6
+ class Component < JIRA::Base; end
9
7
  end
10
8
  end
@@ -1,6 +1,5 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class CreatemetaFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
@@ -9,36 +8,35 @@ module JIRA
9
8
  '/issue/createmeta'
10
9
  end
11
10
 
12
- def self.all(client, params={})
13
-
14
- if params.has_key?(:projectKeys)
15
- values = Array(params[:projectKeys]).map{|i| (i.is_a?(JIRA::Resource::Project) ? i.key : i)}
11
+ def self.all(client, params = {})
12
+ if params.key?(:projectKeys)
13
+ values = Array(params[:projectKeys]).map { |i| (i.is_a?(JIRA::Resource::Project) ? i.key : i) }
16
14
  params[:projectKeys] = values.join(',')
17
15
  end
18
16
 
19
- if params.has_key?(:projectIds)
20
- values = Array(params[:projectIds]).map{|i| (i.is_a?(JIRA::Resource::Project) ? i.id : i)}
17
+ if params.key?(:projectIds)
18
+ values = Array(params[:projectIds]).map { |i| (i.is_a?(JIRA::Resource::Project) ? i.id : i) }
21
19
  params[:projectIds] = values.join(',')
22
20
  end
23
21
 
24
- if params.has_key?(:issuetypeNames)
25
- values = Array(params[:issuetypeNames]).map{|i| (i.is_a?(JIRA::Resource::Issuetype) ? i.name : i)}
22
+ if params.key?(:issuetypeNames)
23
+ values = Array(params[:issuetypeNames]).map { |i| (i.is_a?(JIRA::Resource::Issuetype) ? i.name : i) }
26
24
  params[:issuetypeNames] = values.join(',')
27
25
  end
28
26
 
29
- if params.has_key?(:issuetypeIds)
30
- values = Array(params[:issuetypeIds]).map{|i| (i.is_a?(JIRA::Resource::Issuetype) ? i.id : i)}
27
+ if params.key?(:issuetypeIds)
28
+ values = Array(params[:issuetypeIds]).map { |i| (i.is_a?(JIRA::Resource::Issuetype) ? i.id : i) }
31
29
  params[:issuetypeIds] = values.join(',')
32
30
  end
33
31
 
34
- create_meta_url = client.options[:rest_base_path] + self.endpoint_name
32
+ create_meta_url = client.options[:rest_base_path] + endpoint_name
35
33
  params = hash_to_query_string(params)
36
34
 
37
- response = params.empty? ? client.get("#{create_meta_url}") : client.get("#{create_meta_url}?#{params}")
35
+ response = params.empty? ? client.get(create_meta_url.to_s) : client.get("#{create_meta_url}?#{params}")
38
36
 
39
37
  json = parse_json(response.body)
40
38
  json['projects'].map do |attrs|
41
- self.new(client, {:attrs => attrs})
39
+ new(client, attrs: attrs)
42
40
  end
43
41
  end
44
42
  end
@@ -1,20 +1,20 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class FieldFactory < JIRA::BaseFactory # :nodoc:
5
- delegate_to_target_class :map_fields, :name_to_id, :field_map
4
+ delegate_to_target_class :map_fields, :name_to_id, :field_map
6
5
  end
7
6
 
8
7
  class Field < JIRA::Base
9
-
10
- #translate a custom field description to a method-safe name
8
+ # translate a custom field description to a method-safe name
11
9
  def self.safe_name(description)
12
- description.gsub(/[^a-zA-Z0-9]/,'_')
10
+ description.gsub(/[^a-zA-Z0-9]/, '_')
13
11
  end
14
12
 
15
13
  # safe_name plus disambiguation if it fails it uses the original jira id (customfield_#####)
16
14
  def self.safer_name(description, jira_id)
17
- "#{safe_name(description)}_#{jira_id.split('_')[1]}" rescue jira_id
15
+ "#{safe_name(description)}_#{jira_id.split('_')[1]}"
16
+ rescue StandardError
17
+ jira_id
18
18
  end
19
19
 
20
20
  def self.map_fields(client)
@@ -34,17 +34,17 @@ module JIRA
34
34
  fields.each do |f|
35
35
  next unless f.custom
36
36
  name = if field_map.key? f.name
37
- renamed = safer_name(f.name, f.id)
38
- warn "Duplicate Field name #{f.name} #{f.id} - renaming as #{renamed}"
39
- renamed
40
- else
41
- safe_name(f.name)
37
+ renamed = safer_name(f.name, f.id)
38
+ warn "Duplicate Field name #{f.name} #{f.id} - renaming as #{renamed}"
39
+ renamed
40
+ else
41
+ safe_name(f.name)
42
42
  end
43
43
  field_map_reverse[f.id] = [f.name, name] # capture both the official name, and the mapped name
44
44
  field_map[name] = f.id
45
45
  end
46
46
 
47
- client.cache.field_map_reverse = field_map_reverse # not sure where this will be used yet, but sure to be useful
47
+ client.cache.field_map_reverse = field_map_reverse # not sure where this will be used yet, but sure to be useful
48
48
  client.cache.field_map = field_map
49
49
  end
50
50
 
@@ -58,8 +58,8 @@ module JIRA
58
58
  client.cache.field_map[field_name]
59
59
  end
60
60
 
61
- def respond_to?(method_name, include_all=false)
62
- if [method_name.to_s, client.Field.name_to_id(method_name)].any? {|k| attrs.key?(k)}
61
+ def respond_to?(method_name, _include_all = false)
62
+ if [method_name.to_s, client.Field.name_to_id(method_name)].any? { |k| attrs.key?(k) }
63
63
  true
64
64
  else
65
65
  super(method_name)
@@ -67,16 +67,16 @@ module JIRA
67
67
  end
68
68
 
69
69
  def method_missing(method_name, *args, &block)
70
- if attrs.keys.include?(method_name.to_s)
71
- attrs[method_name.to_s]
70
+ if attrs.key?(method_name.to_s)
71
+ attrs[method_name.to_s]
72
+ else
73
+ official_name = client.Field.name_to_id(method_name)
74
+ if attrs.key?(official_name)
75
+ attrs[official_name]
72
76
  else
73
- official_name=client.Field.name_to_id(method_name)
74
- if attrs.keys.include?(official_name)
75
- attrs[official_name]
76
- else
77
- super(method_name, *args, &block)
78
- end
77
+ super(method_name, *args, &block)
79
78
  end
79
+ end
80
80
  end
81
81
  end
82
82
  end
@@ -4,11 +4,11 @@ module JIRA
4
4
  end
5
5
 
6
6
  class Filter < JIRA::Base
7
- has_one :owner, :class => JIRA::Resource::User
7
+ has_one :owner, class: JIRA::Resource::User
8
8
 
9
9
  # Returns all the issues for this filter
10
10
  def issues
11
- Issue.jql(self.client, self.jql)
11
+ Issue.jql(client, jql)
12
12
  end
13
13
  end
14
14
  end
@@ -1,46 +1,50 @@
1
1
  require 'cgi'
2
+ require 'json'
2
3
 
3
4
  module JIRA
4
5
  module Resource
5
-
6
6
  class IssueFactory < JIRA::BaseFactory # :nodoc:
7
7
  end
8
8
 
9
9
  class Issue < JIRA::Base
10
+ has_one :reporter, class: JIRA::Resource::User,
11
+ nested_under: 'fields'
12
+ has_one :assignee, class: JIRA::Resource::User,
13
+ nested_under: 'fields'
14
+ has_one :project, nested_under: 'fields'
10
15
 
11
- has_one :reporter, :class => JIRA::Resource::User,
12
- :nested_under => 'fields'
13
- has_one :assignee, :class => JIRA::Resource::User,
14
- :nested_under => 'fields'
15
- has_one :project, :nested_under => 'fields'
16
-
17
- has_one :issuetype, :nested_under => 'fields'
16
+ has_one :issuetype, nested_under: 'fields'
18
17
 
19
- has_one :priority, :nested_under => 'fields'
18
+ has_one :priority, nested_under: 'fields'
20
19
 
21
- has_one :status, :nested_under => 'fields'
20
+ has_one :status, nested_under: 'fields'
22
21
 
23
22
  has_many :transitions
24
23
 
25
- has_many :components, :nested_under => 'fields'
24
+ has_many :components, nested_under: 'fields'
25
+
26
+ has_many :comments, nested_under: %w[fields comment]
26
27
 
27
- has_many :comments, :nested_under => ['fields','comment']
28
+ has_many :attachments, nested_under: 'fields',
29
+ attribute_key: 'attachment'
28
30
 
29
- has_many :attachments, :nested_under => 'fields',
30
- :attribute_key => 'attachment'
31
+ has_many :versions, nested_under: 'fields'
32
+ has_many :fixVersions, class: JIRA::Resource::Version,
33
+ nested_under: 'fields'
31
34
 
32
- has_many :versions, :nested_under => 'fields'
33
- has_many :fixVersions, :class => JIRA::Resource::Version,
34
- :nested_under => 'fields'
35
+ has_many :worklogs, nested_under: %w[fields worklog]
36
+ has_one :sprint, class: JIRA::Resource::Sprint,
37
+ nested_under: 'fields'
35
38
 
36
- has_many :worklogs, :nested_under => ['fields','worklog']
39
+ has_many :closed_sprints, class: JIRA::Resource::Sprint,
40
+ nested_under: 'fields', attribute_key: 'closedSprints'
37
41
 
38
- has_many :issuelinks, :nested_under => 'fields'
42
+ has_many :issuelinks, nested_under: 'fields'
39
43
 
40
- has_many :remotelink, :class => JIRA::Resource::Remotelink
44
+ has_many :remotelink, class: JIRA::Resource::Remotelink
41
45
 
42
- has_many :watchers, :attribute_key => 'watches',
43
- :nested_under => ['fields', 'watches']
46
+ has_many :watchers, attribute_key: 'watches',
47
+ nested_under: %w[fields watches]
44
48
 
45
49
  def self.all(client)
46
50
  start_at = 0
@@ -54,28 +58,28 @@ module JIRA
54
58
  json['issues'].map do |issue|
55
59
  result.push(client.Issue.build(issue))
56
60
  end
57
- break if json['issues'].size == 0
61
+ break if json['issues'].empty?
58
62
  start_at += json['issues'].size
59
63
  end
60
64
  result
61
65
  end
62
66
 
63
- def self.jql(client, jql, options = {fields: nil, start_at: nil, max_results: nil, expand: nil, validate_query: true})
67
+ def self.jql(client, jql, options = { fields: nil, start_at: nil, max_results: nil, expand: nil, validate_query: true })
64
68
  url = client.options[:rest_base_path] + "/search?jql=#{CGI.escape(jql)}"
65
69
 
66
- url << "&fields=#{options[:fields].map{ |value| CGI.escape(client.Field.name_to_id(value)) }.join(',')}" if options[:fields]
70
+ url << "&fields=#{options[:fields].map { |value| CGI.escape(client.Field.name_to_id(value)) }.join(',')}" if options[:fields]
67
71
  url << "&startAt=#{CGI.escape(options[:start_at].to_s)}" if options[:start_at]
68
72
  url << "&maxResults=#{CGI.escape(options[:max_results].to_s)}" if options[:max_results]
69
- url << "&validateQuery=false" if options[:validate_query] === false
73
+ url << '&validateQuery=false' if options[:validate_query] === false
70
74
 
71
75
  if options[:expand]
72
76
  options[:expand] = [options[:expand]] if options[:expand].is_a?(String)
73
- url << "&expand=#{options[:expand].to_a.map{ |value| CGI.escape(value.to_s) }.join(',')}"
77
+ url << "&expand=#{options[:expand].to_a.map { |value| CGI.escape(value.to_s) }.join(',')}"
74
78
  end
75
79
 
76
80
  response = client.get(url)
77
81
  json = parse_json(response.body)
78
- if options[:max_results] and options[:max_results] == 0
82
+ if options[:max_results] && (options[:max_results] == 0)
79
83
  return json['total']
80
84
  end
81
85
  json['issues'].map do |issue|
@@ -90,11 +94,11 @@ module JIRA
90
94
  return if expanded? && !reload
91
95
  response = client.get(url_with_query_params(url, query_params))
92
96
  set_attrs_from_response(response)
93
- if @attrs and @attrs['fields'] and @attrs['fields']['worklog'] and @attrs['fields']['worklog']['total'] > @attrs['fields']['worklog']['maxResults']
97
+ if @attrs && @attrs['fields'] && @attrs['fields']['worklog'] && (@attrs['fields']['worklog']['total'] > @attrs['fields']['worklog']['maxResults'])
94
98
  worklog_url = client.options[:rest_base_path] + "/#{self.class.endpoint_name}/#{id}/worklog"
95
99
  response = client.get(worklog_url)
96
- unless response.body.nil? or response.body.length < 2
97
- set_attrs({'fields' => { 'worklog' => self.class.parse_json(response.body) }}, false)
100
+ unless response.body.nil? || (response.body.length < 2)
101
+ set_attrs({ 'fields' => { 'worklog' => self.class.parse_json(response.body) } }, false)
98
102
  end
99
103
  end
100
104
  @expanded = true
@@ -108,8 +112,8 @@ module JIRA
108
112
  json['fields']
109
113
  end
110
114
 
111
- def respond_to?(method_name, include_all=false)
112
- if attrs.keys.include?('fields') && [method_name.to_s, client.Field.name_to_id(method_name)].any? {|k| attrs['fields'].key?(k)}
115
+ def respond_to?(method_name, _include_all = false)
116
+ if attrs.key?('fields') && [method_name.to_s, client.Field.name_to_id(method_name)].any? { |k| attrs['fields'].key?(k) }
113
117
  true
114
118
  else
115
119
  super(method_name)
@@ -117,12 +121,12 @@ module JIRA
117
121
  end
118
122
 
119
123
  def method_missing(method_name, *args, &block)
120
- if attrs.keys.include?('fields')
121
- if attrs['fields'].keys.include?(method_name.to_s)
124
+ if attrs.key?('fields')
125
+ if attrs['fields'].key?(method_name.to_s)
122
126
  attrs['fields'][method_name.to_s]
123
127
  else
124
- official_name=client.Field.name_to_id(method_name)
125
- if attrs['fields'].keys.include?(official_name)
128
+ official_name = client.Field.name_to_id(method_name)
129
+ if attrs['fields'].key?(official_name)
126
130
  attrs['fields'][official_name]
127
131
  else
128
132
  super(method_name, *args, &block)
@@ -132,8 +136,6 @@ module JIRA
132
136
  super(method_name, *args, &block)
133
137
  end
134
138
  end
135
-
136
139
  end
137
-
138
140
  end
139
141
  end
@@ -1,6 +1,5 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class IssuelinkFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
@@ -9,14 +8,13 @@ module JIRA
9
8
  class Issue < JIRA::Base; end
10
9
 
11
10
  class Issuelink < JIRA::Base
12
- has_one :type, :class => JIRA::Resource::Issuelinktype
13
- has_one :inwardIssue, :class => JIRA::Resource::Issue
14
- has_one :outwardIssue, :class => JIRA::Resource::Issue
11
+ has_one :type, class: JIRA::Resource::Issuelinktype
12
+ has_one :inwardIssue, class: JIRA::Resource::Issue
13
+ has_one :outwardIssue, class: JIRA::Resource::Issue
15
14
 
16
15
  def self.endpoint_name
17
16
  'issueLink'
18
17
  end
19
-
20
18
  end
21
19
  end
22
20
  end
@@ -1,6 +1,5 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class IssuelinktypeFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
@@ -1,10 +1,8 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class IssuetypeFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
7
- class Issuetype < JIRA::Base ; end
8
-
6
+ class Issuetype < JIRA::Base; end
9
7
  end
10
8
  end
@@ -1,10 +1,8 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class PriorityFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
7
- class Priority < JIRA::Base ; end
8
-
6
+ class Priority < JIRA::Base; end
9
7
  end
10
8
  end
@@ -1,14 +1,12 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class ProjectFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
7
6
  class Project < JIRA::Base
8
-
9
- has_one :lead, :class => JIRA::Resource::User
7
+ has_one :lead, class: JIRA::Resource::User
10
8
  has_many :components
11
- has_many :issuetypes, :attribute_key => 'issueTypes'
9
+ has_many :issuetypes, attribute_key: 'issueTypes'
12
10
  has_many :versions
13
11
 
14
12
  def self.key_attribute
@@ -16,9 +14,9 @@ module JIRA
16
14
  end
17
15
 
18
16
  # Returns all the issues for this project
19
- def issues(options={})
17
+ def issues(options = {})
20
18
  search_url = client.options[:rest_base_path] + '/search'
21
- query_params = {:jql => "project=\"#{key}\""}
19
+ query_params = { jql: "project=\"#{key}\"" }
22
20
  query_params.update Base.query_params_for_search(options)
23
21
  response = client.get(url_with_query_params(search_url, query_params))
24
22
  json = self.class.parse_json(response.body)
@@ -29,7 +27,7 @@ module JIRA
29
27
 
30
28
  def users(start_at: nil, max_results: nil)
31
29
  users_url = client.options[:rest_base_path] + '/user/assignable/search'
32
- query_params = { project: self.key_value }
30
+ query_params = { project: key_value }
33
31
  query_params['startAt'] = start_at if start_at
34
32
  query_params['maxResults'] = max_results if max_results
35
33
  response = client.get(url_with_query_params(users_url, query_params))
@@ -2,12 +2,10 @@ require 'cgi'
2
2
 
3
3
  module JIRA
4
4
  module Resource
5
-
6
5
  class RapidViewFactory < JIRA::BaseFactory # :nodoc:
7
6
  end
8
7
 
9
8
  class RapidView < JIRA::Base
10
-
11
9
  def self.all(client)
12
10
  response = client.get(path_base(client) + '/rapidview')
13
11
  json = parse_json(response.body)
@@ -16,18 +14,43 @@ module JIRA
16
14
  end
17
15
  end
18
16
 
19
- def self.find(client, key, options = {})
17
+ def self.find(client, key, _options = {})
20
18
  response = client.get(path_base(client) + "/rapidview/#{key}")
21
19
  json = parse_json(response.body)
22
20
  client.RapidView.build(json)
23
21
  end
24
22
 
25
- def issues
23
+ def issues(options = {})
26
24
  response = client.get(path_base(client) + "/xboard/plan/backlog/data?rapidViewId=#{id}")
27
25
  json = self.class.parse_json(response.body)
28
26
  # To get Issue objects with the same structure as for Issue.all
29
27
  issue_ids = json['issues'].map { |issue| issue['id'] }
30
- client.Issue.jql("id IN(#{issue_ids.join(', ')})")
28
+
29
+ # First we have to get all IDs of parent and sub tasks
30
+ jql = "id IN(#{issue_ids.join(', ')})"
31
+
32
+ # Filtering options
33
+ jql << ' AND sprint IS NOT EMPTY' unless options[:include_backlog_items]
34
+
35
+ parent_issues = client.Issue.jql(jql)
36
+ subtask_ids = parent_issues.map { |t| t.subtasks.map { |sub| sub['id'] } }.flatten
37
+
38
+ parent_and_sub_ids = parent_issues.map(&:id) + subtask_ids
39
+ jql = "id IN(#{parent_and_sub_ids.join(', ')})"
40
+ jql << " and updated >= '#{options.delete(:updated)}'" if options[:updated]
41
+
42
+ client.Issue.jql(jql)
43
+ end
44
+
45
+ def sprints(options = {})
46
+ params = { includeHistoricSprints: options.fetch(:include_historic, false),
47
+ includeFutureSprints: options.fetch(:include_future, false) }
48
+ response = client.get(path_base(client) + "/sprintquery/#{id}?#{params.to_query}")
49
+ json = self.class.parse_json(response.body)
50
+ json['sprints'].map do |sprint|
51
+ sprint['rapidview_id'] = id
52
+ client.Sprint.build(sprint)
53
+ end
31
54
  end
32
55
 
33
56
  private
@@ -39,8 +62,6 @@ module JIRA
39
62
  def path_base(client)
40
63
  self.class.path_base(client)
41
64
  end
42
-
43
65
  end
44
-
45
66
  end
46
67
  end