googleauth 0.5.1 → 0.14.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 (80) hide show
  1. checksums.yaml +5 -5
  2. data/.github/CODEOWNERS +7 -0
  3. data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +5 -4
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +36 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
  6. data/.github/ISSUE_TEMPLATE/support_request.md +7 -0
  7. data/.kokoro/build.bat +16 -0
  8. data/.kokoro/build.sh +4 -0
  9. data/.kokoro/continuous/common.cfg +24 -0
  10. data/.kokoro/continuous/linux.cfg +25 -0
  11. data/.kokoro/continuous/osx.cfg +8 -0
  12. data/.kokoro/continuous/post.cfg +30 -0
  13. data/.kokoro/continuous/windows.cfg +29 -0
  14. data/.kokoro/osx.sh +4 -0
  15. data/.kokoro/presubmit/common.cfg +24 -0
  16. data/.kokoro/presubmit/linux.cfg +24 -0
  17. data/.kokoro/presubmit/osx.cfg +8 -0
  18. data/.kokoro/presubmit/windows.cfg +29 -0
  19. data/.kokoro/release.cfg +94 -0
  20. data/.kokoro/trampoline.bat +10 -0
  21. data/.kokoro/trampoline.sh +4 -0
  22. data/.repo-metadata.json +5 -0
  23. data/.rubocop.yml +19 -1
  24. data/CHANGELOG.md +112 -19
  25. data/CODE_OF_CONDUCT.md +43 -0
  26. data/Gemfile +19 -13
  27. data/{COPYING → LICENSE} +0 -0
  28. data/README.md +58 -18
  29. data/Rakefile +126 -9
  30. data/googleauth.gemspec +28 -25
  31. data/integration/helper.rb +31 -0
  32. data/integration/id_tokens/key_source_test.rb +74 -0
  33. data/lib/googleauth.rb +7 -96
  34. data/lib/googleauth/application_default.rb +81 -0
  35. data/lib/googleauth/client_id.rb +21 -19
  36. data/lib/googleauth/compute_engine.rb +70 -43
  37. data/lib/googleauth/credentials.rb +442 -0
  38. data/lib/googleauth/credentials_loader.rb +117 -43
  39. data/lib/googleauth/default_credentials.rb +93 -0
  40. data/lib/googleauth/iam.rb +11 -11
  41. data/lib/googleauth/id_tokens.rb +233 -0
  42. data/lib/googleauth/id_tokens/errors.rb +71 -0
  43. data/lib/googleauth/id_tokens/key_sources.rb +394 -0
  44. data/lib/googleauth/id_tokens/verifier.rb +144 -0
  45. data/lib/googleauth/json_key_reader.rb +50 -0
  46. data/lib/googleauth/scope_util.rb +12 -12
  47. data/lib/googleauth/service_account.rb +74 -63
  48. data/lib/googleauth/signet.rb +55 -13
  49. data/lib/googleauth/stores/file_token_store.rb +8 -8
  50. data/lib/googleauth/stores/redis_token_store.rb +22 -22
  51. data/lib/googleauth/token_store.rb +6 -6
  52. data/lib/googleauth/user_authorizer.rb +80 -68
  53. data/lib/googleauth/user_refresh.rb +44 -35
  54. data/lib/googleauth/version.rb +1 -1
  55. data/lib/googleauth/web_user_authorizer.rb +77 -68
  56. data/rakelib/devsite_builder.rb +45 -0
  57. data/rakelib/link_checker.rb +64 -0
  58. data/rakelib/repo_metadata.rb +59 -0
  59. data/spec/googleauth/apply_auth_examples.rb +74 -50
  60. data/spec/googleauth/client_id_spec.rb +75 -55
  61. data/spec/googleauth/compute_engine_spec.rb +98 -46
  62. data/spec/googleauth/credentials_spec.rb +478 -0
  63. data/spec/googleauth/get_application_default_spec.rb +149 -111
  64. data/spec/googleauth/iam_spec.rb +25 -25
  65. data/spec/googleauth/scope_util_spec.rb +26 -24
  66. data/spec/googleauth/service_account_spec.rb +269 -144
  67. data/spec/googleauth/signet_spec.rb +101 -30
  68. data/spec/googleauth/stores/file_token_store_spec.rb +12 -13
  69. data/spec/googleauth/stores/redis_token_store_spec.rb +11 -11
  70. data/spec/googleauth/stores/store_examples.rb +16 -16
  71. data/spec/googleauth/user_authorizer_spec.rb +153 -124
  72. data/spec/googleauth/user_refresh_spec.rb +186 -121
  73. data/spec/googleauth/web_user_authorizer_spec.rb +82 -69
  74. data/spec/spec_helper.rb +21 -19
  75. data/test/helper.rb +33 -0
  76. data/test/id_tokens/key_sources_test.rb +240 -0
  77. data/test/id_tokens/verifier_test.rb +269 -0
  78. metadata +87 -34
  79. data/.rubocop_todo.yml +0 -32
  80. data/.travis.yml +0 -37
