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,78 +1,176 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe JIRA::HttpClient do
4
-
5
4
  let(:basic_client) do
6
- options = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::HttpClient::DEFAULT_OPTIONS)
5
+ options = JIRA::Client::DEFAULT_OPTIONS
6
+ .merge(JIRA::HttpClient::DEFAULT_OPTIONS)
7
+ .merge(basic_auth_credentials)
7
8
  JIRA::HttpClient.new(options)
8
9
  end
9
10
 
10
11
  let(:basic_cookie_client) do
11
- options = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::HttpClient::DEFAULT_OPTIONS).merge(:use_cookies => true)
12
+ options = JIRA::Client::DEFAULT_OPTIONS
13
+ .merge(JIRA::HttpClient::DEFAULT_OPTIONS)
14
+ .merge(use_cookies: true)
15
+ .merge(basic_auth_credentials)
16
+ JIRA::HttpClient.new(options)
17
+ end
18
+
19
+ let(:custom_ssl_version_client) do
20
+ options = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::HttpClient::DEFAULT_OPTIONS).merge(ssl_version: :TLSv1_2)
21
+ JIRA::HttpClient.new(options)
22
+ end
23
+
24
+ let(:basic_cookie_client_with_context_path) do
25
+ options = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::HttpClient::DEFAULT_OPTIONS).merge(
26
+ use_cookies: true,
27
+ context_path: '/context'
28
+ )
29
+ JIRA::HttpClient.new(options)
30
+ end
31
+
32
+ let(:basic_cookie_client_with_additional_cookies) do
33
+ options = JIRA::Client::DEFAULT_OPTIONS
34
+ .merge(JIRA::HttpClient::DEFAULT_OPTIONS)
35
+ .merge(
36
+ use_cookies: true,
37
+ additional_cookies: ['sessionToken=abc123', 'internal=true']
38
+ )
39
+ .merge(basic_auth_credentials)
40
+ JIRA::HttpClient.new(options)
41
+ end
42
+
43
+ let(:basic_client_cert_client) do
44
+ options = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::HttpClient::DEFAULT_OPTIONS).merge(
45
+ use_client_cert: true,
46
+ cert: 'public certificate contents',
47
+ key: 'private key contents'
48
+ )
49
+ JIRA::HttpClient.new(options)
50
+ end
51
+
52
+ let(:basic_client_with_no_auth_credentials) do
53
+ options = JIRA::Client::DEFAULT_OPTIONS
54
+ .merge(JIRA::HttpClient::DEFAULT_OPTIONS)
55
+ JIRA::HttpClient.new(options)
56
+ end
57
+
58
+ let(:basic_auth_credentials) do
59
+ { username: 'donaldduck', password: 'supersecret' }
60
+ end
61
+
62
+ let(:proxy_client) do
63
+ options = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::HttpClient::DEFAULT_OPTIONS).merge(
64
+ proxy_address: 'proxyAddress',
65
+ proxy_port: 42,
66
+ proxy_username: 'proxyUsername',
67
+ proxy_password: 'proxyPassword'
68
+ )
12
69
  JIRA::HttpClient.new(options)
13
70
  end
14
71
 
15
72
  let(:response) do
16
- response = double("response")
73
+ response = double('response')
17
74
  allow(response).to receive(:kind_of?).with(Net::HTTPSuccess).and_return(true)
18
75
  response
19
76
  end
20
77
 
21
78
  let(:cookie_response) do
22
- response = double("response")
79
+ response = double('response')
23
80
  allow(response).to receive(:kind_of?).with(Net::HTTPSuccess).and_return(true)
24
81
  response
25
82
  end
26
83
 
27
- it "creates an instance of Net:HTTP for a basic auth client" do
84
+ it 'creates an instance of Net:HTTP for a basic auth client' do
28
85
  expect(basic_client.basic_auth_http_conn.class).to eq(Net::HTTP)
29
86
  end
30
87
 
