jira-ruby 1.2.0 → 2.3.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 (109) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -0
  3. data/.travis.yml +5 -3
  4. data/Gemfile +7 -1
  5. data/Guardfile +1 -1
  6. data/README.md +452 -0
  7. data/Rakefile +6 -7
  8. data/example.rb +23 -1
  9. data/http-basic-example.rb +13 -12
  10. data/jira-ruby.gemspec +13 -13
  11. data/lib/jira/base.rb +53 -52
  12. data/lib/jira/base_factory.rb +3 -6
  13. data/lib/jira/client.rb +127 -30
  14. data/lib/jira/has_many_proxy.rb +0 -1
  15. data/lib/jira/http_client.rb +54 -16
  16. data/lib/jira/http_error.rb +3 -5
  17. data/lib/jira/jwt_client.rb +67 -0
  18. data/lib/jira/oauth_client.rb +47 -17
  19. data/lib/jira/request_client.rb +16 -5
  20. data/lib/jira/resource/agile.rb +34 -9
  21. data/lib/jira/resource/applinks.rb +5 -8
  22. data/lib/jira/resource/attachment.rb +41 -3
  23. data/lib/jira/resource/board.rb +91 -0
  24. data/lib/jira/resource/board_configuration.rb +9 -0
  25. data/lib/jira/resource/comment.rb +0 -2
  26. data/lib/jira/resource/component.rb +1 -3
  27. data/lib/jira/resource/createmeta.rb +12 -14
  28. data/lib/jira/resource/field.rb +22 -22
  29. data/lib/jira/resource/filter.rb +2 -2
  30. data/lib/jira/resource/issue.rb +69 -38
  31. data/lib/jira/resource/issue_picker_suggestions.rb +24 -0
  32. data/lib/jira/resource/issue_picker_suggestions_issue.rb +10 -0
  33. data/lib/jira/resource/issuelink.rb +3 -5
  34. data/lib/jira/resource/issuelinktype.rb +0 -1
  35. data/lib/jira/resource/issuetype.rb +1 -3
  36. data/lib/jira/resource/priority.rb +1 -3
  37. data/lib/jira/resource/project.rb +5 -7
  38. data/lib/jira/resource/rapidview.rb +28 -7
  39. data/lib/jira/resource/remotelink.rb +1 -4
  40. data/lib/jira/resource/resolution.rb +2 -4
  41. data/lib/jira/resource/serverinfo.rb +1 -2
  42. data/lib/jira/resource/sprint.rb +86 -17
  43. data/lib/jira/resource/sprint_report.rb +8 -0
  44. data/lib/jira/resource/status.rb +1 -3
  45. data/lib/jira/resource/suggested_issue.rb +9 -0
  46. data/lib/jira/resource/transition.rb +2 -6
  47. data/lib/jira/resource/user.rb +12 -2
  48. data/lib/jira/resource/version.rb +1 -3
  49. data/lib/jira/resource/watcher.rb +35 -0
  50. data/lib/jira/resource/webhook.rb +3 -6
  51. data/lib/jira/resource/worklog.rb +3 -5
  52. data/lib/jira/version.rb +1 -1
  53. data/lib/jira-ruby.rb +12 -2
  54. data/lib/tasks/generate.rake +4 -4
  55. data/spec/integration/attachment_spec.rb +17 -8
  56. data/spec/integration/comment_spec.rb +31 -34
  57. data/spec/integration/component_spec.rb +21 -24
  58. data/spec/integration/field_spec.rb +15 -18
  59. data/spec/integration/issue_spec.rb +45 -46
  60. data/spec/integration/issuelinktype_spec.rb +8 -11
  61. data/spec/integration/issuetype_spec.rb +5 -7
  62. data/spec/integration/priority_spec.rb +5 -8
  63. data/spec/integration/project_spec.rb +13 -20
  64. data/spec/integration/rapidview_spec.rb +17 -10
  65. data/spec/integration/resolution_spec.rb +7 -10
  66. data/spec/integration/status_spec.rb +5 -8
  67. data/spec/integration/transition_spec.rb +17 -20
  68. data/spec/integration/user_spec.rb +24 -8
  69. data/spec/integration/version_spec.rb +21 -25
  70. data/spec/integration/watcher_spec.rb +62 -0
  71. data/spec/integration/webhook.rb +8 -17
  72. data/spec/integration/worklog_spec.rb +30 -34
  73. data/spec/jira/base_factory_spec.rb +11 -12
  74. data/spec/jira/base_spec.rb +216 -229
  75. data/spec/jira/client_spec.rb +227 -159
  76. data/spec/jira/has_many_proxy_spec.rb +11 -12
  77. data/spec/jira/http_client_spec.rb +254 -31
  78. data/spec/jira/http_error_spec.rb +7 -9
  79. data/spec/jira/jwt_uri_builder_spec.rb +59 -0
  80. data/spec/jira/oauth_client_spec.rb +110 -39
  81. data/spec/jira/request_client_spec.rb +36 -9
  82. data/spec/jira/resource/agile_spec.rb +135 -0
  83. data/spec/jira/resource/attachment_spec.rb +127 -9
  84. data/spec/jira/resource/board_spec.rb +224 -0
  85. data/spec/jira/resource/createmeta_spec.rb +29 -32
  86. data/spec/jira/resource/field_spec.rb +42 -48
  87. data/spec/jira/resource/filter_spec.rb +40 -40
  88. data/spec/jira/resource/issue_picker_suggestions_spec.rb +79 -0
  89. data/spec/jira/resource/issue_spec.rb +88 -85
  90. data/spec/jira/resource/issuelink_spec.rb +1 -1
  91. data/spec/jira/resource/jira_picker_suggestions_issue_spec.rb +18 -0
  92. data/spec/jira/resource/project_factory_spec.rb +2 -4
  93. data/spec/jira/resource/project_spec.rb +33 -33
  94. data/spec/jira/resource/sprint_spec.rb +90 -0
  95. data/spec/jira/resource/user_factory_spec.rb +6 -8
  96. data/spec/jira/resource/worklog_spec.rb +9 -11
  97. data/spec/mock_responses/board/1.json +33 -0
  98. data/spec/mock_responses/board/1_issues.json +62 -0
  99. data/spec/mock_responses/empty_issues.json +8 -0
  100. data/spec/mock_responses/issue/10002/watchers.json +13 -0
  101. data/spec/mock_responses/issue.json +1 -1
  102. data/spec/mock_responses/sprint/1_issues.json +125 -0
  103. data/spec/spec_helper.rb +8 -9
  104. data/spec/support/clients_helper.rb +4 -4
  105. data/spec/support/shared_examples/integration.rb +60 -77
  106. metadata +115 -55
  107. data/.ruby-version +0 -1
  108. data/README.rdoc +0 -333
  109. /data/spec/mock_responses/{attachment → issue/10002/attachments}/10000.json +0 -0
