jira-ruby 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
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