@@ -27,268 +27,333 @@
27
27
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
28
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
 
30
- spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
31
- $LOAD_PATH.unshift(spec_dir)
30
+ spec_dir = File.expand_path File.join(File.dirname(__FILE__))
31
+ $LOAD_PATH.unshift spec_dir
32
32
  $LOAD_PATH.uniq!
33
33
 
34
- require 'apply_auth_examples'
35
- require 'fakefs/safe'
36
- require 'fileutils'
37
- require 'googleauth/user_refresh'
38
- require 'jwt'
39
- require 'multi_json'
40
- require 'openssl'
41
- require 'spec_helper'
42
- require 'tmpdir'
34
+ require "apply_auth_examples"
35
+ require "fakefs/safe"
36
+ require "fileutils"
37
+ require "googleauth/user_refresh"
38
+ require "jwt"
39
+ require "multi_json"
40
+ require "openssl"
41
+ require "spec_helper"
42
+ require "tmpdir"
43
+ require "os"
43
44
 
44
45
  include Google::Auth::CredentialsLoader
45
46
 
46
47
  describe Google::Auth::UserRefreshCredentials do
47
48
  UserRefreshCredentials = Google::Auth::UserRefreshCredentials
48
49
 
49
- let(:cred_json) do
50
+ let :cred_json do
50
51
  {
51
- client_secret: 'privatekey',
52
- client_id: 'client123',
53
- refresh_token: 'refreshtoken',
54
- type: 'authorized_user'
52
+ client_secret: "privatekey",
53
+ client_id: "client123",
54
+ refresh_token: "refreshtoken",
55
+ type: "authorized_user"
55
56
  }
56
57
  end
57
58
 
58
- before(:example) do
59
- @key = OpenSSL::PKey::RSA.new(2048)
59
+ before :example do
60
+ @key = OpenSSL::PKey::RSA.new 2048
60
61
  @client = UserRefreshCredentials.make_creds(
61
62
  json_key_io: StringIO.new(cred_json_text),
62
- scope: 'https://www.googleapis.com/auth/userinfo.profile'
63
+ scope: "https://www.googleapis.com/auth/userinfo.profile"
63
64
  )
64
65
  end
65
66
 
66
- def make_auth_stubs(opts = {})
67
- access_token = opts[:access_token] || ''
68
- body = MultiJson.dump('access_token' => access_token,
69
- 'token_type' => 'Bearer',
70
- 'expires_in' => 3600)
71
- stub_request(:post, 'https://www.googleapis.com/oauth2/v3/token')
72
- .with(body: hash_including('grant_type' => 'refresh_token'))
73
- .to_return(body: body,
74
- status: 200,
75
- headers: { 'Content-Type' => 'application/json' })
67
+ def make_auth_stubs opts
68
+ access_token = opts[:access_token] || ""
69
+ body = MultiJson.dump("access_token" => access_token,
70
+ "token_type" => "Bearer",
71
+ "expires_in" => 3600)
72
+ stub_request(:post, "https://oauth2.googleapis.com/token")
73
+ .with(body: hash_including("grant_type" => "refresh_token"))
74
+ .to_return(body: body,
75
+ status: 200,
76
+ headers: { "Content-Type" => "application/json" })
76
77
  end