31
- it "responds to the http methods" do
88
+ it 'makes a correct HTTP request for make_cookie_auth_request' do
89
+ request = double
90
+ basic_auth_http_conn = double
91
+
92
+ headers = { 'Content-Type' => 'application/json' }
93
+ expected_path = '/context/rest/auth/1/session'
94
+ expected_body = '{"username":"","password":""}'
95
+
96
+ allow(basic_cookie_client_with_context_path).to receive(:basic_auth_http_conn).and_return(basic_auth_http_conn)
97
+ expect(basic_auth_http_conn).to receive(:request).with(request).and_return(response)
98
+
99
+ allow(request).to receive(:basic_auth)
100
+ allow(response).to receive(:get_fields).with('set-cookie')
101
+
102
+ expect(request).to receive(:body=).with(expected_body)
103
+ expect(Net::HTTP.const_get(:post.to_s.capitalize)).to receive(:new).with(expected_path, headers).and_return(request)
104
+
105
+ basic_cookie_client_with_context_path.make_cookie_auth_request
106
+ end
107
+
108
+ it 'responds to the http methods' do
32
109
  body = ''
33
- headers = double()
34
- basic_auth_http_conn = double()
35
- request = double()
110
+ headers = double
111
+ basic_auth_http_conn = double
112
+ request = double
36
113
  allow(basic_client).to receive(:basic_auth_http_conn).and_return(basic_auth_http_conn)
37
114
  expect(request).to receive(:basic_auth).with(basic_client.options[:username], basic_client.options[:password]).exactly(5).times.and_return(request)
38
115
  expect(basic_auth_http_conn).to receive(:request).exactly(5).times.with(request).and_return(response)
39
- [:delete, :get, :head].each do |method|
116
+ %i[delete get head].each do |method|
40
117
  expect(Net::HTTP.const_get(method.to_s.capitalize)).to receive(:new).with('/path', headers).and_return(request)
41
118
  expect(basic_client.make_request(method, '/path', nil, headers)).to eq(response)
42
119
  end
43
- [:post, :put].each do |method|
120
+ %i[post put].each do |method|
44
121
  expect(Net::HTTP.const_get(method.to_s.capitalize)).to receive(:new).with('/path', headers).and_return(request)
45
122
  expect(request).to receive(:body=).with(body).and_return(request)
46
123
  expect(basic_client.make_request(method, '/path', body, headers)).to eq(response)
47
124
  end
48
125
  end
49
126
 
50
- it "gets and sets cookies" do
127
+ it 'gets and sets cookies' do
51
128
  body = ''
52
- headers = double()
53
- basic_auth_http_conn = double()
54
- request = double()
129
+ headers = double
130
+ basic_auth_http_conn = double
131
+ request = double
55
132
  allow(basic_cookie_client).to receive(:basic_auth_http_conn).and_return(basic_auth_http_conn)
56
133
  expect(request).to receive(:basic_auth).with(basic_cookie_client.options[:username], basic_cookie_client.options[:password]).exactly(5).times.and_return(request)
57
134
  expect(cookie_response).to receive(:get_fields).with('set-cookie').exactly(5).times
58
135
  expect(basic_auth_http_conn).to receive(:request).exactly(5).times.with(request).and_return(cookie_response)
59
- [:delete, :get, :head].each do |method|
136
+ %i[delete get head].each do |method|
60
137
  expect(Net::HTTP.const_get(method.to_s.capitalize)).to receive(:new).with('/path', headers).and_return(request)
61
138
  expect(basic_cookie_client.make_request(method, '/path', nil, headers)).to eq(cookie_response)
62
139
  end
63
- [:post, :put].each do |method|
140
+ %i[post put].each do |method|
64
141
  expect(Net::HTTP.const_get(method.to_s.capitalize)).to receive(:new).with('/path', headers).and_return(request)
65
142
  expect(request).to receive(:body=).with(body).and_return(request)