@@ -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,69 +1,85 @@
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]
27
+
28
+ has_many :attachments, nested_under: 'fields',
29
+ attribute_key: 'attachment'
26
30
 
27
- has_many :comments, :nested_under => ['fields','comment']
31
+ has_many :versions, nested_under: 'fields'
32
+ has_many :fixVersions, class: JIRA::Resource::Version,
33
+ nested_under: 'fields'
28
34
 
29
- has_many :attachments, :nested_under => 'fields',
30
- :attribute_key => 'attachment'
35
+ has_many :worklogs, nested_under: %w[fields worklog]
36
+ has_one :sprint, class: JIRA::Resource::Sprint,
37
+ nested_under: 'fields'
31
38
 
32
- has_many :versions, :nested_under => 'fields'
33
- has_many :fixVersions, :class => JIRA::Resource::Version,
34
- :nested_under => 'fields'
39
+ has_many :closed_sprints, class: JIRA::Resource::Sprint,
40
+ nested_under: 'fields', attribute_key: 'closedSprints'
35
41
 
36
- has_many :worklogs, :nested_under => ['fields','worklog']
42
+ has_many :issuelinks, nested_under: 'fields'
37
43
 
38
- has_many :issuelinks, :nested_under => 'fields'
44
+ has_many :remotelink, class: JIRA::Resource::Remotelink
39
45
 
