jira-ruby 3.0.0.beta2 → 3.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/CI.yml +1 -0
- data/.github/workflows/rubocop.yml +1 -1
- data/.rubocop.yml +4 -1
- data/README.md +0 -1
- data/jira-ruby.gemspec +1 -0
- data/lib/jira/base_factory.rb +1 -1
- data/lib/jira/resource/issue.rb +55 -13
- data/lib/jira/resource/project.rb +1 -1
- data/lib/jira/resource/sprint.rb +2 -2
- data/lib/jira/version.rb +1 -1
- data/spec/integration/issue_spec.rb +3 -4
- data/spec/integration/project_spec.rb +1 -1
- data/spec/integration/rapidview_spec.rb +2 -2
- data/spec/jira/client_spec.rb +9 -9
- data/spec/jira/resource/agile_spec.rb +2 -2
- data/spec/jira/resource/filter_spec.rb +3 -2
- data/spec/jira/resource/issue_spec.rb +119 -63
- data/spec/jira/resource/project_spec.rb +2 -2
- data/spec/jira/resource/sprint_spec.rb +3 -3
- data/spec/mock_responses/board/1_issues.json +2 -1
- data/spec/mock_responses/issue.json +1 -0
- data/spec/mock_responses/rapidview/SAMPLEPROJECT.issues.full.json +2 -1
- data/spec/mock_responses/rapidview/SAMPLEPROJECT.issues.json +2 -1
- data/spec/support/shared_examples/integration.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8d81df9752f33a1c48332b6793d3b6596359b77b1a79575b57382553c1e04400
|
|
4
|
+
data.tar.gz: 5d6d16a50ccd3293b893068c303405a67450006197bd1d5aec85d75a9d3179e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e4dc469b98fac2378bf647cd33e433a33ddc17ddf83d2e6fe835d21eda2239c6e3899fe9a838ebb4b1130356fa011302dd7f463ce9f4a0f660d4f66c5258e547
|
|
7
|
+
data.tar.gz: 2a09541af9b0028a16338dd13d31014e1e919e730e86ff370150536f1a2e4a8911532283dea8f7d57571010fffa5c2986097fda8d4da7034b35a3afbc806fcfa
|
data/.github/workflows/CI.yml
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -62,9 +62,12 @@ Naming/AccessorMethodName:
|
|
|
62
62
|
Naming/HeredocDelimiterNaming:
|
|
63
63
|
Enabled: false
|
|
64
64
|
|
|
65
|
-
Naming/
|
|
65
|
+
Naming/PredicatePrefix:
|
|
66
66
|
Enabled: false
|
|
67
67
|
|
|
68
|
+
Naming/PredicateMethod:
|
|
69
|
+
AllowBangMethods: true
|
|
70
|
+
|
|
68
71
|
Naming/VariableNumber:
|
|
69
72
|
Enabled: false
|
|
70
73
|
|
data/README.md
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# JIRA API Gem
|
|
2
2
|
|
|
3
|
-
[](https://codeclimate.com/github/sumoheavy/jira-ruby)
|
|
4
3
|
[](https://github.com/sumoheavy/jira-ruby/actions/workflows/CI.yml)
|
|
5
4
|
|
|
6
5
|
This gem provides access to the Atlassian JIRA REST API.
|
data/jira-ruby.gemspec
CHANGED
data/lib/jira/base_factory.rb
CHANGED
|
@@ -38,7 +38,7 @@ module JIRA
|
|
|
38
38
|
# The principle purpose of this class is to delegate methods to the corresponding
|
|
39
39
|
# non-factory class and automatically prepend the client argument to the argument
|
|
40
40
|
# list.
|
|
41
|
-
delegate_to_target_class :all, :find, :collection_path, :singular_path, :jql, :get_backlog_issues,
|
|
41
|
+
delegate_to_target_class :all, :find, :collection_path, :singular_path, :jql, :jql_paged, :get_backlog_issues,
|
|
42
42
|
:get_board_issues, :get_sprints, :get_sprint_issues, :get_projects, :get_projects_full
|
|
43
43
|
|
|
44
44
|
# This method needs special handling as it has a default argument value
|
data/lib/jira/resource/issue.rb
CHANGED
|
@@ -67,7 +67,7 @@ module JIRA
|
|
|
67
67
|
result = []
|
|
68
68
|
loop do
|
|
69
69
|
url = client.options[:rest_base_path] +
|
|
70
|
-
"/search?expand=transitions.fields&maxResults=#{max_results}&startAt=#{start_at}"
|
|
70
|
+
"/search/jql?expand=transitions.fields&maxResults=#{max_results}&startAt=#{start_at}"
|
|
71
71
|
response = client.get(url)
|
|
72
72
|
json = parse_json(response.body)
|
|
73
73
|
json['issues'].map do |issue|
|
|
@@ -80,30 +80,72 @@ module JIRA
|
|
|
80
80
|
result
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
# Get issues using JQL query.
|
|
84
|
+
# @param client [JIRA::Client]
|
|
85
|
+
# @param jql [String] the JQL query string to search with
|
|
86
|
+
# @param options [Hash] Jira API options for the search
|
|
87
|
+
# @return [Array<JIRA::Resource::Issue>] or [Integer] total count if max_results is 0
|
|
88
|
+
def self.jql(client, jql, options = { fields: nil, max_results: nil, expand: nil, reconcile_issues: nil })
|
|
89
|
+
issues = []
|
|
90
|
+
total = nil
|
|
91
|
+
next_page_token = nil
|
|
92
|
+
is_last = false
|
|
93
|
+
|
|
94
|
+
until is_last
|
|
95
|
+
result = jql_paged(client, jql, options.merge(next_page_token:))
|
|
96
|
+
|
|
97
|
+
issues.concat(result[:issues])
|
|
98
|
+
total = result[:total]
|
|
99
|
+
next_page_token = result[:next_page_token]
|
|
100
|
+
is_last = next_page_token.nil?
|
|
101
|
+
end
|
|
102
|
+
options[:max_results]&.zero? ? total : issues
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Get paged issues using JQL query.
|
|
106
|
+
# @param jql [String] the JQL query string to search with
|
|
107
|
+
# @param options [Hash] Jira API options for the search, including next_page_token
|
|
108
|
+
# @return [Hash] with format { issues: [JIRA::Resource::Issue], next_page_token: [String], total: [Integer] }
|
|
109
|
+
def self.jql_paged(client, jql, options = { fields: nil, max_results: nil, expand: nil, reconcile_issues: nil, next_page_token: nil })
|
|
110
|
+
url = jql_url(client, jql, options)
|
|
111
|
+
next_page_token = options[:next_page_token]
|
|
112
|
+
max_results = options[:max_results]
|
|
113
|
+
|
|
114
|
+
issues = []
|
|
115
|
+
|
|
116
|
+
page_url = url.dup
|
|
117
|
+
page_url << "&nextPageToken=#{next_page_token}" if next_page_token
|
|
118
|
+
|
|
119
|
+
response = client.get(page_url)
|
|
120
|
+
json = parse_json(response.body)
|
|
121
|
+
total = json['total']
|
|
122
|
+
|
|
123
|
+
unless max_results&.zero?
|
|
124
|
+
next_page_token = json['nextPageToken']
|
|
125
|
+
json['issues'].map do |issue|
|
|
126
|
+
issues << client.Issue.build(issue)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
{ issues:, next_page_token:, total: }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def self.jql_url(client, jql, options)
|
|
134
|
+
url = client.options[:rest_base_path] + "/search/jql?jql=#{CGI.escape(jql)}"
|
|
85
135
|
|
|
86
136
|
if options[:fields]
|
|
87
137
|
url << "&fields=#{options[:fields].map do |value|
|
|
88
138
|
CGI.escape(client.Field.name_to_id(value))
|
|
89
139
|
end.join(',')}"
|
|
90
140
|
end
|
|
91
|
-
url << "&startAt=#{CGI.escape(options[:start_at].to_s)}" if options[:start_at]
|
|
92
141
|
url << "&maxResults=#{CGI.escape(options[:max_results].to_s)}" if options[:max_results]
|
|
93
|
-
url <<
|
|
142
|
+
url << "&reconcileIssues=#{CGI.escape(options[:reconcile_issues].to_s)}" if options[:reconcile_issues]
|
|
94
143
|
|
|
95
144
|
if options[:expand]
|
|
96
145
|
options[:expand] = [options[:expand]] if options[:expand].is_a?(String)
|
|
97
146
|
url << "&expand=#{options[:expand].to_a.map { |value| CGI.escape(value.to_s) }.join(',')}"
|
|
98
147
|
end
|
|
99
|
-
|
|
100
|
-
response = client.get(url)
|
|
101
|
-
json = parse_json(response.body)
|
|
102
|
-
return json['total'] if options[:max_results]&.zero?
|
|
103
|
-
|
|
104
|
-
json['issues'].map do |issue|
|
|
105
|
-
client.Issue.build(issue)
|
|
106
|
-
end
|
|
148
|
+
url
|
|
107
149
|
end
|
|
108
150
|
|
|
109
151
|
# Fetches the attributes for the specified resource from JIRA unless
|
|
@@ -17,7 +17,7 @@ module JIRA
|
|
|
17
17
|
|
|
18
18
|
# Returns all the issues for this project
|
|
19
19
|
def issues(options = {})
|
|
20
|
-
search_url = "#{client.options[:rest_base_path]}/search"
|
|
20
|
+
search_url = "#{client.options[:rest_base_path]}/search/jql"
|
|
21
21
|
query_params = { jql: "project=\"#{key}\"" }
|
|
22
22
|
query_params.update Base.query_params_for_search(options)
|
|
23
23
|
response = client.get(url_with_query_params(search_url, query_params))
|
data/lib/jira/resource/sprint.rb
CHANGED
|
@@ -20,14 +20,14 @@ module JIRA
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def add_issue(issue)
|
|
23
|
-
add_issues([issue])
|
|
23
|
+
add_issues([issue]).first
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def add_issues(issues)
|
|
27
27
|
issue_ids = issues.map(&:id)
|
|
28
28
|
request_body = { issues: issue_ids }.to_json
|
|
29
29
|
client.post("#{agile_path}/issue", request_body)
|
|
30
|
-
|
|
30
|
+
issues
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def start_date
|
data/lib/jira/version.rb
CHANGED
|
@@ -45,10 +45,10 @@ describe JIRA::Resource::Issue do
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
before do
|
|
48
|
-
stub_request(:get, "#{site_url}/jira/rest/api/2/search?expand=transitions.fields&maxResults=1000&startAt=0")
|
|
48
|
+
stub_request(:get, "#{site_url}/jira/rest/api/2/search/jql?expand=transitions.fields&maxResults=1000&startAt=0")
|
|
49
49
|
.to_return(status: 200, body: get_mock_response('issue.json'))
|
|
50
50
|
|
|
51
|
-
stub_request(:get, "#{site_url}/jira/rest/api/2/search?expand=transitions.fields&maxResults=1000&startAt=11")
|
|
51
|
+
stub_request(:get, "#{site_url}/jira/rest/api/2/search/jql?expand=transitions.fields&maxResults=1000&startAt=11")
|
|
52
52
|
.to_return(status: 200, body: get_mock_response('empty_issues.json'))
|
|
53
53
|
end
|
|
54
54
|
|
|
@@ -78,10 +78,9 @@ describe JIRA::Resource::Issue do
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
describe 'GET jql issues' do # JIRA::Resource::Issue.jql uses the search endpoint
|
|
81
|
-
jql_query_string = "PROJECT = 'SAMPLEPROJECT'"
|
|
82
81
|
let(:client) { client }
|
|
83
82
|
let(:site_url) { site_url }
|
|
84
|
-
let(:jql_query_string) {
|
|
83
|
+
let(:jql_query_string) { "PROJECT = 'SAMPLEPROJECT'" }
|
|
85
84
|
|
|
86
85
|
let(:expected_attributes) do
|
|
87
86
|
{
|
|
@@ -23,7 +23,7 @@ describe JIRA::Resource::Project do
|
|
|
23
23
|
|
|
24
24
|
describe 'issues' do
|
|
25
25
|
it 'returns all the issues' do
|
|
26
|
-
stub_request(:get, "#{site_url}/jira/rest/api/2/search?jql=project=\"SAMPLEPROJECT\"")
|
|
26
|
+
stub_request(:get, "#{site_url}/jira/rest/api/2/search/jql?jql=project=\"SAMPLEPROJECT\"")
|
|
27
27
|
.to_return(status: 200, body: get_mock_response('project/SAMPLEPROJECT.issues.json'))
|
|
28
28
|
subject = client.Project.build('key' => key)
|
|
29
29
|
issues = subject.issues
|
|
@@ -46,7 +46,7 @@ describe JIRA::Resource::RapidView do
|
|
|
46
46
|
|
|
47
47
|
stub_request(
|
|
48
48
|
:get,
|
|
49
|
-
"#{site_url}/jira/rest/api/2/search?jql=id IN(10001, 10000)"
|
|
49
|
+
"#{site_url}/jira/rest/api/2/search/jql?jql=id IN(10001, 10000)"
|
|
50
50
|
).to_return(
|
|
51
51
|
status: 200,
|
|
52
52
|
body: get_mock_response('rapidview/SAMPLEPROJECT.issues.full.json')
|
|
@@ -54,7 +54,7 @@ describe JIRA::Resource::RapidView do
|
|
|
54
54
|
|
|
55
55
|
stub_request(
|
|
56
56
|
:get,
|
|
57
|
-
"#{site_url}/jira/rest/api/2/search?jql=id IN(10000, 10001) AND sprint IS NOT EMPTY"
|
|
57
|
+
"#{site_url}/jira/rest/api/2/search/jql?jql=id IN(10000, 10001) AND sprint IS NOT EMPTY"
|
|
58
58
|
).to_return(
|
|
59
59
|
status: 200,
|
|
60
60
|
body: get_mock_response('rapidview/SAMPLEPROJECT.issues.full.json')
|
data/spec/jira/client_spec.rb
CHANGED
|
@@ -99,7 +99,7 @@ RSpec.shared_examples 'HttpClient tests' do
|
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
RSpec.shared_examples 'OAuth Common Tests' do
|
|
102
|
-
|
|
102
|
+
it_behaves_like 'Client Common Tests'
|
|
103
103
|
|
|
104
104
|
specify { expect(subject.request_client).to be_a JIRA::OauthClient }
|
|
105
105
|
|
|
@@ -162,8 +162,8 @@ describe JIRA::Client do
|
|
|
162
162
|
.to_return(status: 401, headers: {})
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
it_behaves_like 'Client Common Tests'
|
|
166
|
+
it_behaves_like 'HttpClient tests'
|
|
167
167
|
|
|
168
168
|
specify { expect(subject.request_client).to be_a JIRA::HttpClient }
|
|
169
169
|
|
|
@@ -214,8 +214,8 @@ describe JIRA::Client do
|
|
|
214
214
|
.to_return(status: 200, body: '[]', headers: {})
|
|
215
215
|
end
|
|
216
216
|
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
it_behaves_like 'Client Common Tests'
|
|
218
|
+
it_behaves_like 'HttpClient tests'
|
|
219
219
|
|
|
220
220
|
specify { expect(subject.request_client).to be_a JIRA::HttpClient }
|
|
221
221
|
|
|
@@ -251,8 +251,8 @@ describe JIRA::Client do
|
|
|
251
251
|
.to_return(status: 200, body: '[]', headers: {})
|
|
252
252
|
end
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
|
|
254
|
+
it_behaves_like 'Client Common Tests'
|
|
255
|
+
it_behaves_like 'HttpClient tests'
|
|
256
256
|
|
|
257
257
|
specify { expect(subject.request_client).to be_a JIRA::JwtClient }
|
|
258
258
|
|
|
@@ -286,13 +286,13 @@ describe JIRA::Client do
|
|
|
286
286
|
context 'with oauth' do
|
|
287
287
|
subject { described_class.new(consumer_key: 'foo', consumer_secret: 'bar') }
|
|
288
288
|
|
|
289
|
-
|
|
289
|
+
it_behaves_like 'OAuth Common Tests'
|
|
290
290
|
end
|
|
291
291
|
|
|
292
292
|
context 'with oauth_2legged' do
|
|
293
293
|
subject { described_class.new(consumer_key: 'foo', consumer_secret: 'bar', auth_type: :oauth_2legged) }
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
it_behaves_like 'OAuth Common Tests'
|
|
296
296
|
end
|
|
297
297
|
|
|
298
298
|
context 'with unknown options' do
|
|
@@ -31,7 +31,7 @@ describe JIRA::Resource::Agile do
|
|
|
31
31
|
expect(client).to receive(:get).with('/jira/rest/agile/1.0/board/1/issue?').and_return(response)
|
|
32
32
|
expect(response).to receive(:body).and_return(get_mock_response('board/1_issues.json'))
|
|
33
33
|
|
|
34
|
-
expect(client).to receive(:get).with('/jira/rest/api/2/search?jql=id+IN%2810546%2C+10547%2C+10556%2C+10557%2C+10558%2C+10559%2C+10600%2C+10601%2C+10604%29').and_return(response)
|
|
34
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/search/jql?jql=id+IN%2810546%2C+10547%2C+10556%2C+10557%2C+10558%2C+10559%2C+10600%2C+10601%2C+10604%29').and_return(response)
|
|
35
35
|
expect(response).to receive(:body).and_return(get_mock_response('board/1_issues.json'))
|
|
36
36
|
|
|
37
37
|
issues = described_class.get_board_issues(client, 1)
|
|
@@ -48,7 +48,7 @@ describe JIRA::Resource::Agile do
|
|
|
48
48
|
expect(client).to receive(:get).with('/jira/rest/agile/1.0/board/1/issue?startAt=50').and_return(response)
|
|
49
49
|
expect(response).to receive(:body).and_return(get_mock_response('board/1_issues.json'))
|
|
50
50
|
|
|
51
|
-
expect(client).to receive(:get).with('/jira/rest/api/2/search?jql=id+IN%2810546%2C+10547%2C+10556%2C+10557%2C+10558%2C+10559%2C+10600%2C+10601%2C+10604%29').and_return(response)
|
|
51
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/search/jql?jql=id+IN%2810546%2C+10547%2C+10556%2C+10557%2C+10558%2C+10559%2C+10600%2C+10601%2C+10604%29').and_return(response)
|
|
52
52
|
expect(response).to receive(:body).and_return(get_mock_response('board/1_issues.json'))
|
|
53
53
|
|
|
54
54
|
issues = described_class.get_board_issues(client, 1, startAt: 50)
|
|
@@ -28,7 +28,7 @@ describe JIRA::Resource::Filter do
|
|
|
28
28
|
owner: jira_user,
|
|
29
29
|
jql: '"Git Repository" ~ jira-ruby AND status = Resolved',
|
|
30
30
|
viewUrl: 'https://localhost/secure/IssueNavigator.jspa?mode=hide&requestId=42',
|
|
31
|
-
searchUrl: 'https://localhost/rest/api/2/search?jql=%22Git+Repository%22+~+jira-ruby+AND+status+%3D+Resolved',
|
|
31
|
+
searchUrl: 'https://localhost/rest/api/2/search/jql?jql=%22Git+Repository%22+~+jira-ruby+AND+status+%3D+Resolved',
|
|
32
32
|
favourite: false,
|
|
33
33
|
sharePermissions: [
|
|
34
34
|
{
|
|
@@ -69,6 +69,7 @@ describe JIRA::Resource::Filter do
|
|
|
69
69
|
startAt: 0,
|
|
70
70
|
maxResults: 50,
|
|
71
71
|
total: 2,
|
|
72
|
+
isLast: true,
|
|
72
73
|
issues: [jql_issue]
|
|
73
74
|
}
|
|
74
75
|
end
|
|
@@ -86,7 +87,7 @@ describe JIRA::Resource::Filter do
|
|
|
86
87
|
expect(filter).to be_present
|
|
87
88
|
allow(client).to receive(:options).and_return(rest_base_path: 'localhost')
|
|
88
89
|
expect(client).to receive(:get)
|
|
89
|
-
.with("localhost/search?jql=#{CGI.escape(filter.jql)}")
|
|
90
|
+
.with("localhost/search/jql?jql=#{CGI.escape(filter.jql)}")
|
|
90
91
|
.and_return(issue_jql_response)
|
|
91
92
|
issues = filter.issues
|
|
92
93
|
expect(issues).to be_an(Array)
|
|
@@ -42,10 +42,10 @@ describe JIRA::Resource::Issue do
|
|
|
42
42
|
issue = double
|
|
43
43
|
|
|
44
44
|
allow(response).to receive(:body).and_return('{"issues":[{"id":"1","summary":"Bugs Everywhere"}]}')
|
|
45
|
-
expect(client).to receive(:get).with('/jira/rest/api/2/search?expand=transitions.fields&maxResults=1000&startAt=0')
|
|
45
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/search/jql?expand=transitions.fields&maxResults=1000&startAt=0')
|
|
46
46
|
.and_return(response)
|
|
47
47
|
allow(empty_response).to receive(:body).and_return('{"issues":[]}')
|
|
48
|
-
expect(client).to receive(:get).with('/jira/rest/api/2/search?expand=transitions.fields&maxResults=1000&startAt=1')
|
|
48
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/search/jql?expand=transitions.fields&maxResults=1000&startAt=1')
|
|
49
49
|
.and_return(empty_response)
|
|
50
50
|
|
|
51
51
|
expect(client).to receive(:Issue).and_return(issue)
|
|
@@ -70,85 +70,141 @@ describe JIRA::Resource::Issue do
|
|
|
70
70
|
expect(issue_from_id.attrs).to eq(issue_from_key.attrs)
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
issue = double
|
|
73
|
+
describe '.jql' do
|
|
74
|
+
subject { described_class.jql(client, 'foo bar', args) }
|
|
76
75
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
expect(issue).to receive(:build).with(%w[key foo]).and_return('')
|
|
76
|
+
let(:args) { {} }
|
|
77
|
+
let(:issue) { double }
|
|
78
|
+
let(:response) { double }
|
|
79
|
+
let(:response_string) { '{"issues": {"key":"foo"}, "isLast": true}' }
|
|
82
80
|
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
before do
|
|
82
|
+
allow(response).to receive(:body).and_return(response_string)
|
|
83
|
+
allow(client).to receive(:Issue).and_return(issue)
|
|
84
|
+
allow(issue).to receive(:build).with(%w[key foo]).and_return('')
|
|
85
|
+
end
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
it 'searches an issue with a jql query string' do
|
|
88
|
+
expect(client).to receive(:get).with('/jira/rest/api/2/search/jql?jql=foo+bar')
|
|
89
|
+
.and_return(response)
|
|
90
|
+
expect(described_class.jql(client, 'foo bar')).to eq([''])
|
|
91
|
+
end
|
|
89
92
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
expect(client).to receive(:Issue).and_return(issue)
|
|
95
|
-
expect(issue).to receive(:build).with(%w[key foo]).and_return('')
|
|
93
|
+
it 'passes thorugh the reconcileIssues parameter' do
|
|
94
|
+
expect(client).to receive(:get)
|
|
95
|
+
.with('/jira/rest/api/2/search/jql?jql=foo+bar&reconcileIssues=true')
|
|
96
|
+
.and_return(response)
|
|
96
97
|
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
expect(described_class.jql(client, 'foo bar', reconcile_issues: true)).to eq([''])
|
|
99
|
+
end
|
|
99
100
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
it 'searches an issue with a jql query string and fields' do
|
|
102
|
+
expect(client).to receive(:get)
|
|
103
|
+
.with('/jira/rest/api/2/search/jql?jql=foo+bar&fields=foo,bar')
|
|
104
|
+
.and_return(response)
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
.with('/jira/rest/api/2/search?jql=foo+bar&startAt=1&maxResults=3')
|
|
107
|
-
.and_return(response)
|
|
108
|
-
expect(client).to receive(:Issue).and_return(issue)
|
|
109
|
-
expect(issue).to receive(:build).with(%w[key foo]).and_return('')
|
|
106
|
+
expect(described_class.jql(client, 'foo bar', fields: %w[foo bar])).to eq([''])
|
|
107
|
+
end
|
|
110
108
|
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
context 'when maxResults is provided' do
|
|
110
|
+
let(:args) { { max_results: } }
|
|
113
111
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
double
|
|
112
|
+
context 'with non-zero' do
|
|
113
|
+
let(:max_results) { 3 }
|
|
117
114
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
115
|
+
it 'searches an issue with a jql query string and maxResults' do
|
|
116
|
+
expect(client).to receive(:get)
|
|
117
|
+
.with('/jira/rest/api/2/search/jql?jql=foo+bar&maxResults=3')
|
|
118
|
+
.and_return(response)
|
|
122
119
|
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
expect(subject).to eq([''])
|
|
121
|
+
end
|
|
122
|
+
end
|
|
125
123
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
124
|
+
context 'with zero' do
|
|
125
|
+
let(:response_string) { '{"total": 1, "issues": []}' }
|
|
126
|
+
let(:max_results) { 0 }
|
|
129
127
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
expect(client).to receive(:Issue).and_return(issue)
|
|
135
|
-
expect(issue).to receive(:build).with(%w[key foo]).and_return('')
|
|
128
|
+
it 'searches an issue with a jql query string and should return the count of tickets' do
|
|
129
|
+
expect(client).to receive(:get)
|
|
130
|
+
.with('/jira/rest/api/2/search/jql?jql=foo+bar&maxResults=0')
|
|
131
|
+
.and_return(response)
|
|
136
132
|
|
|
137
|
-
|
|
133
|
+
expect(subject).to eq(1)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it 'searches an issue with a jql query string and string expand' do
|
|
139
|
+
expect(client).to receive(:get)
|
|
140
|
+
.with('/jira/rest/api/2/search/jql?jql=foo+bar&expand=transitions')
|
|
141
|
+
.and_return(response)
|
|
142
|
+
|
|
143
|
+
expect(described_class.jql(client, 'foo bar', expand: 'transitions')).to eq([''])
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'searches an issue with a jql query string and array expand' do
|
|
147
|
+
expect(client).to receive(:get)
|
|
148
|
+
.with('/jira/rest/api/2/search/jql?jql=foo+bar&expand=transitions')
|
|
149
|
+
.and_return(response)
|
|
150
|
+
|
|
151
|
+
expect(described_class.jql(client, 'foo bar', expand: %w[transitions])).to eq([''])
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
context 'when pagination is required' do
|
|
155
|
+
let(:response_string) { '{"issues": [{"key":"foo"}], "isLast": false, "nextPageToken": "abc"}' }
|
|
156
|
+
let(:second_response_string) { '{"issues": [{"key":"bar"}], "isLast": true}' }
|
|
157
|
+
|
|
158
|
+
before do
|
|
159
|
+
allow(issue).to receive(:build).with({ 'key' => 'foo' }).and_return('1')
|
|
160
|
+
allow(issue).to receive(:build).with({ 'key' => 'bar' }).and_return('2')
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it 'makes multiple requests' do
|
|
164
|
+
expect(client).to receive(:get)
|
|
165
|
+
.with('/jira/rest/api/2/search/jql?jql=foo+bar')
|
|
166
|
+
.and_return(response)
|
|
167
|
+
expect(client).to receive(:get)
|
|
168
|
+
.with('/jira/rest/api/2/search/jql?jql=foo+bar&nextPageToken=abc')
|
|
169
|
+
.and_return(double(body: second_response_string))
|
|
170
|
+
|
|
171
|
+
expect(subject).to eq(%w[1 2])
|
|
172
|
+
end
|
|
173
|
+
end
|
|
138
174
|
end
|
|
139
175
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
176
|
+
describe '.jql_paged' do
|
|
177
|
+
let(:issue) { double }
|
|
178
|
+
let(:response) { double }
|
|
143
179
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
.
|
|
147
|
-
.and_return(
|
|
148
|
-
|
|
149
|
-
|
|
180
|
+
before do
|
|
181
|
+
allow(response).to receive(:body).and_return(response_string)
|
|
182
|
+
allow(client).to receive(:Issue).and_return(issue)
|
|
183
|
+
allow(issue).to receive(:build).with({ 'key' => 'foo' }).and_return('1')
|
|
184
|
+
allow(issue).to receive(:build).with({ 'key' => 'bar' }).and_return('2')
|
|
185
|
+
allow(issue).to receive(:build).with({ 'key' => 'baz' }).and_return('3')
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
context 'without next_page_token (first page)' do
|
|
189
|
+
subject { described_class.jql_paged(client, 'foo bar', page_size: 2) }
|
|
190
|
+
|
|
191
|
+
before { expect(client).to receive(:get).with('/jira/rest/api/2/search/jql?jql=foo+bar').and_return(response) }
|
|
150
192
|
|
|
151
|
-
|
|
193
|
+
let(:response) { double }
|
|
194
|
+
let(:response_string) { '{"issues": [{"key":"foo"},{"key":"bar"}], "isLast": false, "nextPageToken": "abc"}' }
|
|
195
|
+
|
|
196
|
+
it { is_expected.to eq(issues: %w[1 2], next_page_token: 'abc', total: nil) }
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context 'with next_page_token' do
|
|
200
|
+
subject { described_class.jql_paged(client, 'foo bar', page_size: 2, next_page_token: 'abc') }
|
|
201
|
+
|
|
202
|
+
let(:response_string) { '{"issues": [{"key":"baz"}], "isLast": true}' }
|
|
203
|
+
|
|
204
|
+
before { expect(client).to receive(:get).with('/jira/rest/api/2/search/jql?jql=foo+bar&nextPageToken=abc').and_return(double(body: response_string)) }
|
|
205
|
+
|
|
206
|
+
it { is_expected.to eq(issues: %w[3], next_page_token: nil, total: nil) }
|
|
207
|
+
end
|
|
152
208
|
end
|
|
153
209
|
|
|
154
210
|
it 'returns meta data available for editing an issue' do
|
|
@@ -42,7 +42,7 @@ describe JIRA::Resource::Project do
|
|
|
42
42
|
issue_factory = double('issue factory')
|
|
43
43
|
|
|
44
44
|
expect(client).to receive(:get)
|
|
45
|
-
.with('/jira/rest/api/2/search?jql=project%3D%22test%22')
|
|
45
|
+
.with('/jira/rest/api/2/search/jql?jql=project%3D%22test%22')
|
|
46
46
|
.and_return(response)
|
|
47
47
|
expect(client).to receive(:Issue).and_return(issue_factory)
|
|
48
48
|
expect(issue_factory).to receive(:build)
|
|
@@ -58,7 +58,7 @@ describe JIRA::Resource::Project do
|
|
|
58
58
|
issue_factory = double('issue factory')
|
|
59
59
|
|
|
60
60
|
expect(client).to receive(:get)
|
|
61
|
-
.with('/jira/rest/api/2/search?jql=project%3D%22test%22&expand=changelog&startAt=1&maxResults=100')
|
|
61
|
+
.with('/jira/rest/api/2/search/jql?jql=project%3D%22test%22&expand=changelog&startAt=1&maxResults=100')
|
|
62
62
|
.and_return(response)
|
|
63
63
|
expect(client).to receive(:Issue).and_return(issue_factory)
|
|
64
64
|
expect(issue_factory).to receive(:build)
|
|
@@ -127,12 +127,12 @@ describe JIRA::Resource::Sprint do
|
|
|
127
127
|
{ issues: [issue.id] }
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
-
describe '#
|
|
130
|
+
describe '#add_issue' do
|
|
131
131
|
context 'when an issue is passed' do
|
|
132
132
|
it 'posts with the issue id' do
|
|
133
133
|
expect(client).to receive(:post).with(post_issue_path, post_issue_input.to_json)
|
|
134
134
|
|
|
135
|
-
sprint.add_issue(issue)
|
|
135
|
+
expect(sprint.add_issue(issue)).to eq(issue)
|
|
136
136
|
end
|
|
137
137
|
end
|
|
138
138
|
end
|
|
@@ -160,7 +160,7 @@ describe JIRA::Resource::Sprint do
|
|
|
160
160
|
it 'posts with the issue id' do
|
|
161
161
|
expect(client).to receive(:post).with(post_issue_path, post_issue_input.to_json)
|
|
162
162
|
|
|
163
|
-
sprint.add_issues(issues)
|
|
163
|
+
expect(sprint.add_issues(issues)).to eq(issues)
|
|
164
164
|
end
|
|
165
165
|
end
|
|
166
166
|
end
|
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
},
|
|
102
102
|
"canManageSprints": true,
|
|
103
103
|
"maxIssuesExceeded": false,
|
|
104
|
+
"isLast": true,
|
|
104
105
|
"queryResultLimit": 2147483647,
|
|
105
106
|
"versionData": {
|
|
106
107
|
"versionsPerProject": {
|
|
@@ -108,4 +109,4 @@
|
|
|
108
109
|
},
|
|
109
110
|
"canCreateVersion": true
|
|
110
111
|
}
|
|
111
|
-
}
|
|
112
|
+
}
|
|
@@ -76,7 +76,7 @@ shared_examples 'a resource with JQL inputs and a collection GET endpoint' do
|
|
|
76
76
|
it 'gets the collection' do
|
|
77
77
|
stub_request(
|
|
78
78
|
:get,
|
|
79
|
-
"#{site_url}#{client.options[:rest_base_path]}/search?jql=#{CGI.escape(jql_query_string)}"
|
|
79
|
+
"#{site_url}#{client.options[:rest_base_path]}/search/jql?jql=#{CGI.escape(jql_query_string)}"
|
|
80
80
|
).to_return(status: 200, body: get_mock_response('issue.json'))
|
|
81
81
|
|
|
82
82
|
collection = build_receiver.jql(jql_query_string)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jira-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- SUMO Heavy Industries
|
|
8
8
|
- test IO
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-02-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -38,6 +38,20 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: cgi
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
56
|
name: multipart-post
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|