66
143
  expect(basic_cookie_client.make_request(method, '/path', body, headers)).to eq(cookie_response)
67
144
  end
68
145
  end
69
146
 
147
+ it 'sets additional cookies when they are provided' do
148
+ client = basic_cookie_client_with_additional_cookies
149
+ body = ''
150
+ headers = double
151
+ basic_auth_http_conn = double
152
+ request = double
153
+ allow(client).to receive(:basic_auth_http_conn).and_return(basic_auth_http_conn)
154
+ expect(request).to receive(:basic_auth).with(client.options[:username], client.options[:password]).exactly(5).times.and_return(request)
155
+ expect(request).to receive(:add_field).with('Cookie', 'sessionToken=abc123; internal=true').exactly(5).times
156
+ expect(cookie_response).to receive(:get_fields).with('set-cookie').exactly(5).times
157
+ expect(basic_auth_http_conn).to receive(:request).exactly(5).times.with(request).and_return(cookie_response)
158
+ %i[delete get head].each do |method|
159
+ expect(Net::HTTP.const_get(method.to_s.capitalize)).to receive(:new).with('/path', headers).and_return(request)
160
+ expect(client.make_request(method, '/path', nil, headers)).to eq(cookie_response)
161
+ end
162
+ %i[post put].each do |method|
163
+ expect(Net::HTTP.const_get(method.to_s.capitalize)).to receive(:new).with('/path', headers).and_return(request)
164
+ expect(request).to receive(:body=).with(body).and_return(request)
165
+ expect(client.make_request(method, '/path', body, headers)).to eq(cookie_response)
166
+ end
167
+ end
70
168
 
71
- it "performs a basic http client request" do
169
+ it 'performs a basic http client request' do
72
170
  body = nil
73
- headers = double()
74
- basic_auth_http_conn = double()
75
- http_request = double()
171
+ headers = double
172
+ basic_auth_http_conn = double
173
+ http_request = double
76
174
  expect(Net::HTTP::Get).to receive(:new).with('/foo', headers).and_return(http_request)
77
175
 
78
176
  expect(basic_auth_http_conn).to receive(:request).with(http_request).and_return(response)
@@ -81,16 +179,42 @@ describe JIRA::HttpClient do
81
179
  basic_client.make_request(:get, '/foo', body, headers)
82
180
  end
83
181
 
84
- it "returns a URI" do
182
+ it 'performs a basic http client request with a full domain' do
183
+ body = nil
184
+ headers = double
185
+ basic_auth_http_conn = double
186
+ http_request = double
187
+ expect(Net::HTTP::Get).to receive(:new).with('/foo', headers).and_return(http_request)
188
+
189
+ expect(basic_auth_http_conn).to receive(:request).with(http_request).and_return(response)
190
+ expect(http_request).to receive(:basic_auth).with(basic_client.options[:username], basic_client.options[:password]).and_return(http_request)
191
+ allow(basic_client).to receive(:basic_auth_http_conn).and_return(basic_auth_http_conn)
192
+ basic_client.make_request(:get, 'http://mydomain.com/foo', body, headers)
193
+ end
194
+
195
+ it 'does not try to use basic auth if the credentials are not set' do
196
+ body = nil
197
+ headers = double
198
+ basic_auth_http_conn = double
199
+ http_request = double
200
+ expect(Net::HTTP::Get).to receive(:new).with('/foo', headers).and_return(http_request)
201
+
202
+ expect(basic_auth_http_conn).to receive(:request).with(http_request).and_return(response)
203
+ expect(http_request).not_to receive(:basic_auth)
204
+ allow(basic_client_with_no_auth_credentials).to receive(:basic_auth_http_conn).and_return(basic_auth_http_conn)
205
+ basic_client_with_no_auth_credentials.make_request(:get, '/foo', body, headers)
206
+ end
207
+
208
+ it 'returns a URI' do
85
209
  uri = URI.parse(basic_client.options[:site])
