arvados-google-api-client 0.8.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +178 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +202 -0
  5. data/README.md +218 -0
  6. data/Rakefile +41 -0
  7. data/google-api-client.gemspec +43 -0
  8. data/lib/cacerts.pem +2183 -0
  9. data/lib/compat/multi_json.rb +19 -0
  10. data/lib/google/api_client.rb +750 -0
  11. data/lib/google/api_client/auth/compute_service_account.rb +28 -0
  12. data/lib/google/api_client/auth/file_storage.rb +59 -0
  13. data/lib/google/api_client/auth/installed_app.rb +126 -0
  14. data/lib/google/api_client/auth/jwt_asserter.rb +126 -0
  15. data/lib/google/api_client/auth/key_utils.rb +93 -0
  16. data/lib/google/api_client/auth/pkcs12.rb +41 -0
  17. data/lib/google/api_client/auth/storage.rb +102 -0
  18. data/lib/google/api_client/auth/storages/file_store.rb +58 -0
  19. data/lib/google/api_client/auth/storages/redis_store.rb +54 -0
  20. data/lib/google/api_client/batch.rb +326 -0
  21. data/lib/google/api_client/charset.rb +33 -0
  22. data/lib/google/api_client/client_secrets.rb +179 -0
  23. data/lib/google/api_client/discovery.rb +19 -0
  24. data/lib/google/api_client/discovery/api.rb +310 -0
  25. data/lib/google/api_client/discovery/media.rb +77 -0
  26. data/lib/google/api_client/discovery/method.rb +363 -0
  27. data/lib/google/api_client/discovery/resource.rb +156 -0
  28. data/lib/google/api_client/discovery/schema.rb +117 -0
  29. data/lib/google/api_client/environment.rb +42 -0
  30. data/lib/google/api_client/errors.rb +65 -0
  31. data/lib/google/api_client/gzip.rb +28 -0
  32. data/lib/google/api_client/logging.rb +32 -0
  33. data/lib/google/api_client/media.rb +259 -0
  34. data/lib/google/api_client/railtie.rb +18 -0
  35. data/lib/google/api_client/reference.rb +27 -0
  36. data/lib/google/api_client/request.rb +350 -0
  37. data/lib/google/api_client/result.rb +255 -0
  38. data/lib/google/api_client/service.rb +233 -0
  39. data/lib/google/api_client/service/batch.rb +110 -0
  40. data/lib/google/api_client/service/request.rb +144 -0
  41. data/lib/google/api_client/service/resource.rb +40 -0
  42. data/lib/google/api_client/service/result.rb +162 -0
  43. data/lib/google/api_client/service/simple_file_store.rb +151 -0
  44. data/lib/google/api_client/service/stub_generator.rb +61 -0
  45. data/lib/google/api_client/service_account.rb +21 -0
  46. data/lib/google/api_client/version.rb +26 -0
  47. data/spec/google/api_client/auth/storage_spec.rb +122 -0
  48. data/spec/google/api_client/auth/storages/file_store_spec.rb +40 -0
  49. data/spec/google/api_client/auth/storages/redis_store_spec.rb +70 -0
  50. data/spec/google/api_client/batch_spec.rb +248 -0
  51. data/spec/google/api_client/client_secrets_spec.rb +53 -0
  52. data/spec/google/api_client/discovery_spec.rb +708 -0
  53. data/spec/google/api_client/gzip_spec.rb +98 -0
  54. data/spec/google/api_client/media_spec.rb +178 -0
  55. data/spec/google/api_client/request_spec.rb +29 -0
  56. data/spec/google/api_client/result_spec.rb +207 -0
  57. data/spec/google/api_client/service_account_spec.rb +169 -0
  58. data/spec/google/api_client/service_spec.rb +618 -0
  59. data/spec/google/api_client/simple_file_store_spec.rb +133 -0
  60. data/spec/google/api_client_spec.rb +352 -0
  61. data/spec/spec_helper.rb +66 -0
  62. metadata +339 -0
