google-api-client 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|