40
- has_many :remotelink, :class => JIRA::Resource::Remotelink
46
+ has_many :watchers, attribute_key: 'watches',
47
+ nested_under: %w[fields watches]
41
48
 
42
49
  def self.all(client)
43
- url = client.options[:rest_base_path] + "/search?expand=transitions.fields"
44
- response = client.get(url)
45
- json = parse_json(response.body)
46
- json['issues'].map do |issue|
47
- client.Issue.build(issue)
50
+ start_at = 0
51
+ max_results = 1000
52
+ result = []
53
+ loop do
54
+ url = client.options[:rest_base_path] +
55
+ "/search?expand=transitions.fields&maxResults=#{max_results}&startAt=#{start_at}"
56
+ response = client.get(url)
57
+ json = parse_json(response.body)
58
+ json['issues'].map do |issue|
59
+ result.push(client.Issue.build(issue))
60
+ end
61
+ break if json['issues'].empty?
62
+ start_at += json['issues'].size
48
63
  end
64
+ result
49
65
  end
50
66
 
51
- 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 })
52
68
  url = client.options[:rest_base_path] + "/search?jql=#{CGI.escape(jql)}"
53
69
 
54
- 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]
55
71
  url << "&startAt=#{CGI.escape(options[:start_at].to_s)}" if options[:start_at]
56
72
  url << "&maxResults=#{CGI.escape(options[:max_results].to_s)}" if options[:max_results]
57
- url << "&validateQuery=false" if options[:validate_query] === false
73
+ url << '&validateQuery=false' if options[:validate_query] === false
58
74
 
59
75
  if options[:expand]
60
76
  options[:expand] = [options[:expand]] if options[:expand].is_a?(String)
61
- 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(',')}"
62
78
  end
63
79
 
64
80
  response = client.get(url)
65
81
  json = parse_json(response.body)
66
- if options[:max_results] and options[:max_results] == 0
82
+ if options[:max_results] && (options[:max_results] == 0)
67
83
  return json['total']
68
84
  end
69
85
  json['issues'].map do |issue|
@@ -71,6 +87,23 @@ module JIRA
71
87
  end
72
88
  end
73
89
 
90
+ # Fetches the attributes for the specified resource from JIRA unless
91
+ # the resource is already expanded and the optional force reload flag
92
+ # is not set
93
+ def fetch(reload = false, query_params = {})
94
+ return if expanded? && !reload
95
+ response = client.get(url_with_query_params(url, query_params))
96
+ set_attrs_from_response(response)
97
+ if @attrs && @attrs['fields'] && @attrs['fields']['worklog'] && (@attrs['fields']['worklog']['total'] > @attrs['fields']['worklog']['maxResults'])
98
+ worklog_url = client.options[:rest_base_path] + "/#{self.class.endpoint_name}/#{id}/worklog"
99
+ response = client.get(worklog_url)
100
+ unless response.body.nil? || (response.body.length < 2)
101
+ set_attrs({ 'fields' => { 'worklog' => self.class.parse_json(response.body) } }, false)
102
+ end
103
+ end
104
+ @expanded = true
105
+ end
106
+
74
107
  def editmeta
75
108
  editmeta_url = client.options[:rest_base_path] + "/#{self.class.endpoint_name}/#{key}/editmeta"
76
109
 
@@ -79,8 +112,8 @@ module JIRA
79
112
  json['fields']
80
113
  end
81
114
 
82
- def respond_to?(method_name, include_all=false)
83
- 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) }
84
117
  true
85
118
  else
86
119
  super(method_name)
@@ -88,12 +121,12 @@ module JIRA
88
121
  end