77
78
 
78
- def cred_json_text(missing = nil)
79
- cred_json.delete(missing.to_sym) unless missing.nil?
80
- MultiJson.dump(cred_json)
79
+ def cred_json_text missing = nil
80
+ cred_json.delete missing.to_sym unless missing.nil?
81
+ MultiJson.dump cred_json
81
82
  end
82
83
 
83
- it_behaves_like 'apply/apply! are OK'
84
+ it_behaves_like "apply/apply! are OK"
84
85
 
85
- describe '#from_env' do
86
- before(:example) do
86
+ describe "#from_env" do
87
+ before :example do
87
88
  @var_name = ENV_VAR
88
89
  @credential_vars = [
89
90
  ENV_VAR, CLIENT_ID_VAR, CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR,
90
- ACCOUNT_TYPE_VAR]
91
+ ACCOUNT_TYPE_VAR
92
+ ]
91
93
  @original_env_vals = {}
92
94
  @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
93
- @scope = 'https://www.googleapis.com/auth/userinfo.profile'
95
+ @scope = "https://www.googleapis.com/auth/userinfo.profile"
94
96
  @clz = UserRefreshCredentials
97
+ @project_id = "a_project_id"
95
98
  end
96
99
 
97
- after(:example) do
100
+ after :example do
98
101
  @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
99
102
  end
100
103
 
101
- it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do
102
- ENV.delete(@var_name) unless ENV[@var_name].nil?
104
+ it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset" do
105
+ ENV.delete @var_name unless ENV[@var_name].nil?
103
106
  expect(UserRefreshCredentials.from_env(@scope)).to be_nil
104
107
  end
105
108
 
106
- it 'fails if the GOOGLE_APPLICATION_CREDENTIALS path does not exist' do
107
- ENV.delete(@var_name) unless ENV[@var_name].nil?
109
+ it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is empty" do
110
+ ENV[@var_name] = ""
111
+ expect(UserRefreshCredentials.from_env(@scope)).to be_nil
112
+ end
113
+
114
+ it "fails if the GOOGLE_APPLICATION_CREDENTIALS path does not exist" do
115
+ ENV.delete @var_name unless ENV[@var_name].nil?
108
116
  expect(UserRefreshCredentials.from_env(@scope)).to be_nil
109
117
  Dir.mktmpdir do |dir|
110
- key_path = File.join(dir, 'does-not-exist')
118
+ key_path = File.join dir, "does-not-exist"
111
119
  ENV[@var_name] = key_path
112
- expect { @clz.from_env(@scope) }.to raise_error RuntimeError
120
+ expect { @clz.from_env @scope }.to raise_error RuntimeError
113
121
  end
114
122
  end
115
123
 
116
- it 'fails if the GOOGLE_APPLICATION_CREDENTIALS path file is invalid' do
117
- needed = %w(client_id client_secret refresh_token)
124
+ it "fails if the GOOGLE_APPLICATION_CREDENTIALS path file is invalid" do
125
+ needed = %w[client_id client_secret refresh_token]
118
126
  needed.each do |missing|
119
127
  Dir.mktmpdir do |dir|
120
- key_path = File.join(dir, 'my_cert_file')
121
- FileUtils.mkdir_p(File.dirname(key_path))
122
- File.write(key_path, cred_json_text(missing))
128
+ key_path = File.join dir, "my_cert_file"
129
+ FileUtils.mkdir_p File.dirname(key_path)
130
+ File.write key_path, cred_json_text(missing)
123
131
  ENV[@var_name] = key_path
124
- expect { @clz.from_env(@scope) }.to raise_error RuntimeError
132
+ expect { @clz.from_env @scope }.to raise_error RuntimeError
125
133
  end
126
134
  end
127
135
  end
128
136
 
129
- it 'succeeds when the GOOGLE_APPLICATION_CREDENTIALS file is valid' do
137
+ it "succeeds when the GOOGLE_APPLICATION_CREDENTIALS file is valid" do
130
138
  Dir.mktmpdir do |dir|