86
210
  expect(basic_client.uri).to eq(uri)
87
211
  end
88
212
 
89
- it "sets up a http connection with options" do
90
- http_conn = double()
91
- uri = double()
92
- host = double()
93
- port = double()
213
+ it 'sets up a http connection with options' do
214
+ http_conn = double
215
+ uri = double
216
+ host = double
217
+ port = double
94
218
  expect(uri).to receive(:host).and_return(host)
95
219
  expect(uri).to receive(:port).and_return(port)
96
220
  expect(Net::HTTP).to receive(:new).with(host, port).and_return(http_conn)
@@ -100,11 +224,110 @@ describe JIRA::HttpClient do
100
224
  expect(basic_client.http_conn(uri)).to eq(http_conn)
101
225
  end
102
226
 
103
- it "returns a http connection" do
104
- http_conn = double()
105
- uri = double()
227
+ it 'sets the SSL version when one is provided' do
228
+ http_conn = double
229
+ uri = double
230
+ host = double
231
+ port = double
232
+ expect(uri).to receive(:host).and_return(host)
233
+ expect(uri).to receive(:port).and_return(port)
234
+ expect(Net::HTTP).to receive(:new).with(host, port).and_return(http_conn)
235
+ expect(http_conn).to receive(:use_ssl=).with(basic_client.options[:use_ssl]).and_return(http_conn)
236
+ expect(http_conn).to receive(:verify_mode=).with(basic_client.options[:ssl_verify_mode]).and_return(http_conn)
237
+ expect(http_conn).to receive(:ssl_version=).with(custom_ssl_version_client.options[:ssl_version]).and_return(http_conn)
238
+ expect(http_conn).to receive(:read_timeout=).with(basic_client.options[:read_timeout]).and_return(http_conn)
239
+ expect(custom_ssl_version_client.http_conn(uri)).to eq(http_conn)
240
+ end
241
+
242
+ it 'sets up a non-proxied http connection by default' do
243
+ uri = double
244
+ host = double
245
+ port = double
246
+
247
+ expect(uri).to receive(:host).and_return(host)
248
+ expect(uri).to receive(:port).and_return(port)
249
+
250
+ proxy_configuration = basic_client.http_conn(uri).class
251
+ expect(proxy_configuration.proxy_address).to be_nil
252
+ expect(proxy_configuration.proxy_port).to be_nil
253
+ expect(proxy_configuration.proxy_user).to be_nil
254
+ expect(proxy_configuration.proxy_pass).to be_nil
255
+ end
256
+
257
+ it 'sets up a proxied http connection when using proxy options' do
258
+ uri = double
259
+ host = double
260
+ port = double
261
+
262
+ expect(uri).to receive(:host).and_return(host)
263
+ expect(uri).to receive(:port).and_return(port)
264
+
265
+ proxy_configuration = proxy_client.http_conn(uri).class
266
+ expect(proxy_configuration.proxy_address).to eq(proxy_client.options[:proxy_address])
267
+ expect(proxy_configuration.proxy_port).to eq(proxy_client.options[:proxy_port])
268
+ expect(proxy_configuration.proxy_user).to eq(proxy_client.options[:proxy_username])
269
+ expect(proxy_configuration.proxy_pass).to eq(proxy_client.options[:proxy_password])
270
+ end
271
+
272
+ it 'can use client certificates' do
273
+ http_conn = double
274
+ uri = double
275
+ host = double
276
+ port = double
277
+ expect(Net::HTTP).to receive(:new).with(host, port).and_return(http_conn)
278
+ expect(uri).to receive(:host).and_return(host)
279
+ expect(uri).to receive(:port).and_return(port)
280
+ expect(http_conn).to receive(:use_ssl=).with(basic_client.options[:use_ssl])
281
+ expect(http_conn).to receive(:verify_mode=).with(basic_client.options[:ssl_verify_mode])
282
+ expect(http_conn).to receive(:read_timeout=).with(basic_client.options[:read_timeout])
283
+ expect(http_conn).to receive(:cert=).with(basic_client_cert_client.options[:ssl_client_cert])
284
+ expect(http_conn).to receive(:key=).with(basic_client_cert_client.options[:ssl_client_key])
285
+ expect(basic_client_cert_client.http_conn(uri)).to eq(http_conn)
286
+ end
287
+
288
+ it 'can use a certificate authority file' do
289
+ client = JIRA::HttpClient.new(JIRA::Client::DEFAULT_OPTIONS.merge(ca_file: '/opt/custom.ca.pem'))
290
+ expect(client.http_conn(client.uri).ca_file).to eql('/opt/custom.ca.pem')
291
+ end
292
+
293
+ it 'returns a http connection' do
294
+ http_conn = double
295
+ uri = double
106
296
  expect(basic_client).to receive(:uri).and_return(uri)
