google-api-client 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/CHANGELOG.md +14 -0
- data/Gemfile +0 -36
- data/README.md +12 -1
- data/Rakefile +1 -8
- data/google-api-client.gemspec +40 -0
- data/lib/google/api_client.rb +98 -30
- data/lib/google/api_client/auth/compute_service_account.rb +1 -1
- data/lib/google/api_client/auth/file_storage.rb +19 -44
- data/lib/google/api_client/auth/installed_app.rb +11 -7
- data/lib/google/api_client/auth/storage.rb +101 -0
- data/lib/google/api_client/auth/storages/file_store.rb +58 -0
- data/lib/google/api_client/auth/storages/redis_store.rb +54 -0
- data/lib/google/api_client/batch.rb +13 -11
- data/lib/google/api_client/charset.rb +33 -0
- data/lib/google/api_client/client_secrets.rb +9 -6
- data/lib/google/api_client/discovery/api.rb +3 -3
- data/lib/google/api_client/discovery/resource.rb +3 -3
- data/lib/google/api_client/discovery/schema.rb +3 -5
- data/lib/google/api_client/errors.rb +5 -0
- data/lib/google/api_client/railtie.rb +2 -1
- data/lib/google/api_client/request.rb +1 -2
- data/lib/google/api_client/result.rb +4 -2
- data/lib/google/api_client/service.rb +2 -2
- data/lib/google/api_client/service/batch.rb +7 -0
- data/lib/google/api_client/service/stub_generator.rb +4 -2
- data/lib/google/api_client/service_account.rb +3 -0
- data/lib/google/api_client/version.rb +8 -13
- data/spec/google/api_client/auth/storage_spec.rb +122 -0
- data/spec/google/api_client/auth/storages/file_store_spec.rb +40 -0
- data/spec/google/api_client/auth/storages/redis_store_spec.rb +70 -0
- data/spec/google/api_client/batch_spec.rb +29 -30
- data/spec/google/api_client/client_secrets_spec.rb +53 -0
- data/spec/google/api_client/discovery_spec.rb +101 -91
- data/spec/google/api_client/gzip_spec.rb +21 -9
- data/spec/google/api_client/media_spec.rb +31 -32
- data/spec/google/api_client/request_spec.rb +3 -4
- data/spec/google/api_client/result_spec.rb +51 -47
- data/spec/google/api_client/service_account_spec.rb +40 -35
- data/spec/google/api_client/service_spec.rb +144 -112
- data/spec/google/api_client/simple_file_store_spec.rb +30 -34
- data/spec/google/api_client_spec.rb +139 -40
- data/spec/spec_helper.rb +9 -1
- metadata +111 -88
- data/CONTRIBUTING.md +0 -32
- data/lib/cacerts.pem +0 -2183
- data/lib/google/inflection.rb +0 -28
- data/spec/fixtures/files/privatekey.p12 +0 -0
- data/spec/fixtures/files/sample.txt +0 -33
- data/spec/fixtures/files/secret.pem +0 -19
- data/tasks/gem.rake +0 -97
- data/tasks/git.rake +0 -45
- data/tasks/metrics.rake +0 -22
- data/tasks/spec.rake +0 -57
- data/tasks/wiki.rake +0 -82
- data/tasks/yard.rake +0 -29
@@ -18,14 +18,10 @@ require 'spec_helper'
|
|
18
18
|
|
19
19
|
require 'google/api_client/service/simple_file_store'
|
20
20
|
|
21
|
-
describe Google::APIClient::Service::SimpleFileStore do
|
21
|
+
RSpec.describe Google::APIClient::Service::SimpleFileStore do
|
22
22
|
|
23
23
|
FILE_NAME = 'test.cache'
|
24
24
|
|
25
|
-
before(:all) do
|
26
|
-
File.delete(FILE_NAME) if File.exists?(FILE_NAME)
|
27
|
-
end
|
28
|
-
|
29
25
|
describe 'with no cache file' do
|
30
26
|
before(:each) do
|
31
27
|
File.delete(FILE_NAME) if File.exists?(FILE_NAME)
|
@@ -33,35 +29,35 @@ describe Google::APIClient::Service::SimpleFileStore do
|
|
33
29
|
end
|
34
30
|
|
35
31
|
it 'should return nil when asked if a key exists' do
|
36
|
-
@cache.exist?('invalid').
|
37
|
-
File.exists?(FILE_NAME).
|
32
|
+
expect(@cache.exist?('invalid')).to be_nil
|
33
|
+
expect(File.exists?(FILE_NAME)).to be_falsey
|
38
34
|
end
|
39
35
|
|
40
36
|
it 'should return nil when asked to read a key' do
|
41
|
-
@cache.read('invalid').
|
42
|
-
File.exists?(FILE_NAME).
|
37
|
+
expect(@cache.read('invalid')).to be_nil
|
38
|
+
expect(File.exists?(FILE_NAME)).to be_falsey
|
43
39
|
end
|
44
40
|
|
45
41
|
it 'should return nil when asked to fetch a key' do
|
46
|
-
@cache.fetch('invalid').
|
47
|
-
File.exists?(FILE_NAME).
|
42
|
+
expect(@cache.fetch('invalid')).to be_nil
|
43
|
+
expect(File.exists?(FILE_NAME)).to be_falsey
|
48
44
|
end
|
49
45
|
|
50
46
|
it 'should create a cache file when asked to fetch a key with a default' do
|
51
|
-
@cache.fetch('new_key') do
|
47
|
+
expect(@cache.fetch('new_key') do
|
52
48
|
'value'
|
53
|
-
end.
|
54
|
-
File.exists?(FILE_NAME).
|
49
|
+
end).to eq('value')
|
50
|
+
expect(File.exists?(FILE_NAME)).to be_truthy
|
55
51
|
end
|
56
52
|
|
57
53
|
it 'should create a cache file when asked to write a key' do
|
58
54
|
@cache.write('new_key', 'value')
|
59
|
-
File.exists?(FILE_NAME).
|
55
|
+
expect(File.exists?(FILE_NAME)).to be_truthy
|
60
56
|
end
|
61
57
|
|
62
58
|
it 'should return nil when asked to delete a key' do
|
63
|
-
@cache.delete('invalid').
|
64
|
-
File.exists?(FILE_NAME).
|
59
|
+
expect(@cache.delete('invalid')).to be_nil
|
60
|
+
expect(File.exists?(FILE_NAME)).to be_falsey
|
65
61
|
end
|
66
62
|
end
|
67
63
|
|
@@ -73,61 +69,61 @@ describe Google::APIClient::Service::SimpleFileStore do
|
|
73
69
|
end
|
74
70
|
|
75
71
|
it 'should return true when asked if an existing key exists' do
|
76
|
-
@cache.exist?('existing_key').
|
72
|
+
expect(@cache.exist?('existing_key')).to be_truthy
|
77
73
|
end
|
78
74
|
|
79
75
|
it 'should return false when asked if a nonexistent key exists' do
|
80
|
-
@cache.exist?('invalid').
|
76
|
+
expect(@cache.exist?('invalid')).to be_falsey
|
81
77
|
end
|
82
78
|
|
83
79
|
it 'should return the value for an existing key when asked to read it' do
|
84
|
-
@cache.read('existing_key').
|
80
|
+
expect(@cache.read('existing_key')).to eq('existing_value')
|
85
81
|
end
|
86
82
|
|
87
83
|
it 'should return nil for a nonexistent key when asked to read it' do
|
88
|
-
@cache.read('invalid').
|
84
|
+
expect(@cache.read('invalid')).to be_nil
|
89
85
|
end
|
90
86
|
|
91
87
|
it 'should return the value for an existing key when asked to read it' do
|
92
|
-
@cache.read('existing_key').
|
88
|
+
expect(@cache.read('existing_key')).to eq('existing_value')
|
93
89
|
end
|
94
90
|
|
95
91
|
it 'should return nil for a nonexistent key when asked to fetch it' do
|
96
|
-
@cache.fetch('invalid').
|
92
|
+
expect(@cache.fetch('invalid')).to be_nil
|
97
93
|
end
|
98
94
|
|
99
95
|
it 'should return and save the default value for a nonexistent key when asked to fetch it with a default' do
|
100
|
-
@cache.fetch('new_key') do
|
96
|
+
expect(@cache.fetch('new_key') do
|
101
97
|
'value'
|
102
|
-
end.
|
103
|
-
@cache.read('new_key').
|
98
|
+
end).to eq('value')
|
99
|
+
expect(@cache.read('new_key')).to eq('value')
|
104
100
|
end
|
105
101
|
|
106
102
|
it 'should remove an existing value and return true when asked to delete it' do
|
107
|
-
@cache.delete('existing_key').
|
108
|
-
@cache.read('existing_key').
|
103
|
+
expect(@cache.delete('existing_key')).to be_truthy
|
104
|
+
expect(@cache.read('existing_key')).to be_nil
|
109
105
|
end
|
110
106
|
|
111
107
|
it 'should return false when asked to delete a nonexistent key' do
|
112
|
-
@cache.delete('invalid').
|
108
|
+
expect(@cache.delete('invalid')).to be_falsey
|
113
109
|
end
|
114
110
|
|
115
111
|
it 'should convert keys to strings when storing them' do
|
116
112
|
@cache.write(:symbol_key, 'value')
|
117
|
-
@cache.read('symbol_key').
|
113
|
+
expect(@cache.read('symbol_key')).to eq('value')
|
118
114
|
end
|
119
115
|
|
120
116
|
it 'should convert keys to strings when reading them' do
|
121
|
-
@cache.read(:existing_key).
|
117
|
+
expect(@cache.read(:existing_key)).to eq('existing_value')
|
122
118
|
end
|
123
119
|
|
124
120
|
it 'should convert keys to strings when fetching them' do
|
125
|
-
@cache.fetch(:existing_key).
|
121
|
+
expect(@cache.fetch(:existing_key)).to eq('existing_value')
|
126
122
|
end
|
127
123
|
|
128
124
|
it 'should convert keys to strings when deleting them' do
|
129
|
-
@cache.delete(:existing_key).
|
130
|
-
@cache.read('existing_key').
|
125
|
+
expect(@cache.delete(:existing_key)).to be_truthy
|
126
|
+
expect(@cache.read('existing_key')).to be_nil
|
131
127
|
end
|
132
128
|
end
|
133
129
|
|
@@ -17,26 +17,25 @@ require 'spec_helper'
|
|
17
17
|
require 'faraday'
|
18
18
|
require 'signet/oauth_1/client'
|
19
19
|
require 'google/api_client'
|
20
|
-
require 'google/api_client/version'
|
21
20
|
|
22
21
|
shared_examples_for 'configurable user agent' do
|
23
22
|
include ConnectionHelpers
|
24
|
-
|
23
|
+
|
25
24
|
it 'should allow the user agent to be modified' do
|
26
25
|
client.user_agent = 'Custom User Agent/1.2.3'
|
27
|
-
client.user_agent.
|
26
|
+
expect(client.user_agent).to eq('Custom User Agent/1.2.3')
|
28
27
|
end
|
29
28
|
|
30
29
|
it 'should allow the user agent to be set to nil' do
|
31
30
|
client.user_agent = nil
|
32
|
-
client.user_agent.
|
31
|
+
expect(client.user_agent).to eq(nil)
|
33
32
|
end
|
34
33
|
|
35
34
|
it 'should not allow the user agent to be used with bogus values' do
|
36
|
-
(lambda do
|
35
|
+
expect(lambda do
|
37
36
|
client.user_agent = 42
|
38
37
|
client.execute(:uri=>'https://www.google.com/')
|
39
|
-
end).
|
38
|
+
end).to raise_error(TypeError)
|
40
39
|
end
|
41
40
|
|
42
41
|
it 'should transmit a User-Agent header when sending requests' do
|
@@ -45,8 +44,8 @@ shared_examples_for 'configurable user agent' do
|
|
45
44
|
conn = stub_connection do |stub|
|
46
45
|
stub.get('/') do |env|
|
47
46
|
headers = env[:request_headers]
|
48
|
-
headers.
|
49
|
-
headers['User-Agent'].
|
47
|
+
expect(headers).to have_key('User-Agent')
|
48
|
+
expect(headers['User-Agent']).to eq(client.user_agent)
|
50
49
|
[200, {}, ['']]
|
51
50
|
end
|
52
51
|
end
|
@@ -55,17 +54,22 @@ shared_examples_for 'configurable user agent' do
|
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
58
|
-
describe Google::APIClient do
|
57
|
+
RSpec.describe Google::APIClient do
|
59
58
|
include ConnectionHelpers
|
60
59
|
|
61
60
|
let(:client) { Google::APIClient.new(:application_name => 'API Client Tests') }
|
62
61
|
|
62
|
+
it "should pass the faraday options provided on initialization to FaraDay configuration block" do
|
63
|
+
client = Google::APIClient.new(faraday_option: {timeout: 999})
|
64
|
+
expect(client.connection.options.timeout).to be == 999
|
65
|
+
end
|
66
|
+
|
63
67
|
it 'should make its version number available' do
|
64
|
-
Google::APIClient::VERSION::STRING.
|
68
|
+
expect(Google::APIClient::VERSION::STRING).to be_instance_of(String)
|
65
69
|
end
|
66
70
|
|
67
71
|
it 'should default to OAuth 2' do
|
68
|
-
Signet::OAuth2::Client.
|
72
|
+
expect(Signet::OAuth2::Client).to be === client.authorization
|
69
73
|
end
|
70
74
|
|
71
75
|
describe 'configure for no authentication' do
|
@@ -74,7 +78,7 @@ describe Google::APIClient do
|
|
74
78
|
end
|
75
79
|
it_should_behave_like 'configurable user agent'
|
76
80
|
end
|
77
|
-
|
81
|
+
|
78
82
|
describe 'configured for OAuth 1' do
|
79
83
|
before do
|
80
84
|
client.authorization = :oauth_1
|
@@ -83,15 +87,17 @@ describe Google::APIClient do
|
|
83
87
|
end
|
84
88
|
|
85
89
|
it 'should use the default OAuth1 client configuration' do
|
86
|
-
client.authorization.temporary_credential_uri.to_s.
|
90
|
+
expect(client.authorization.temporary_credential_uri.to_s).to eq(
|
87
91
|
'https://www.google.com/accounts/OAuthGetRequestToken'
|
88
|
-
|
92
|
+
)
|
93
|
+
expect(client.authorization.authorization_uri.to_s).to include(
|
89
94
|
'https://www.google.com/accounts/OAuthAuthorizeToken'
|
90
95
|
)
|
91
|
-
client.authorization.token_credential_uri.to_s.
|
96
|
+
expect(client.authorization.token_credential_uri.to_s).to eq(
|
92
97
|
'https://www.google.com/accounts/OAuthGetAccessToken'
|
93
|
-
|
94
|
-
client.authorization.
|
98
|
+
)
|
99
|
+
expect(client.authorization.client_credential_key).to eq('anonymous')
|
100
|
+
expect(client.authorization.client_credential_secret).to eq('anonymous')
|
95
101
|
end
|
96
102
|
|
97
103
|
it_should_behave_like 'configurable user agent'
|
@@ -106,14 +112,14 @@ describe Google::APIClient do
|
|
106
112
|
# TODO
|
107
113
|
it_should_behave_like 'configurable user agent'
|
108
114
|
end
|
109
|
-
|
115
|
+
|
110
116
|
describe 'when executing requests' do
|
111
117
|
before do
|
112
118
|
@prediction = client.discovered_api('prediction', 'v1.2')
|
113
119
|
client.authorization = :oauth_2
|
114
120
|
@connection = stub_connection do |stub|
|
115
121
|
stub.post('/prediction/v1.2/training?data=12345') do |env|
|
116
|
-
env[:request_headers]['Authorization'].
|
122
|
+
expect(env[:request_headers]['Authorization']).to eq('Bearer 12345')
|
117
123
|
[200, {}, '{}']
|
118
124
|
end
|
119
125
|
end
|
@@ -122,10 +128,10 @@ describe Google::APIClient do
|
|
122
128
|
after do
|
123
129
|
@connection.verify
|
124
130
|
end
|
125
|
-
|
131
|
+
|
126
132
|
it 'should use default authorization' do
|
127
133
|
client.authorization.access_token = "12345"
|
128
|
-
client.execute(
|
134
|
+
client.execute(
|
129
135
|
:api_method => @prediction.training.insert,
|
130
136
|
:parameters => {'data' => '12345'},
|
131
137
|
:connection => @connection
|
@@ -135,14 +141,14 @@ describe Google::APIClient do
|
|
135
141
|
it 'should use request scoped authorization when provided' do
|
136
142
|
client.authorization.access_token = "abcdef"
|
137
143
|
new_auth = Signet::OAuth2::Client.new(:access_token => '12345')
|
138
|
-
client.execute(
|
144
|
+
client.execute(
|
139
145
|
:api_method => @prediction.training.insert,
|
140
146
|
:parameters => {'data' => '12345'},
|
141
147
|
:authorization => new_auth,
|
142
148
|
:connection => @connection
|
143
149
|
)
|
144
150
|
end
|
145
|
-
|
151
|
+
|
146
152
|
it 'should accept options with batch/request style execute' do
|
147
153
|
client.authorization.access_token = "abcdef"
|
148
154
|
new_auth = Signet::OAuth2::Client.new(:access_token => '12345')
|
@@ -156,19 +162,19 @@ describe Google::APIClient do
|
|
156
162
|
:connection => @connection
|
157
163
|
)
|
158
164
|
end
|
159
|
-
|
160
|
-
|
165
|
+
|
166
|
+
|
161
167
|
it 'should accept options in array style execute' do
|
162
168
|
client.authorization.access_token = "abcdef"
|
163
169
|
new_auth = Signet::OAuth2::Client.new(:access_token => '12345')
|
164
|
-
client.execute(
|
170
|
+
client.execute(
|
165
171
|
@prediction.training.insert, {'data' => '12345'}, '', {},
|
166
|
-
{ :authorization => new_auth, :connection => @connection }
|
172
|
+
{ :authorization => new_auth, :connection => @connection }
|
167
173
|
)
|
168
174
|
end
|
169
|
-
end
|
175
|
+
end
|
170
176
|
|
171
|
-
describe 'when
|
177
|
+
describe 'when retries enabled' do
|
172
178
|
before do
|
173
179
|
client.retries = 2
|
174
180
|
end
|
@@ -176,7 +182,7 @@ describe Google::APIClient do
|
|
176
182
|
after do
|
177
183
|
@connection.verify
|
178
184
|
end
|
179
|
-
|
185
|
+
|
180
186
|
it 'should follow redirects' do
|
181
187
|
client.authorization = nil
|
182
188
|
@connection = stub_connection do |stub|
|
@@ -189,12 +195,12 @@ describe Google::APIClient do
|
|
189
195
|
end
|
190
196
|
|
191
197
|
client.execute(
|
192
|
-
:uri => 'https://www.
|
198
|
+
:uri => 'https://www.google.com/foo',
|
193
199
|
:connection => @connection
|
194
200
|
)
|
195
201
|
end
|
196
202
|
|
197
|
-
it 'should refresh tokens on 401
|
203
|
+
it 'should refresh tokens on 401 errors' do
|
198
204
|
client.authorization.access_token = '12345'
|
199
205
|
expect(client.authorization).to receive(:fetch_access_token!)
|
200
206
|
|
@@ -208,11 +214,45 @@ describe Google::APIClient do
|
|
208
214
|
end
|
209
215
|
|
210
216
|
client.execute(
|
211
|
-
:uri => 'https://www.
|
217
|
+
:uri => 'https://www.google.com/foo',
|
218
|
+
:connection => @connection
|
219
|
+
)
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
it 'should not attempt multiple token refreshes' do
|
224
|
+
client.authorization.access_token = '12345'
|
225
|
+
expect(client.authorization).to receive(:fetch_access_token!).once
|
226
|
+
|
227
|
+
@connection = stub_connection do |stub|
|
228
|
+
stub.get('/foo') do |env|
|
229
|
+
[401, {}, '{}']
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
client.execute(
|
234
|
+
:uri => 'https://www.google.com/foo',
|
212
235
|
:connection => @connection
|
213
236
|
)
|
214
237
|
end
|
215
238
|
|
239
|
+
it 'should not retry on client errors' do
|
240
|
+
count = 0
|
241
|
+
@connection = stub_connection do |stub|
|
242
|
+
stub.get('/foo') do |env|
|
243
|
+
expect(count).to eq(0)
|
244
|
+
count += 1
|
245
|
+
[403, {}, '{}']
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
client.execute(
|
250
|
+
:uri => 'https://www.google.com/foo',
|
251
|
+
:connection => @connection,
|
252
|
+
:authenticated => false
|
253
|
+
)
|
254
|
+
end
|
255
|
+
|
216
256
|
it 'should retry on 500 errors' do
|
217
257
|
client.authorization = nil
|
218
258
|
|
@@ -225,10 +265,10 @@ describe Google::APIClient do
|
|
225
265
|
end
|
226
266
|
end
|
227
267
|
|
228
|
-
client.execute(
|
229
|
-
:uri => 'https://www.
|
268
|
+
expect(client.execute(
|
269
|
+
:uri => 'https://www.google.com/foo',
|
230
270
|
:connection => @connection
|
231
|
-
).status.
|
271
|
+
).status).to eq(200)
|
232
272
|
|
233
273
|
end
|
234
274
|
|
@@ -242,12 +282,71 @@ describe Google::APIClient do
|
|
242
282
|
end
|
243
283
|
end
|
244
284
|
|
245
|
-
client.execute(
|
285
|
+
expect(client.execute(
|
286
|
+
:uri => 'https://www.google.com/foo',
|
287
|
+
:connection => @connection
|
288
|
+
).status).to eq(500)
|
289
|
+
expect(count).to eq(3)
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
293
|
+
|
294
|
+
describe 'when retries disabled and expired_auth_retry on (default)' do
|
295
|
+
before do
|
296
|
+
client.retries = 0
|
297
|
+
end
|
298
|
+
|
299
|
+
after do
|
300
|
+
@connection.verify
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'should refresh tokens on 401 errors' do
|
304
|
+
client.authorization.access_token = '12345'
|
305
|
+
expect(client.authorization).to receive(:fetch_access_token!)
|
306
|
+
|
307
|
+
@connection = stub_connection do |stub|
|
308
|
+
stub.get('/foo') do |env|
|
309
|
+
[401, {}, '{}']
|
310
|
+
end
|
311
|
+
stub.get('/foo') do |env|
|
312
|
+
[200, {}, '{}']
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
client.execute(
|
246
317
|
:uri => 'https://www.gogole.com/foo',
|
247
318
|
:connection => @connection
|
248
|
-
)
|
249
|
-
|
319
|
+
)
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|
323
|
+
|
324
|
+
describe 'when retries disabled and expired_auth_retry off' do
|
325
|
+
before do
|
326
|
+
client.retries = 0
|
327
|
+
client.expired_auth_retry = false
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'should not refresh tokens on 401 errors' do
|
331
|
+
client.authorization.access_token = '12345'
|
332
|
+
expect(client.authorization).not_to receive(:fetch_access_token!)
|
333
|
+
|
334
|
+
@connection = stub_connection do |stub|
|
335
|
+
stub.get('/foo') do |env|
|
336
|
+
[401, {}, '{}']
|
337
|
+
end
|
338
|
+
stub.get('/foo') do |env|
|
339
|
+
[200, {}, '{}']
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
resp = client.execute(
|
344
|
+
:uri => 'https://www.gogole.com/foo',
|
345
|
+
:connection => @connection
|
346
|
+
)
|
347
|
+
|
348
|
+
expect(resp.response.status).to be == 401
|
250
349
|
end
|
251
350
|
|
252
|
-
end
|
351
|
+
end
|
253
352
|
end
|