131
- key_path = File.join(dir, 'my_cert_file')
132
- FileUtils.mkdir_p(File.dirname(key_path))
133
- File.write(key_path, cred_json_text)
139
+ key_path = File.join dir, "my_cert_file"
140
+ FileUtils.mkdir_p File.dirname(key_path)
141
+ File.write key_path, cred_json_text
134
142
  ENV[@var_name] = key_path
135
143
  expect(@clz.from_env(@scope)).to_not be_nil
136
144
  end
137
145
  end
138
146
 
139
- it 'succeeds when GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and '\
140
- 'GOOGLE_REFRESH_TOKEN env vars are valid' do
147
+ it "succeeds when GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and "\
148
+ "GOOGLE_REFRESH_TOKEN env vars are valid" do
149
+ ENV[ENV_VAR] = nil
141
150
  ENV[CLIENT_ID_VAR] = cred_json[:client_id]
142
151
  ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
143
152
  ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
144
153
  ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
145
- creds = @clz.from_env(@scope)
154
+ creds = @clz.from_env @scope
146
155
  expect(creds).to_not be_nil
147
156
  expect(creds.client_id).to eq(cred_json[:client_id])
148
157
  expect(creds.client_secret).to eq(cred_json[:client_secret])
149
158
  expect(creds.refresh_token).to eq(cred_json[:refresh_token])
150
159
  end
160
+
161
+ it "sets project_id when the PROJECT_ID_VAR env var is set" do
162
+ ENV[ENV_VAR] = nil
163
+ ENV[CLIENT_ID_VAR] = cred_json[:client_id]
164
+ ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
165
+ ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
166
+ ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
167
+ ENV[PROJECT_ID_VAR] = @project_id
168
+ creds = @clz.from_env @scope
169
+ expect(creds.project_id).to eq(@project_id)
170
+ end
151
171
  end
152
172
 
153
- describe '#from_well_known_path' do
154
- before(:example) do
155
- @home = ENV['HOME']
156
- @scope = 'https://www.googleapis.com/auth/userinfo.profile'
173
+ describe "#from_well_known_path" do
174
+ before :example do
175
+ @home = ENV["HOME"]
176
+ @app_data = ENV["APPDATA"]
177
+ @scope = "https://www.googleapis.com/auth/userinfo.profile"
157
178
  @known_path = WELL_KNOWN_PATH
158
179
  @clz = UserRefreshCredentials
159
180
  end
160
181
 
161
- after(:example) do
162
- ENV['HOME'] = @home unless @home == ENV['HOME']
182
+ after :example do
183
+ ENV["HOME"] = @home unless @home == ENV["HOME"]
184
+ ENV["APPDATA"] = @app_data unless @app_data == ENV["APPDATA"]
163
185
  end
164
186
 
165
- it 'is nil if no file exists' do
166
- ENV['HOME'] = File.dirname(__FILE__)
187
+ it "is nil if no file exists" do
188
+ ENV["HOME"] = File.dirname __FILE__
167
189
  expect(UserRefreshCredentials.from_well_known_path(@scope)).to be_nil
168
190
  end
169
191
 
170
- it 'fails if the file is invalid' do
171
- needed = %w(client_id client_secret refresh_token)
192
+ it "fails if the file is invalid" do
193
+ needed = %w[client_id client_secret refresh_token]
172
194
  needed.each do |missing|
173
195
  Dir.mktmpdir do |dir|
174
- key_path = File.join(dir, '.config', @known_path)
175
- FileUtils.mkdir_p(File.dirname(key_path))
176
- File.write(key_path, cred_json_text(missing))
177
- ENV['HOME'] = dir
178
- expect { @clz.from_well_known_path(@scope) }
196
+ key_path = File.join dir, ".config", @known_path
197
+ key_path = File.join dir, @known_path if OS.windows?
198
+ FileUtils.mkdir_p File.dirname(key_path)
199
+ File.write key_path, cred_json_text(missing)
200
+ ENV["HOME"] = dir
201
+ ENV["APPDATA"] = dir
202
+ expect { @clz.from_well_known_path @scope }
179
203
  .to raise_error RuntimeError
180
204
  end
181
205
  end
182
206
  end
183
207
 
184
- it 'successfully loads the file when it is present' do
208
+ it "successfully loads the file when it is present" do
185
209
  Dir.mktmpdir do |dir|