107
297
  expect(basic_client).to receive(:http_conn).and_return(http_conn)
108
298
  expect(basic_client.basic_auth_http_conn).to eq(http_conn)
109
299
  end
300
+
301
+ describe '#make_multipart_request' do
302
+ subject do
303
+ basic_client.make_multipart_request(path, data, headers)
304
+ end
305
+
306
+ let(:path) { '/foo' }
307
+ let(:data) { {} }
308
+ let(:headers) { { 'X-Atlassian-Token' => 'no-check' } }
309
+ let(:basic_auth_http_conn) { double }
310
+ let(:request) { double('Http Request', path: path) }
311
+ let(:response) { double('response') }
312
+
313
+ before do
314
+ allow(request).to receive(:basic_auth)
315
+ allow(Net::HTTP::Post::Multipart).to receive(:new).with(path, data, headers).and_return(request)
316
+ allow(basic_client).to receive(:basic_auth_http_conn).and_return(basic_auth_http_conn)
317
+ allow(basic_auth_http_conn).to receive(:request).with(request).and_return(response)
318
+ end
319
+
320
+ it 'performs a basic http client request' do
321
+ expect(request).to receive(:basic_auth).with(basic_client.options[:username], basic_client.options[:password]).and_return(request)
322
+
323
+ subject
324
+ end
325
+
326
+ it 'makes a correct HTTP request' do
327
+ expect(basic_auth_http_conn).to receive(:request).with(request).and_return(response)
328
+ expect(response).to receive(:is_a?).with(Net::HTTPOK)
329
+
330
+ subject
331
+ end
332
+ end
110
333
  end
@@ -1,26 +1,24 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe JIRA::HTTPError do
4
-
5
- let(:response) {
6
- response = double("response")
4
+ let(:response) do
5
+ response = double('response')
7
6
  allow(response).to receive(:code).and_return(401)
8
- allow(response).to receive(:message).and_return("A MESSAGE WOO")
7
+ allow(response).to receive(:message).and_return('A MESSAGE WOO')
9
8
  response
10
- }
9
+ end
11
10
 
12
11
  subject { described_class.new(response) }
13
12
 
14
- it "takes the response object as an argument" do
13
+ it 'takes the response object as an argument' do
15
14
  expect(subject.response).to eq(response)
16
15
  end
17
16
 
18
- it "has a code method" do
17
+ it 'has a code method' do
19
18
  expect(subject.code).to eq(response.code)
20
19
  end
21
20
 
22
- it "returns code and class from message" do
21
+ it 'returns code and class from message' do
23
22
  expect(subject.message).to eq(response.message)
24
23
  end
25
-
26
24
  end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe JIRA::JwtClient::JwtUriBuilder do