@@ -0,0 +1,169 @@
1
+ # Copyright 2012 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ require 'google/api_client'
18
+
19
+ fixtures_path = File.expand_path('../../../fixtures', __FILE__)
20
+
21
+ RSpec.describe Google::APIClient::KeyUtils do
22
+ it 'should read PKCS12 files from the filesystem' do
23
+ if RUBY_PLATFORM == 'java' && RUBY_VERSION.start_with?('1.8')
24
+ pending "Reading from PKCS12 not supported on jruby 1.8.x"
25
+ end
26
+ path = File.expand_path('files/privatekey.p12', fixtures_path)
27
+ key = Google::APIClient::KeyUtils.load_from_pkcs12(path, 'notasecret')
28
+ expect(key).not_to eq(nil)
29
+ end
30
+
31
+ it 'should read PKCS12 files from loaded files' do
32
+ if RUBY_PLATFORM == 'java' && RUBY_VERSION.start_with?('1.8')
33
+ pending "Reading from PKCS12 not supported on jruby 1.8.x"
34
+ end
35
+ path = File.expand_path('files/privatekey.p12', fixtures_path)
36
+ content = File.read(path)
37
+ key = Google::APIClient::KeyUtils.load_from_pkcs12(content, 'notasecret')
38
+ expect(key).not_to eq(nil)
39
+ end
40
+
41
+ it 'should read PEM files from the filesystem' do
42
+ path = File.expand_path('files/secret.pem', fixtures_path)
43
+ key = Google::APIClient::KeyUtils.load_from_pem(path, 'notasecret')
44
+ expect(key).not_to eq(nil)
45
+ end
46
+
47
+ it 'should read PEM files from loaded files' do
48
+ path = File.expand_path('files/secret.pem', fixtures_path)
49
+ content = File.read(path)
50
+ key = Google::APIClient::KeyUtils.load_from_pem(content, 'notasecret')
51
+ expect(key).not_to eq(nil)
52
+ end
53
+
54
+ end
55
+
56
+ RSpec.describe Google::APIClient::JWTAsserter do
57
+ include ConnectionHelpers
58
+
59
+ before do
60
+ @key = OpenSSL::PKey::RSA.new 2048
61
+ end
62
+
63
+ it 'should generate valid JWTs' do
64
+ asserter = Google::APIClient::JWTAsserter.new('client1', 'scope1 scope2', @key)
65
+ jwt = asserter.to_authorization.to_jwt
66
+ expect(jwt).not_to eq(nil)
67
+
68
+ claim = JWT.decode(jwt, @key.public_key, true)
69
+ claim = claim[0] if claim[0]
70
+ expect(claim["iss"]).to eq('client1')
71
+ expect(claim["scope"]).to eq('scope1 scope2')
72
+ end
73
+
74
+ it 'should allow impersonation' do
75
+ conn = stub_connection do |stub|
76
+ stub.post('/o/oauth2/token') do |env|
77
+ params = Addressable::URI.form_unencode(env[:body])
78
+ JWT.decode(params.assoc("assertion").last, @key.public_key)
79
+ expect(params.assoc("grant_type")).to eq(['grant_type','urn:ietf:params:oauth:grant-type:jwt-bearer'])
80
+ [200, {'content-type' => 'application/json'}, '{
81
+ "access_token" : "1/abcdef1234567890",
82
+ "token_type" : "Bearer",
83
+ "expires_in" : 3600
84
+ }']
85
+ end
86
+ end
87
+ asserter = Google::APIClient::JWTAsserter.new('client1', 'scope1 scope2', @key)
88
+ auth = asserter.authorize('user1@email.com', { :connection => conn })
89
+ expect(auth).not_to eq(nil?)
90
+ expect(auth.person).to eq('user1@email.com')
91
+ conn.verify
92
+ end
93
+
94
+ it 'should send valid access token request' do
95
+ conn = stub_connection do |stub|
96
+ stub.post('/o/oauth2/token') do |env|
97
+ params = Addressable::URI.form_unencode(env[:body])
98
+ JWT.decode(params.assoc("assertion").last, @key.public_key)
99
+ expect(params.assoc("grant_type")).to eq(['grant_type','urn:ietf:params:oauth:grant-type:jwt-bearer'])
100
+ [200, {'content-type' => 'application/json'}, '{
101
+ "access_token" : "1/abcdef1234567890",
102
+ "token_type" : "Bearer",
103
+ "expires_in" : 3600
104
+ }']
105
+ end
106
+ end
107
+ asserter = Google::APIClient::JWTAsserter.new('client1', 'scope1 scope2', @key)
108
+ auth = asserter.authorize(nil, { :connection => conn })
109
+ expect(auth).not_to eq(nil?)
110
+ expect(auth.access_token).to eq("1/abcdef1234567890")
111
+ conn.verify
112
+ end
113
+
114
+ it 'should be refreshable' do
115
+ conn = stub_connection do |stub|
116
+ stub.post('/o/oauth2/token') do |env|
117
+ params = Addressable::URI.form_unencode(env[:body])
118
+ JWT.decode(params.assoc("assertion").last, @key.public_key)
119
+ expect(params.assoc("grant_type")).to eq(['grant_type','urn:ietf:params:oauth:grant-type:jwt-bearer'])
120
+ [200, {'content-type' => 'application/json'}, '{
121
+ "access_token" : "1/abcdef1234567890",
122
+ "token_type" : "Bearer",
123
+ "expires_in" : 3600
124
+ }']
125
+ end
126
+ stub.post('/o/oauth2/token') do |env|
127
+ params = Addressable::URI.form_unencode(env[:body])
128
+ JWT.decode(params.assoc("assertion").last, @key.public_key)
129
+ expect(params.assoc("grant_type")).to eq(['grant_type','urn:ietf:params:oauth:grant-type:jwt-bearer'])
130
+ [200, {'content-type' => 'application/json'}, '{
131
+ "access_token" : "1/0987654321fedcba",
132
+ "token_type" : "Bearer",
133
+ "expires_in" : 3600
134
+ }']
135
+ end
136
+ end
137
+ asserter = Google::APIClient::JWTAsserter.new('client1', 'scope1 scope2', @key)
138
+ auth = asserter.authorize(nil, { :connection => conn })
139
+ expect(auth).not_to eq(nil?)
140
+ expect(auth.access_token).to eq("1/abcdef1234567890")
141
+
142
+ auth.fetch_access_token!(:connection => conn)
143
+ expect(auth.access_token).to eq("1/0987654321fedcba")
144
+
145
+ conn.verify
146
+ end
147
+ end
148
+
149
+ RSpec.describe Google::APIClient::ComputeServiceAccount do
150
+ include ConnectionHelpers
151
+
152
+ it 'should query metadata server' do
153
+ conn = stub_connection do |stub|
154
+ stub.get('/computeMetadata/v1beta1/instance/service-accounts/default/token') do |env|
155
+ expect(env.url.host).to eq('metadata')
156
+ [200, {'content-type' => 'application/json'}, '{
157
+ "access_token" : "1/abcdef1234567890",
158
+ "token_type" : "Bearer",
159
+ "expires_in" : 3600
160
+ }']
161
+ end
162
+ end
163
+ service_account = Google::APIClient::ComputeServiceAccount.new
164
+ auth = service_account.fetch_access_token!({ :connection => conn })
165
+ expect(auth).not_to eq(nil?)
166
+ expect(auth["access_token"]).to eq("1/abcdef1234567890")
167
+ conn.verify
168
+ end
169
+ end
@@ -0,0 +1,618 @@
1
+ # encoding:utf-8
2
+
3
+ # Copyright 2013 Google Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'spec_helper'
18
+
19
+ require 'google/api_client'
20
+ require 'google/api_client/service'
21
+
22
+ fixtures_path = File.expand_path('../../../fixtures', __FILE__)
23
+
24
+ RSpec.describe Google::APIClient::Service do
25
+ include ConnectionHelpers
26
+
27
+ APPLICATION_NAME = 'API Client Tests'
28
+
29
+ it 'should error out when called without an API name or version' do
30
+ expect(lambda do
31
+ Google::APIClient::Service.new
32
+ end).to raise_error(ArgumentError)
33
+ end
34
+
35
+ it 'should error out when called without an API version' do
36
+ expect(lambda do
37
+ Google::APIClient::Service.new('foo')
38
+ end).to raise_error(ArgumentError)
39
+ end
40
+
41
+ it 'should error out when the options hash is not a hash' do
42
+ expect(lambda do
43
+ Google::APIClient::Service.new('foo', 'v1', 42)
44
+ end).to raise_error(ArgumentError)
45
+ end
46
+
47
+ describe 'with the AdSense Management API' do
48
+
49
+ it 'should make a valid call for a method with no parameters' do
50
+ conn = stub_connection do |stub|
51
+ stub.get('/adsense/v1.3/adclients') do |env|
52
+ [200, {}, '{}']
53
+ end
54
+ end
55
+ adsense = Google::APIClient::Service.new(
56
+ 'adsense',
57
+ 'v1.3',
58
+ {
59
+ :application_name => APPLICATION_NAME,
60
+ :authenticated => false,
61
+ :connection => conn,
62
+ :cache_store => nil
63
+ }
64
+ )
65
+
66
+ req = adsense.adclients.list.execute()
67
+ conn.verify
68
+ end
69
+
70
+ it 'should make a valid call for a method with parameters' do
71
+ conn = stub_connection do |stub|
72
+ stub.get('/adsense/v1.3/adclients/1/adunits') do |env|
73
+ [200, {}, '{}']
74
+ end
75
+ end
76
+ adsense = Google::APIClient::Service.new(
77
+ 'adsense',
78
+ 'v1.3',
79
+ {
80
+ :application_name => APPLICATION_NAME,
81
+ :authenticated => false,
82
+ :connection => conn,
83
+ :cache_store => nil
84
+ }
85
+ )
86
+ req = adsense.adunits.list(:adClientId => '1').execute()
87
+ end
88
+
89
+ it 'should make a valid call for a deep method' do
90
+ conn = stub_connection do |stub|
91
+ stub.get('/adsense/v1.3/accounts/1/adclients') do |env|
92
+ [200, {}, '{}']
93
+ end
94
+ end
95
+ adsense = Google::APIClient::Service.new(
96
+ 'adsense',
97
+ 'v1.3',
98
+ {
99
+ :application_name => APPLICATION_NAME,
100
+ :authenticated => false,
101
+ :connection => conn,
102
+ :cache_store => nil
103
+ }
104
+ )
105
+ req = adsense.accounts.adclients.list(:accountId => '1').execute()
106
+ end
107
+
108
+ describe 'with no connection' do
109
+ before do
110
+ @adsense = Google::APIClient::Service.new('adsense', 'v1.3',
111
+ {:application_name => APPLICATION_NAME, :cache_store => nil})
112
+ end
113
+
114
+ it 'should return a resource when using a valid resource name' do
115
+ expect(@adsense.accounts).to be_a(Google::APIClient::Service::Resource)
116
+ end
117
+
118
+ it 'should throw an error when using an invalid resource name' do
119
+ expect(lambda do
120
+ @adsense.invalid_resource
121
+ end).to raise_error
122
+ end
123
+
124
+ it 'should return a request when using a valid method name' do
125
+ req = @adsense.adclients.list
126
+ expect(req).to be_a(Google::APIClient::Service::Request)
127
+ expect(req.method.id).to eq('adsense.adclients.list')
128
+ expect(req.parameters).to be_nil
129
+ end
130
+
131
+ it 'should throw an error when using an invalid method name' do
132
+ expect(lambda do
133
+ @adsense.adclients.invalid_method
134
+ end).to raise_error
135
+ end
136
+
137
+ it 'should return a valid request with parameters' do
138
+ req = @adsense.adunits.list(:adClientId => '1')
139
+ expect(req).to be_a(Google::APIClient::Service::Request)
140
+ expect(req.method.id).to eq('adsense.adunits.list')
141
+ expect(req.parameters).not_to be_nil
142
+ expect(req.parameters[:adClientId]).to eq('1')
143
+ end
144
+ end
145
+ end
146
+
147
+ describe 'with the Prediction API' do
148
+
149
+ it 'should make a valid call with an object body' do
150
+ conn = stub_connection do |stub|
151
+ stub.post('/prediction/v1.5/trainedmodels?project=1') do |env|
152
+ expect(env.body).to eq('{"id":"1"}')
153
+ [200, {}, '{}']
154
+ end
155
+ end
156
+ prediction = Google::APIClient::Service.new(
157
+ 'prediction',
158
+ 'v1.5',
159
+ {
160
+ :application_name => APPLICATION_NAME,
161
+ :authenticated => false,
162
+ :connection => conn,
163
+ :cache_store => nil
164
+ }
165
+ )
166
+ req = prediction.trainedmodels.insert(:project => '1').body({'id' => '1'}).execute()
167
+ conn.verify
168
+ end
169
+
170
+ it 'should make a valid call with a text body' do
171
+ conn = stub_connection do |stub|
172
+ stub.post('/prediction/v1.5/trainedmodels?project=1') do |env|
173
+ expect(env.body).to eq('{"id":"1"}')
174
+ [200, {}, '{}']
175
+ end
176
+ end
177
+ prediction = Google::APIClient::Service.new(
178
+ 'prediction',
179
+ 'v1.5',
180
+ {
181
+ :application_name => APPLICATION_NAME,
182
+ :authenticated => false,
183
+ :connection => conn,
184
+ :cache_store => nil
185
+ }
186
+ )
187
+ req = prediction.trainedmodels.insert(:project => '1').body('{"id":"1"}').execute()
188
+ conn.verify
189
+ end
190
+
191
+ describe 'with no connection' do
192
+ before do
193
+ @prediction = Google::APIClient::Service.new('prediction', 'v1.5',
194
+ {:application_name => APPLICATION_NAME, :cache_store => nil})
195
+ end
196
+
197
+ it 'should return a valid request with a body' do
198
+ req = @prediction.trainedmodels.insert(:project => '1').body({'id' => '1'})
199
+ expect(req).to be_a(Google::APIClient::Service::Request)
200
+ expect(req.method.id).to eq('prediction.trainedmodels.insert')
201
+ expect(req.body).to eq({'id' => '1'})
202
+ expect(req.parameters).not_to be_nil
203
+ expect(req.parameters[:project]).to eq('1')
204
+ end
205
+
206
+ it 'should return a valid request with a body when using resource name' do
207
+ req = @prediction.trainedmodels.insert(:project => '1').training({'id' => '1'})
208
+ expect(req).to be_a(Google::APIClient::Service::Request)
209
+ expect(req.method.id).to eq('prediction.trainedmodels.insert')
210
+ expect(req.training).to eq({'id' => '1'})
211
+ expect(req.parameters).not_to be_nil
212
+ expect(req.parameters[:project]).to eq('1')
213
+ end
214
+ end
215
+ end
216
+
217
+ describe 'with the Drive API' do
218
+
219
+ before do
220
+ @metadata = {
221
+ 'title' => 'My movie',
222
+ 'description' => 'The best home movie ever made'
223
+ }
224
+ @file = File.expand_path('files/sample.txt', fixtures_path)
225
+ @media = Google::APIClient::UploadIO.new(@file, 'text/plain')
226
+ end
227
+
228
+ it 'should make a valid call with an object body and media upload' do
229
+ conn = stub_connection do |stub|
230
+ stub.post('/upload/drive/v2/files?uploadType=multipart') do |env|
231
+ expect(env.body).to be_a Faraday::CompositeReadIO
232
+ [200, {}, '{}']
233
+ end
234
+ end
235
+ drive = Google::APIClient::Service.new(
236
+ 'drive',
237
+ 'v2',
238
+ {
239
+ :application_name => APPLICATION_NAME,
240
+ :authenticated => false,
241
+ :connection => conn,
242
+ :cache_store => nil
243
+ }
244
+ )
245
+ req = drive.files.insert(:uploadType => 'multipart').body(@metadata).media(@media).execute()
246
+ conn.verify
247
+ end
248
+
249
+ describe 'with no connection' do
250
+ before do
251
+ @drive = Google::APIClient::Service.new('drive', 'v2',
252
+ {:application_name => APPLICATION_NAME, :cache_store => nil})
253
+ end
254
+
255
+ it 'should return a valid request with a body and media upload' do
256
+ req = @drive.files.insert(:uploadType => 'multipart').body(@metadata).media(@media)
257
+ expect(req).to be_a(Google::APIClient::Service::Request)
258
+ expect(req.method.id).to eq('drive.files.insert')
259
+ expect(req.body).to eq(@metadata)
260
+ expect(req.media).to eq(@media)
261
+ expect(req.parameters).not_to be_nil
262
+ expect(req.parameters[:uploadType]).to eq('multipart')
263
+ end
264
+
265
+ it 'should return a valid request with a body and media upload when using resource name' do
266
+ req = @drive.files.insert(:uploadType => 'multipart').file(@metadata).media(@media)
267
+ expect(req).to be_a(Google::APIClient::Service::Request)
268
+ expect(req.method.id).to eq('drive.files.insert')
269
+ expect(req.file).to eq(@metadata)
270
+ expect(req.media).to eq(@media)
271
+ expect(req.parameters).not_to be_nil
272
+ expect(req.parameters[:uploadType]).to eq('multipart')
273
+ end
274
+ end
275
+ end
276
+
277
+ describe 'with the Discovery API' do
278
+ it 'should make a valid end-to-end request' do
279
+ discovery = Google::APIClient::Service.new('discovery', 'v1',
280
+ {:application_name => APPLICATION_NAME, :authenticated => false,
281
+ :cache_store => nil})
282
+ result = discovery.apis.get_rest(:api => 'discovery', :version => 'v1').execute
283
+ expect(result).not_to be_nil
284
+ expect(result.data.name).to eq('discovery')
285
+ expect(result.data.version).to eq('v1')
286
+ end
287
+ end
288
+ end
289
+
290
+
291
+ RSpec.describe Google::APIClient::Service::Result do
292
+
293
+ describe 'with the plus API' do
294
+ before do
295
+ @plus = Google::APIClient::Service.new('plus', 'v1',
296
+ {:application_name => APPLICATION_NAME, :cache_store => nil})
297
+ @reference = Google::APIClient::Reference.new({
298
+ :api_method => @plus.activities.list.method,
299
+ :parameters => {
300
+ 'userId' => 'me',
301
+ 'collection' => 'public',
302
+ 'maxResults' => 20
303
+ }
304
+ })
305
+ @request = @plus.activities.list(:userId => 'me', :collection => 'public',
306
+ :maxResults => 20)
307
+
308
+ # Response double
309
+ @response = double("response")
310
+ allow(@response).to receive(:status).and_return(200)
311
+ allow(@response).to receive(:headers).and_return({
312
+ 'etag' => '12345',
313
+ 'x-google-apiary-auth-scopes' =>
314
+ 'https://www.googleapis.com/auth/plus.me',
315
+ 'content-type' => 'application/json; charset=UTF-8',
316
+ 'date' => 'Mon, 23 Apr 2012 00:00:00 GMT',
317
+ 'cache-control' => 'private, max-age=0, must-revalidate, no-transform',
318
+ 'server' => 'GSE',
319
+ 'connection' => 'close'
320
+ })
321
+ end
322
+
323
+ describe 'with a next page token' do
324
+ before do
325
+ @body = <<-END_OF_STRING
326
+ {
327
+ "kind": "plus#activityFeed",
328
+ "etag": "FOO",
329
+ "nextPageToken": "NEXT+PAGE+TOKEN",
330
+ "selfLink": "https://www.googleapis.com/plus/v1/people/foo/activities/public?",
331
+ "nextLink": "https://www.googleapis.com/plus/v1/people/foo/activities/public?maxResults=20&pageToken=NEXT%2BPAGE%2BTOKEN",
332
+ "title": "Plus Public Activity Feed for ",
333
+ "updated": "2012-04-23T00:00:00.000Z",
334
+ "id": "123456790",
335
+ "items": []
336
+ }
337
+ END_OF_STRING
338
+ allow(@response).to receive(:body).and_return(@body)
339
+ base_result = Google::APIClient::Result.new(@reference, @response)
340
+ @result = Google::APIClient::Service::Result.new(@request, base_result)
341
+ end
342
+
343
+ it 'should indicate a successful response' do
344
+ expect(@result.error?).to be_falsey
345
+ end
346
+
347
+ it 'should return the correct next page token' do
348
+ expect(@result.next_page_token).to eq('NEXT+PAGE+TOKEN')
349
+ end
350
+
351
+ it 'generate a correct request when calling next_page' do
352
+ next_page_request = @result.next_page
353
+ expect(next_page_request.parameters).to include('pageToken')
354
+ expect(next_page_request.parameters['pageToken']).to eq('NEXT+PAGE+TOKEN')
355
+ @request.parameters.each_pair do |param, value|
356
+ expect(next_page_request.parameters[param]).to eq(value)
357
+ end
358
+ end
359
+
360
+ it 'should return content type correctly' do
361
+ expect(@result.media_type).to eq('application/json')
362
+ end
363
+
364
+ it 'should return the body correctly' do
365
+ expect(@result.body).to eq(@body)
366
+ end
367
+
368
+ it 'should return the result data correctly' do
369
+ expect(@result.data?).to be_truthy
370
+ expect(@result.data.class.to_s).to eq(
371
+ 'Google::APIClient::Schema::Plus::V1::ActivityFeed'
372
+ )
373
+ expect(@result.data.kind).to eq('plus#activityFeed')
374
+ expect(@result.data.etag).to eq('FOO')
375
+ expect(@result.data.nextPageToken).to eq('NEXT+PAGE+TOKEN')
376
+ expect(@result.data.selfLink).to eq(
377
+ 'https://www.googleapis.com/plus/v1/people/foo/activities/public?'
378
+ )
379
+ expect(@result.data.nextLink).to eq(
380
+ 'https://www.googleapis.com/plus/v1/people/foo/activities/public?' +
381
+ 'maxResults=20&pageToken=NEXT%2BPAGE%2BTOKEN'
382
+ )
383
+ expect(@result.data.title).to eq('Plus Public Activity Feed for ')
384
+ expect(@result.data.id).to eq("123456790")
385
+ expect(@result.data.items).to be_empty
386
+ end
387
+ end
388
+
389
+ describe 'without a next page token' do
390
+ before do
391
+ @body = <<-END_OF_STRING
392
+ {
393
+ "kind": "plus#activityFeed",
394
+ "etag": "FOO",
395
+ "selfLink": "https://www.googleapis.com/plus/v1/people/foo/activities/public?",
396
+ "title": "Plus Public Activity Feed for ",
397
+ "updated": "2012-04-23T00:00:00.000Z",
398
+ "id": "123456790",
399
+ "items": []
400
+ }
401
+ END_OF_STRING
402
+ allow(@response).to receive(:body).and_return(@body)
403
+ base_result = Google::APIClient::Result.new(@reference, @response)
404
+ @result = Google::APIClient::Service::Result.new(@request, base_result)
405
+ end
406
+
407
+ it 'should not return a next page token' do
408
+ expect(@result.next_page_token).to eq(nil)
409
+ end
410
+
411
+ it 'should return content type correctly' do
412
+ expect(@result.media_type).to eq('application/json')
413
+ end
414
+
415
+ it 'should return the body correctly' do
416
+ expect(@result.body).to eq(@body)
417
+ end
418
+
419
+ it 'should return the result data correctly' do
420
+ expect(@result.data?).to be_truthy
421
+ expect(@result.data.class.to_s).to eq(
422
+ 'Google::APIClient::Schema::Plus::V1::ActivityFeed'
423
+ )
424
+ expect(@result.data.kind).to eq('plus#activityFeed')
425
+ expect(@result.data.etag).to eq('FOO')
426
+ expect(@result.data.selfLink).to eq(
427
+ 'https://www.googleapis.com/plus/v1/people/foo/activities/public?'
428
+ )
429
+ expect(@result.data.title).to eq('Plus Public Activity Feed for ')
430
+ expect(@result.data.id).to eq("123456790")
431
+ expect(@result.data.items).to be_empty
432
+ end
433
+ end
434
+
435
+ describe 'with JSON error response' do
436
+ before do
437
+ @body = <<-END_OF_STRING
438
+ {
439
+ "error": {
440
+ "errors": [
441
+ {
442
+ "domain": "global",
443
+ "reason": "parseError",
444
+ "message": "Parse Error"
445
+ }
446
+ ],
447
+ "code": 400,
448
+ "message": "Parse Error"
449
+ }
450
+ }
451
+ END_OF_STRING
452
+ allow(@response).to receive(:body).and_return(@body)
453
+ allow(@response).to receive(:status).and_return(400)
454
+ base_result = Google::APIClient::Result.new(@reference, @response)
455
+ @result = Google::APIClient::Service::Result.new(@request, base_result)
456
+ end
457
+
458
+ it 'should return error status correctly' do
459
+ expect(@result.error?).to be_truthy
460
+ end
461
+
462
+ it 'should return the correct error message' do
463
+ expect(@result.error_message).to eq('Parse Error')
464
+ end
465
+
466
+ it 'should return the body correctly' do
467
+ expect(@result.body).to eq(@body)
468
+ end
469
+ end
470
+
471
+ describe 'with 204 No Content response' do
472
+ before do
473
+ allow(@response).to receive(:body).and_return('')
474
+ allow(@response).to receive(:status).and_return(204)
475
+ allow(@response).to receive(:headers).and_return({})
476
+ base_result = Google::APIClient::Result.new(@reference, @response)
477
+ @result = Google::APIClient::Service::Result.new(@request, base_result)
478
+ end
479
+
480
+ it 'should indicate no data is available' do
481
+ expect(@result.data?).to be_falsey
482
+ end
483
+
484
+ it 'should return nil for data' do
485
+ expect(@result.data).to eq(nil)
486
+ end
487
+
488
+ it 'should return nil for media_type' do
489
+ expect(@result.media_type).to eq(nil)
490
+ end
491
+ end
492
+ end
493
+ end
494
+
495
+ RSpec.describe Google::APIClient::Service::BatchRequest do
496
+
497
+ include ConnectionHelpers
498
+
499
+ context 'with a service connection' do
500
+ before do
501
+ @conn = stub_connection do |stub|
502
+ stub.post('/batch') do |env|
503
+ [500, {'Content-Type' => 'application/json'}, '{}']
504
+ end
505
+ end
506
+ @discovery = Google::APIClient::Service.new('discovery', 'v1',
507
+ {:application_name => APPLICATION_NAME, :authorization => nil,
508
+ :cache_store => nil, :connection => @conn})
509
+ @calls = [
510
+ @discovery.apis.get_rest(:api => 'plus', :version => 'v1'),
511
+ @discovery.apis.get_rest(:api => 'discovery', :version => 'v1')
512
+ ]
513
+ end
514
+
515
+ it 'should use the service connection' do
516
+ batch = @discovery.batch(@calls) do
517
+ end
518
+ batch.execute
519
+ @conn.verify
520
+ end
521
+ end
522
+
523
+ describe 'with the discovery API' do
524
+ before do
525
+ @discovery = Google::APIClient::Service.new('discovery', 'v1',
526
+ {:application_name => APPLICATION_NAME, :authorization => nil,
527
+ :cache_store => nil})
528
+ end
529
+
530
+ describe 'with two valid requests' do
531
+ before do
532
+ @calls = [
533
+ @discovery.apis.get_rest(:api => 'plus', :version => 'v1'),
534
+ @discovery.apis.get_rest(:api => 'discovery', :version => 'v1')
535
+ ]
536
+ end
537
+
538
+ it 'should execute both when using a global callback' do
539
+ block_called = 0
540
+ batch = @discovery.batch(@calls) do |result|
541
+ block_called += 1
542
+ expect(result.status).to eq(200)
543
+ end
544
+
545
+ batch.execute
546
+ expect(block_called).to eq(2)
547
+ end
548
+
549
+ it 'should execute both when using individual callbacks' do
550
+ call1_returned, call2_returned = false, false
551
+ batch = @discovery.batch
552
+
553
+ batch.add(@calls[0]) do |result|
554
+ call1_returned = true
555
+ expect(result.status).to eq(200)
556
+ expect(result.call_index).to eq(0)
557
+ end
558
+
559
+ batch.add(@calls[1]) do |result|
560
+ call2_returned = true
561
+ expect(result.status).to eq(200)
562
+ expect(result.call_index).to eq(1)
563
+ end
564
+
565
+ batch.execute
566
+ expect(call1_returned).to eq(true)
567
+ expect(call2_returned).to eq(true)
568
+ end
569
+ end
570
+
571
+ describe 'with a valid request and an invalid one' do
572
+ before do
573
+ @calls = [
574
+ @discovery.apis.get_rest(:api => 'plus', :version => 'v1'),
575
+ @discovery.apis.get_rest(:api => 'invalid', :version => 'invalid')
576
+ ]
577
+ end
578
+
579
+ it 'should execute both when using a global callback' do
580
+ block_called = 0
581
+ batch = @discovery.batch(@calls) do |result|
582
+ block_called += 1
583
+ if result.call_index == 0
584
+ expect(result.status).to eq(200)
585
+ else
586
+ expect(result.status).to be >= 400
587
+ expect(result.status).to be < 500
588
+ end
589
+ end
590
+
591
+ batch.execute
592
+ expect(block_called).to eq(2)
593
+ end
594
+
595
+ it 'should execute both when using individual callbacks' do
596
+ call1_returned, call2_returned = false, false
597
+ batch = @discovery.batch
598
+
599
+ batch.add(@calls[0]) do |result|
600
+ call1_returned = true
601
+ expect(result.status).to eq(200)
602
+ expect(result.call_index).to eq(0)
603
+ end
604
+
605
+ batch.add(@calls[1]) do |result|
606
+ call2_returned = true
607
+ expect(result.status).to be >= 400
608
+ expect(result.status).to be < 500
609
+ expect(result.call_index).to eq(1)
610
+ end
611
+
612
+ batch.execute
613
+ expect(call1_returned).to eq(true)
614
+ expect(call2_returned).to eq(true)
615
+ end
616
+ end
617
+ end
618
+ end