186
- key_path = File.join(dir, '.config', @known_path)
187
- FileUtils.mkdir_p(File.dirname(key_path))
188
- File.write(key_path, cred_json_text)
189
- ENV['HOME'] = dir
210
+ key_path = File.join dir, ".config", @known_path
211
+ key_path = File.join dir, @known_path if OS.windows?
212
+ FileUtils.mkdir_p File.dirname(key_path)
213
+ File.write key_path, cred_json_text
214
+ ENV["HOME"] = dir
215
+ ENV["APPDATA"] = dir
190
216
  expect(@clz.from_well_known_path(@scope)).to_not be_nil
191
217
  end
192
218
  end
219
+
220
+ it "checks gcloud config for project_id if none was provided" do
221
+ Dir.mktmpdir do |dir|
222
+ key_path = File.join dir, ".config", @known_path
223
+ key_path = File.join dir, @known_path if OS.windows?
224
+ FileUtils.mkdir_p File.dirname(key_path)
225
+ File.write key_path, cred_json_text
226
+ ENV["HOME"] = dir
227
+ ENV["APPDATA"] = dir
228
+ ENV[PROJECT_ID_VAR] = nil
229
+ expect(Google::Auth::CredentialsLoader).to receive(:load_gcloud_project_id).with(no_args)
230
+ @clz.from_well_known_path @scope
231
+ end
232
+ end
193
233
  end
194
234
 
195
- describe '#from_system_default_path' do
196
- before(:example) do
197
- @scope = 'https://www.googleapis.com/auth/userinfo.profile'
198
- @path = File.join('/etc/google/auth/', CREDENTIALS_FILE_NAME)
235
+ describe "#from_system_default_path" do
236
+ before :example do
237
+ @scope = "https://www.googleapis.com/auth/userinfo.profile"
238
+ @prefix = OS.windows? ? "/etc/Google/Auth/" : "/etc/google/auth/"
239
+ @path = File.join @prefix, CREDENTIALS_FILE_NAME
240
+ @program_data = ENV["ProgramData"]
199
241
  @clz = UserRefreshCredentials
200
242
  end
201
243
 
202
- it 'is nil if no file exists' do
244
+ after :example do
245
+ ENV["ProgramData"] = @program_data
246
+ end
247
+
248
+ it "is nil if no file exists" do
203
249
  FakeFS do
204
250
  expect(UserRefreshCredentials.from_system_default_path(@scope))
205
251
  .to be_nil
206
252
  end
207
253
  end
208
254
 
209
- it 'fails if the file is invalid' do
210
- needed = %w(client_id client_secret refresh_token)
255
+ it "fails if the file is invalid" do
256
+ needed = %w[client_id client_secret refresh_token]
211
257
  needed.each do |missing|
212
258
  FakeFS do
213
- FileUtils.mkdir_p(File.dirname(@path))
214
- File.write(@path, cred_json_text(missing))
215
- expect { @clz.from_system_default_path(@scope) }
259
+ ENV["ProgramData"] = "/etc"
260
+ FileUtils.mkdir_p File.dirname(@path)
261
+ File.write @path, cred_json_text(missing)
262
+ expect { @clz.from_system_default_path @scope }
216
263
  .to raise_error RuntimeError
217
- File.delete(@path)
264
+ File.delete @path
218
265
  end
219
266
  end
220
267
  end
221
268
 
222
- it 'successfully loads the file when it is present' do
269
+ it "successfully loads the file when it is present" do
223
270
  FakeFS do
224
- FileUtils.mkdir_p(File.dirname(@path))
225
- File.write(@path, cred_json_text)
271
+ ENV["ProgramData"] = "/etc"
272
+ FileUtils.mkdir_p File.dirname(@path)
273
+ File.write @path, cred_json_text
226
274
  expect(@clz.from_system_default_path(@scope)).to_not be_nil
227
- File.delete(@path)
275
+ File.delete @path
228
276
  end
229
277
  end
230
278
  end
231
279
 
