googleauth 0.5.1 → 0.14.0

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