4
+ subject(:url_builder) do
5
+ JIRA::JwtClient::JwtUriBuilder.new(url, http_method, shared_secret, site, issuer)
6
+ end
7
+
8
+ let(:url) { '/foo' }
9
+ let(:http_method) { :get }
10
+ let(:shared_secret) { 'shared_secret' }
11
+ let(:site) { 'http://localhost:2990' }
12
+ let(:issuer) { nil }
13
+
14
+ describe '#build' do
15
+ subject { url_builder.build }
16
+
17
+ it 'includes the jwt param' do
18
+ expect(subject).to include('?jwt=')
19
+ end
20
+
21
+ context 'when the url already contains params' do
22
+ let(:url) { '/foo?expand=projects.issuetypes.fields' }
23
+
24
+ it 'includes the jwt param' do
25
+ expect(subject).to include('&jwt=')
26
+ end
27
+ end
28
+
29
+ context 'with a complete url' do
30
+ let(:url) { 'http://localhost:2990/rest/api/2/issue/createmeta' }
31
+
32
+ it 'includes the jwt param' do
33
+ expect(subject).to include('?jwt=')
34
+ end
35
+
36
+ it { is_expected.to start_with('/') }
37
+
38
+ it 'contains only one ?' do
39
+ expect(subject.count('?')).to eq(1)
40
+ end
41
+ end
42
+
43
+ context 'with a complete url containing a param' do
44
+ let(:url) do
45
+ 'http://localhost:2990/rest/api/2/issue/createmeta?expand=projects.issuetypes.fields'
46
+ end
47
+
48
+ it 'includes the jwt param' do
49
+ expect(subject).to include('&jwt=')
50
+ end
51
+
52
+ it { is_expected.to start_with('/') }
53
+
54
+ it 'contains only one ?' do
55
+ expect(subject.count('?')).to eq(1)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,43 +1,62 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe JIRA::OauthClient do
4
-
5
4
  let(:oauth_client) do
6
- options = { :consumer_key => 'foo', :consumer_secret => 'bar' }
5
+ options = { consumer_key: 'foo', consumer_secret: 'bar' }
7
6
  options = JIRA::Client::DEFAULT_OPTIONS.merge(options)
8
7
  JIRA::OauthClient.new(options)
9
8
  end
10
9
 
11
10
  let(:response) do
12
- response = double("response")
13
- allow(response).to receive(:kind_of?).with(Net::HTTPSuccess).and_return(true)
11
+ response = double('response')
12
+ allow(response).to receive(:is_a?).with(Net::HTTPSuccess).and_return(true)
14
13
  response
15
14
  end
16
15
 
17
- describe "authenticating with oauth" do
18
- it "prepends the context path to all authorization and rest paths" do
19
- options = [:request_token_path, :authorize_path, :access_token_path]
16
+ describe 'authenticating with oauth' do
17
+ it 'prepends the context path to all authorization and rest paths' do
18
+ options = %i[request_token_path authorize_path access_token_path]
20
19
  defaults = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::OauthClient::DEFAULT_OPTIONS)
21
20
  options.each do |key|
22
21
  expect(oauth_client.options[key]).to eq(defaults[:context_path] + defaults[key])
23
22
  end
24
23
  end
25
24
 
26
- it "creates a Oauth::Consumer on initialize" do
25
+ it 'creates a Oauth::Consumer on initialize' do
27
26
  expect(oauth_client.consumer.class).to eq(OAuth::Consumer)
28
27
  expect(oauth_client.consumer.key).to eq(oauth_client.key)
29
28
  expect(oauth_client.consumer.secret).to eq(oauth_client.secret)
30
29
  end
31
30
 
32
- it "returns an OAuth request_token" do
31
+ it 'returns an OAuth request_token' do
33
32
  # Cannot just check for method delegation as http connection will be attempted
34
33
  request_token = OAuth::RequestToken.new(oauth_client.consumer)
35
34
  allow(oauth_client).to receive(:get_request_token).and_return(request_token)
36
35
  expect(oauth_client.get_request_token).to eq(request_token)
37
36
  end
38
37
 