232
- shared_examples 'revoked token' do
233
- it 'should nil the refresh token' do
280
+ shared_examples "revoked token" do
281
+ it "should nil the refresh token" do
234
282
  expect(@client.refresh_token).to be_nil
235
283
  end
236
284
 
237
- it 'should nil the access token' do
285
+ it "should nil the access token" do
238
286
  expect(@client.access_token).to be_nil
239
287
  end
240
288
 
241
- it 'should mark the token as expired' do
289
+ it "should mark the token as expired" do
242
290
  expect(@client.expired?).to be_truthy
243
291
  end
244
292
  end
245
293
 
246
- describe 'when revoking a refresh token' do
247
- let(:stub) do
248
- stub_request(:get, 'https://accounts.google.com/o/oauth2/revoke' \
249
- '?token=refreshtoken')
250
- .to_return(status: 200,
251
- headers: { 'Content-Type' => 'application/json' })
294
+ describe "when revoking a refresh token" do
295
+ let :stub do
296
+ stub_request(:post, "https://oauth2.googleapis.com/revoke")
297
+ .with(body: hash_including("token" => "refreshtoken"))
298
+ .to_return(status: 200,
299
+ headers: { "Content-Type" => "application/json" })
252
300
  end
253
301
 
254
- before(:example) do
302
+ before :example do
255
303
  stub
256
304
  @client.revoke!
257
305
  end
258
306
 
259
- it_behaves_like 'revoked token'
307
+ it_behaves_like "revoked token"
260
308
  end
261
309
 
262
- describe 'when revoking an access token' do
263
- let(:stub) do
264
- stub_request(:get, 'https://accounts.google.com/o/oauth2/revoke' \
265
- '?token=accesstoken')
266
- .to_return(status: 200,
267
- headers: { 'Content-Type' => 'application/json' })
310
+ describe "when revoking an access token" do
311
+ let :stub do
312
+ stub_request(:post, "https://oauth2.googleapis.com/revoke")
313
+ .with(body: hash_including("token" => "accesstoken"))
314
+ .to_return(status: 200,
315
+ headers: { "Content-Type" => "application/json" })
268
316
  end
269
317
 
270
- before(:example) do
318
+ before :example do
271
319
  stub
272
320
  @client.refresh_token = nil
273
- @client.access_token = 'accesstoken'
321
+ @client.access_token = "accesstoken"
274
322
  @client.revoke!
275
323
  end
276
324
 
277
- it_behaves_like 'revoked token'
325
+ it_behaves_like "revoked token"
278
326
  end
279
327
 
280
- describe 'when revoking an invalid token' do
281
- let(:stub) do
282
- stub_request(:get, 'https://accounts.google.com/o/oauth2/revoke' \
283
- '?token=refreshtoken')
284
- .to_return(status: 400,
285
- headers: { 'Content-Type' => 'application/json' })
328
+ describe "when revoking an invalid token" do
329
+ let :stub do
330
+ stub_request(:post, "https://oauth2.googleapis.com/revoke")
331
+ .with(body: hash_including("token" => "refreshtoken"))
332
+ .to_return(status: 400,
333
+ headers: { "Content-Type" => "application/json" })
286
334
  end
287
335
 
288
- it 'raises an authorization error' do
336
+ it "raises an authorization error" do
289
337
  stub
290
338
  expect { @client.revoke! }.to raise_error(
291
- Signet::AuthorizationError)
339
+ Signet::AuthorizationError
340
+ )
341
+ end
342
+ end
343
+
344
+ describe "when errors occurred with request" do
345
+ it "should fail with Signet::AuthorizationError if request times out" do
346
+ allow_any_instance_of(Faraday::Connection).to receive(:post)
347
+ .and_raise(Faraday::TimeoutError)
348
+ expect { @client.revoke! }
349
+ .to raise_error Signet::AuthorizationError
350
+ end
351
+
352
+ it "should fail with Signet::AuthorizationError if request fails" do
353
+ allow_any_instance_of(Faraday::Connection).to receive(:post)
354
+ .and_raise(Faraday::ConnectionFailed, nil)
355
+ expect { @client.revoke! }
356
+ .to raise_error Signet::AuthorizationError
292
357
  end
293
358
  end
294
359
  end