89
122
 
90
123
  def method_missing(method_name, *args, &block)
91
- if attrs.keys.include?('fields')
92
- if attrs['fields'].keys.include?(method_name.to_s)
124
+ if attrs.key?('fields')
125
+ if attrs['fields'].key?(method_name.to_s)
93
126
  attrs['fields'][method_name.to_s]
94
127
  else
95
- official_name=client.Field.name_to_id(method_name)
96
- if attrs['fields'].keys.include?(official_name)
128
+ official_name = client.Field.name_to_id(method_name)
129
+ if attrs['fields'].key?(official_name)
97
130
  attrs['fields'][official_name]
98
131
  else
99
132
  super(method_name, *args, &block)
@@ -103,8 +136,6 @@ module JIRA
103
136
  super(method_name, *args, &block)
104
137
  end
105
138
  end
106
-
107
139
  end
108
-
109
140
  end
110
141
  end
@@ -0,0 +1,24 @@
1
+ module JIRA
2
+ module Resource
3
+ class IssuePickerSuggestionsFactory < JIRA::BaseFactory # :nodoc:
4
+ end
5
+
6
+ class IssuePickerSuggestions < JIRA::Base
7
+ has_many :sections, class: JIRA::Resource::IssuePickerSuggestionsIssue
8
+
9
+ def self.all(client, query = '', options = { current_jql: nil, current_issue_key: nil, current_project_id: nil, show_sub_tasks: nil, show_sub_tasks_parent: nil })
10
+ url = client.options[:rest_base_path] + "/issue/picker?query=#{CGI.escape(query)}"
11
+
12
+ url << "&currentJQL=#{CGI.escape(options[:current_jql])}" if options[:current_jql]
13
+ url << "&currentIssueKey=#{CGI.escape(options[:current_issue_key])}" if options[:current_issue_key]
14
+ url << "&currentProjectId=#{CGI.escape(options[:current_project_id])}" if options[:current_project_id]
15
+ url << "&showSubTasks=#{options[:show_sub_tasks]}" if options[:show_sub_tasks]
16
+ url << "&showSubTaskParent=#{options[:show_sub_task_parent]}" if options[:show_sub_task_parent]
17
+
18
+ response = client.get(url)
19
+ json = parse_json(response.body)
20
+ client.IssuePickerSuggestions.build(json)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ module JIRA
2
+ module Resource
3
+ class IssuePickerSuggestionsIssueFactory < JIRA::BaseFactory # :nodoc:
4
+ end
5
+
6
+ class IssuePickerSuggestionsIssue < JIRA::Base
7
+ has_many :issues, class: JIRA::Resource::SuggestedIssue
8
+ end
9
+ end
10
+ 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
@@ -1,6 +1,5 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class RemotelinkFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
@@ -13,9 +12,7 @@ module JIRA
13
12
 
14
13
  def self.all(client, options = {})
15
14
  issue = options[:issue]
16
- unless issue
17
- raise ArgumentError.new("parent issue is required")
18
- end
15
+ raise ArgumentError, 'parent issue is required' unless issue
19
16
 
20
17
  path = "#{issue.self}/#{endpoint_name}"
21
18
  response = client.get(path)
@@ -1,10 +1,8 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class ResolutionFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
7
- class Resolution < JIRA::Base ; end
8
-
6
+ class Resolution < JIRA::Base; end
9
7
  end
10
- end
8
+ end
@@ -1,6 +1,5 @@
1
1
  module JIRA
2
2
  module Resource
3
-
4
3
  class ServerInfoFactory < JIRA::BaseFactory # :nodoc:
5
4
  end
6
5
 
@@ -12,7 +11,7 @@ module JIRA
12
11
  def self.all(client, options = {})
13
12
  response = client.get(collection_path(client))
14
13
  json = parse_json(response.body)
15
- self.new(client, {:attrs => json}.merge(options))
14
+ new(client, { attrs: json }.merge(options))
16
15
  end
17
16
  end
18
17
  end