39
- it "allows setting the request token" do
40
- token = double()
38
+ it 'could pre-process the response body in a block' do
39
+ response = Net::HTTPSuccess.new(1.0, '200', 'OK')
40
+ allow_any_instance_of(OAuth::Consumer).to receive(:request).and_return(response)
41
+ allow(response).to receive(:body).and_return('&oauth_token=token&oauth_token_secret=secret&password=top_secret')
42
+
43
+ result = oauth_client.request_token do |response_body|
44
+ CGI.parse(response_body).each_with_object({}) do |(k, v), h|
45
+ next if k == 'password'
46
+
47
+ h[k.strip.to_sym] = v.first
48
+ end
49
+ end
50
+
51
+ expect(result).to be_an_instance_of(OAuth::RequestToken)
52
+ expect(result.consumer).to eql(oauth_client.consumer)
53
+ expect(result.params[:oauth_token]).to eql('token')
54
+ expect(result.params[:oauth_token_secret]).to eql('secret')
55
+ expect(result.params[:password]).to be_falsey
56
+ end
57
+
58
+ it 'allows setting the request token' do
59
+ token = double
41
60
  expect(OAuth::RequestToken).to receive(:new).with(oauth_client.consumer, 'foo', 'bar').and_return(token)
42
61
 
43
62
  request_token = oauth_client.set_request_token('foo', 'bar')
@@ -46,34 +65,33 @@ describe JIRA::OauthClient do
46
65
  expect(oauth_client.request_token).to eq(token)
47
66
  end
48
67
 
49
- it "allows setting the consumer key" do
68
+ it 'allows setting the consumer key' do
50
69
  expect(oauth_client.key).to eq('foo')
51
70
  end
52
71
 
53
- it "allows setting the consumer secret" do
72
+ it 'allows setting the consumer secret' do
54
73
  expect(oauth_client.secret).to eq('bar')
55
74
  end
56
75
 
57
- describe "the access token" do
58
-
59
- it "initializes" do
76
+ describe 'the access token' do
77
+ it 'initializes' do
60
78
  request_token = OAuth::RequestToken.new(oauth_client.consumer)
61
79
  allow(oauth_client).to receive(:get_request_token).and_return(request_token)
62
- mock_access_token = double()
63
- expect(request_token).to receive(:get_access_token).with(:oauth_verifier => 'abc123').and_return(mock_access_token)
64
- oauth_client.init_access_token(:oauth_verifier => 'abc123')
80
+ mock_access_token = double
81
+ expect(request_token).to receive(:get_access_token).with({ oauth_verifier: 'abc123' }).and_return(mock_access_token)
82
+ oauth_client.init_access_token(oauth_verifier: 'abc123')
65
83
  expect(oauth_client.access_token).to eq(mock_access_token)
66
84
  end
67
85
 
68
- it "raises an exception when accessing without initialisation" do
69
- expect {
86
+ it 'raises an exception when accessing without initialisation' do
87
+ expect do
70
88
  oauth_client.access_token
71
- }.to raise_exception(JIRA::OauthClient::UninitializedAccessTokenError,
72
- "init_access_token must be called before using the client")
89
+ end.to raise_exception(JIRA::OauthClient::UninitializedAccessTokenError,
90
+ 'init_access_token must be called before using the client')
73
91
  end
74
92
 
75
- it "allows setting the access token" do
76
- token = double()
93
+ it 'allows setting the access token' do
94
+ token = double
77
95
  expect(OAuth::AccessToken).to receive(:new).with(oauth_client.consumer, 'foo', 'bar').and_return(token)
78
96
 
79
97
  access_token = oauth_client.set_access_token('foo', 'bar')
@@ -83,29 +101,82 @@ describe JIRA::OauthClient do
83
101
  end
84
102
  end
85
103
 
86
- describe "http" do
87
- it "responds to the http methods" do
88
- headers = double()
89
- mock_access_token = double()
90
- allow(oauth_client).to receive(:access_token).and_return(mock_access_token)
91
- [:delete, :get, :head].each do |method|
92
- expect(mock_access_token).to receive(method).with('/path', headers).and_return(response)
104
+ describe 'http' do
105
+ let(:headers) { double }
106
+ let(:access_token) { double }
107
+ let(:body) { nil }
108
+
109
+ before do
110
+ allow(oauth_client).to receive(:access_token).and_return(access_token)
111
+ end
112
+
113
+ it 'responds to the http methods' do
114
+ %i[delete get head].each do |method|
115
+ expect(access_token).to receive(method).with('/path', headers).and_return(response)
93
116
  oauth_client.make_request(method, '/path', '', headers)
94
117
  end
95
- [:post, :put].each do |method|
96
- expect(mock_access_token).to receive(method).with('/path', '', headers).and_return(response)
118
+ %i[post put].each do |method|
119
+ expect(access_token).to receive(method).with('/path', '', headers).and_return(response)
97
120
  oauth_client.make_request(method, '/path', '', headers)
98
121
  end
99
122
  end
100
123
 
101
- it "performs a request" do
102
- body = nil
103
- headers = double()
104
- access_token = double()
124
+ it 'performs a request' do
105
125
  expect(access_token).to receive(:send).with(:get, '/foo', headers).and_return(response)
106
- allow(oauth_client).to receive(:access_token).and_return(access_token)
126
+
127
+
107
128
  oauth_client.request(:get, '/foo', body, headers)
108
129
  end
130
+
131
+ context 'for a multipart request' do
132
+ subject { oauth_client.make_multipart_request('/path', data, headers) }
133
+
134
+ let(:data) { {} }
135
+ let(:headers) { {} }
136
+
137
+ it 'signs the access_token and performs the request' do
138
+ expect(access_token).to receive(:sign!).with(an_instance_of(Net::HTTP::Post::Multipart))
139
+ expect(oauth_client.consumer).to receive_message_chain(:http, :request).with(an_instance_of(Net::HTTP::Post::Multipart))
140
+
141
+ subject
142
+ end
143
+ end
144
+ end
145
+
146
+ describe 'auth type is oauth_2legged' do
147
+ let(:oauth__2legged_client) do
148
+ options = { consumer_key: 'foo', consumer_secret: 'bar', auth_type: :oauth_2legged }
149
+ options = JIRA::Client::DEFAULT_OPTIONS.merge(options)
150
+ JIRA::OauthClient.new(options)
151
+ end
152
+
153
+ it 'responds to the http methods adding oauth_token parameter' do
154
+ headers = double
155
+ mock_access_token = double
156
+ allow(oauth__2legged_client).to receive(:access_token).and_return(mock_access_token)
157
+ %i[delete get head].each do |method|
158
+ expect(mock_access_token).to receive(method).with('/path?oauth_token=', headers).and_return(response)
159
+ oauth__2legged_client.make_request(method, '/path', '', headers)
160
+ end
161
+ %i[post put].each do |method|
162
+ expect(mock_access_token).to receive(method).with('/path?oauth_token=', '', headers).and_return(response)
163
+ oauth__2legged_client.make_request(method, '/path', '', headers)
164
+ end
165
+ end
166
+
167
+ it 'responds to the http methods adding oauth_token parameter to any existing parameters' do
168
+ headers = double
169
+ mock_access_token = double
170
+ allow(oauth__2legged_client).to receive(:access_token).and_return(mock_access_token)
171
+ %i[delete get head].each do |method|
172
+ expect(mock_access_token).to receive(method).with('/path?any_param=toto&oauth_token=', headers).and_return(response)
173
+ oauth__2legged_client.make_request(method, '/path?any_param=toto', '', headers)
174
+ end
175
+ %i[post put].each do |method|
176
+ expect(mock_access_token).to receive(method).with('/path?any_param=toto&oauth_token=', '', headers).and_return(response)
177
+ oauth__2legged_client.make_request(method, '/path?any_param=toto', '', headers)
178
+ end
179
+ end
109
180
  end
110
181
  end
111
182
  end