3 # Copyright 2010 Google Inc.
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
21 require 'faraday/utils'
23 require 'compat/multi_json'
24 require 'signet/oauth_1/client'
25 require 'google/api_client'
26 require 'google/api_client/version'
28 describe Google::APIClient do
29 CLIENT = Google::APIClient.new unless defined?(CLIENT)
32 # Reset client to not-quite-pristine state
37 it 'should raise a type error for bogus authorization' do
39 Google::APIClient.new(:authorization => 42)
40 end).should raise_error(TypeError)
43 it 'should not be able to retrieve the discovery document for a bogus API' do
45 CLIENT.discovery_document('bogus')
46 end).should raise_error(Google::APIClient::TransmissionError)
48 CLIENT.discovered_api('bogus')
49 end).should raise_error(Google::APIClient::TransmissionError)
52 it 'should raise an error for bogus services' do
54 CLIENT.discovered_api(42)
55 end).should raise_error(TypeError)
58 it 'should raise an error for bogus services' do
60 CLIENT.preferred_version(42)
61 end).should raise_error(TypeError)
64 it 'should raise an error for bogus methods' do
66 CLIENT.generate_request(42)
67 end).should raise_error(TypeError)
70 it 'should not return a preferred version for bogus service names' do
71 CLIENT.preferred_version('bogus').should == nil
74 describe 'with the prediction API' do
76 CLIENT.authorization = nil
77 # The prediction API no longer exposes a v1, so we have to be
78 # careful about looking up the wrong API version.
79 @prediction = CLIENT.discovered_api('prediction', 'v1.2')
82 it 'should correctly determine the discovery URI' do
83 CLIENT.discovery_uri('prediction').should ===
84 'https://www.googleapis.com/discovery/v1/apis/prediction/v1/rest'
87 it 'should correctly determine the discovery URI if :user_ip is set' do
88 CLIENT.user_ip = '127.0.0.1'
89 request = CLIENT.generate_request(
90 :http_method => 'GET',
91 :uri => CLIENT.discovery_uri('prediction', 'v1.2'),
92 :authenticated => false
94 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should === (
95 'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
100 it 'should correctly determine the discovery URI if :key is set' do
101 CLIENT.key = 'qwerty'
102 request = CLIENT.generate_request(
103 :http_method => 'GET',
104 :uri => CLIENT.discovery_uri('prediction', 'v1.2'),
105 :authenticated => false
107 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should === (
108 'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
113 it 'should correctly determine the discovery URI if both are set' do
114 CLIENT.key = 'qwerty'
115 CLIENT.user_ip = '127.0.0.1'
116 request = CLIENT.generate_request(
117 :http_method => 'GET',
118 :uri => CLIENT.discovery_uri('prediction', 'v1.2'),
119 :authenticated => false
121 Addressable::URI.parse(
122 request.to_http_request.to_env(Faraday.default_connection)[:url]
123 ).query_values.should == {
125 'userIp' => '127.0.0.1'
129 it 'should correctly generate API objects' do
130 CLIENT.discovered_api('prediction', 'v1.2').name.should == 'prediction'
131 CLIENT.discovered_api('prediction', 'v1.2').version.should == 'v1.2'
132 CLIENT.discovered_api(:prediction, 'v1.2').name.should == 'prediction'
133 CLIENT.discovered_api(:prediction, 'v1.2').version.should == 'v1.2'
136 it 'should discover methods' do
137 CLIENT.discovered_method(
138 'prediction.training.insert', 'prediction', 'v1.2'
139 ).name.should == 'insert'
140 CLIENT.discovered_method(
141 :'prediction.training.insert', :prediction, 'v1.2'
142 ).name.should == 'insert'
143 CLIENT.discovered_method(
144 'prediction.training.delete', 'prediction', 'v1.2'
145 ).name.should == 'delete'
148 it 'should define the origin API in discovered methods' do
149 CLIENT.discovered_method(
150 'prediction.training.insert', 'prediction', 'v1.2'
151 ).api.name.should == 'prediction'
154 it 'should not find methods that are not in the discovery document' do
155 CLIENT.discovered_method(
156 'prediction.bogus', 'prediction', 'v1.2'
160 it 'should raise an error for bogus methods' do
162 CLIENT.discovered_method(42, 'prediction', 'v1.2')
163 end).should raise_error(TypeError)
166 it 'should raise an error for bogus methods' do
168 CLIENT.generate_request(CLIENT.discovered_api('prediction', 'v1.2'))
169 end).should raise_error(TypeError)
172 it 'should correctly determine the preferred version' do
173 CLIENT.preferred_version('prediction').version.should_not == 'v1'
174 CLIENT.preferred_version(:prediction).version.should_not == 'v1'
177 it 'should return a batch path' do
178 CLIENT.discovered_api('prediction', 'v1.2').batch_path.should_not be_nil
181 it 'should generate valid requests' do
182 request = CLIENT.generate_request(
183 :api_method => @prediction.training.insert,
184 :parameters => {'data' => '12345'}
186 request.to_http_request.method.should == :post
187 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
188 'https://www.googleapis.com/prediction/v1.2/training?data=12345'
189 request.headers.should be_empty
190 request.body.should == ''
193 it 'should generate valid requests when repeated parameters are passed' do
194 pending("This is caused by Faraday's encoding of query parameters.")
195 request = CLIENT.generate_request(
196 :api_method => @prediction.training.insert,
197 :parameters => [['data', '1'], ['data','2']]
199 request.to_http_request.method.should == :post
200 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
201 'https://www.googleapis.com/prediction/v1.2/training?data=1&data=2'
204 it 'should generate requests against the correct URIs' do
205 request = CLIENT.generate_request(
206 :api_method => @prediction.training.insert,
207 :parameters => {'data' => '12345'}
209 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
210 'https://www.googleapis.com/prediction/v1.2/training?data=12345'
213 it 'should generate requests against the correct URIs' do
214 request = CLIENT.generate_request(
215 :api_method => @prediction.training.insert,
216 :parameters => {'data' => '12345'}
218 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
219 'https://www.googleapis.com/prediction/v1.2/training?data=12345'
222 it 'should allow modification to the base URIs for testing purposes' do
223 # Using a new client instance here to avoid caching rebased discovery doc
225 Google::APIClient.new.discovered_api('prediction', 'v1.2')
226 prediction_rebase.method_base =
227 'https://testing-domain.example.com/prediction/v1.2/'
228 request = CLIENT.generate_request(
229 :api_method => prediction_rebase.training.insert,
230 :parameters => {'data' => '123'}
232 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should === (
233 'https://testing-domain.example.com/' +
234 'prediction/v1.2/training?data=123'
238 it 'should generate OAuth 1 requests' do
239 CLIENT.authorization = :oauth_1
240 CLIENT.authorization.token_credential_key = '12345'
241 CLIENT.authorization.token_credential_secret = '12345'
242 request = CLIENT.generate_request(
243 :api_method => @prediction.training.insert,
244 :parameters => {'data' => '12345'}
246 http_request = request.to_http_request
247 http_request.headers.should have_key('Authorization')
248 http_request.headers['Authorization'].should =~ /^OAuth/
251 it 'should generate OAuth 2 requests' do
252 CLIENT.authorization = :oauth_2
253 CLIENT.authorization.access_token = '12345'
254 request = CLIENT.generate_request(
255 :api_method => @prediction.training.insert,
256 :parameters => {'data' => '12345'}
258 http_request = request.to_http_request
259 http_request.headers.should have_key('Authorization')
260 http_request.headers['Authorization'].should =~ /^Bearer/
263 it 'should not be able to execute improperly authorized requests' do
264 CLIENT.authorization = :oauth_1
265 CLIENT.authorization.token_credential_key = '12345'
266 CLIENT.authorization.token_credential_secret = '12345'
267 result = CLIENT.execute(
268 @prediction.training.insert,
271 result.response.status.should == 401
274 it 'should not be able to execute improperly authorized requests' do
275 CLIENT.authorization = :oauth_2
276 CLIENT.authorization.access_token = '12345'
277 result = CLIENT.execute(
278 @prediction.training.insert,
281 result.response.status.should == 401
284 it 'should not be able to execute improperly authorized requests' do
286 CLIENT.authorization = :oauth_1
287 CLIENT.authorization.token_credential_key = '12345'
288 CLIENT.authorization.token_credential_secret = '12345'
289 result = CLIENT.execute!(
290 @prediction.training.insert,
293 end).should raise_error(Google::APIClient::ClientError)
296 it 'should not be able to execute improperly authorized requests' do
298 CLIENT.authorization = :oauth_2
299 CLIENT.authorization.access_token = '12345'
300 result = CLIENT.execute!(
301 @prediction.training.insert,
304 end).should raise_error(Google::APIClient::ClientError)
307 it 'should correctly handle unnamed parameters' do
308 CLIENT.authorization = :oauth_2
309 CLIENT.authorization.access_token = '12345'
310 result = CLIENT.execute(
311 @prediction.training.insert,
313 MultiJson.dump({"id" => "bucket/object"}),
314 {'Content-Type' => 'application/json'}
316 result.reference.to_http_request.headers['Content-Type'].should == 'application/json'
320 describe 'with the plus API' do
322 CLIENT.authorization = nil
323 @plus = CLIENT.discovered_api('plus')
326 it 'should correctly determine the discovery URI' do
327 CLIENT.discovery_uri('plus').should ===
328 'https://www.googleapis.com/discovery/v1/apis/plus/v1/rest'
331 it 'should find APIs that are in the discovery document' do
332 CLIENT.discovered_api('plus').name.should == 'plus'
333 CLIENT.discovered_api('plus').version.should == 'v1'
334 CLIENT.discovered_api(:plus).name.should == 'plus'
335 CLIENT.discovered_api(:plus).version.should == 'v1'
338 it 'should find methods that are in the discovery document' do
339 # TODO(bobaman) Fix this when the RPC names are correct
340 CLIENT.discovered_method(
341 'plus.activities.list', 'plus'
342 ).name.should == 'list'
345 it 'should define the origin API in discovered methods' do
346 CLIENT.discovered_method(
347 'plus.activities.list', 'plus'
348 ).api.name.should == 'plus'
351 it 'should not find methods that are not in the discovery document' do
352 CLIENT.discovered_method('plus.bogus', 'plus').should == nil
355 it 'should generate requests against the correct URIs' do
356 request = CLIENT.generate_request(
357 :api_method => @plus.activities.list,
359 'userId' => '107807692475771887386', 'collection' => 'public'
361 :authenticated => false
363 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should === (
364 'https://www.googleapis.com/plus/v1/' +
365 'people/107807692475771887386/activities/public'
369 it 'should correctly validate parameters' do
371 CLIENT.generate_request(
372 :api_method => @plus.activities.list,
373 :parameters => {'alt' => 'json'},
374 :authenticated => false
376 end).should raise_error(ArgumentError)
379 it 'should correctly validate parameters' do
381 CLIENT.generate_request(
382 :api_method => @plus.activities.list,
384 'userId' => '107807692475771887386', 'collection' => 'bogus'
386 :authenticated => false
388 end).should raise_error(ArgumentError)
393 describe 'with the latitude API' do
395 CLIENT.authorization = nil
396 @latitude = CLIENT.discovered_api('latitude')
399 it 'should correctly determine the discovery URI' do
400 CLIENT.discovery_uri('latitude').should ===
401 'https://www.googleapis.com/discovery/v1/apis/latitude/v1/rest'
404 it 'should find APIs that are in the discovery document' do
405 CLIENT.discovered_api('latitude').name.should == 'latitude'
406 CLIENT.discovered_api('latitude').version.should == 'v1'
409 it 'should return a batch path' do
410 CLIENT.discovered_api('latitude').batch_path.should_not be_nil
413 it 'should find methods that are in the discovery document' do
414 CLIENT.discovered_method(
415 'latitude.currentLocation.get', 'latitude'
416 ).name.should == 'get'
419 it 'should define the origin API in discovered methods' do
420 CLIENT.discovered_method(
421 'latitude.currentLocation.get', 'latitude'
422 ).api.name.should == 'latitude'
425 it 'should not find methods that are not in the discovery document' do
426 CLIENT.discovered_method('latitude.bogus', 'latitude').should == nil
429 it 'should generate requests against the correct URIs' do
430 request = CLIENT.generate_request(
431 :api_method => 'latitude.currentLocation.get',
432 :authenticated => false
434 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
435 'https://www.googleapis.com/latitude/v1/currentLocation'
438 it 'should generate requests against the correct URIs' do
439 request = CLIENT.generate_request(
440 :api_method => @latitude.current_location.get,
441 :authenticated => false
443 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
444 'https://www.googleapis.com/latitude/v1/currentLocation'
447 it 'should not be able to execute requests without authorization' do
448 result = CLIENT.execute(
449 :api_method => 'latitude.currentLocation.get',
450 :authenticated => false
452 result.response.status.should == 401
457 describe 'with the moderator API' do
459 CLIENT.authorization = nil
460 @moderator = CLIENT.discovered_api('moderator')
463 it 'should correctly determine the discovery URI' do
464 CLIENT.discovery_uri('moderator').should ===
465 'https://www.googleapis.com/discovery/v1/apis/moderator/v1/rest'
468 it 'should find APIs that are in the discovery document' do
469 CLIENT.discovered_api('moderator').name.should == 'moderator'
470 CLIENT.discovered_api('moderator').version.should == 'v1'
473 it 'should find methods that are in the discovery document' do
474 CLIENT.discovered_method(
475 'moderator.profiles.get', 'moderator'
476 ).name.should == 'get'
479 it 'should define the origin API in discovered methods' do
480 CLIENT.discovered_method(
481 'moderator.profiles.get', 'moderator'
482 ).api.name.should == 'moderator'
485 it 'should not find methods that are not in the discovery document' do
486 CLIENT.discovered_method('moderator.bogus', 'moderator').should == nil
489 it 'should return a batch path' do
490 CLIENT.discovered_api('moderator').batch_path.should_not be_nil
493 it 'should generate requests against the correct URIs' do
494 request = CLIENT.generate_request(
495 :api_method => 'moderator.profiles.get',
496 :authenticated => false
498 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
499 'https://www.googleapis.com/moderator/v1/profiles/@me'
502 it 'should generate requests against the correct URIs' do
503 request = CLIENT.generate_request(
504 :api_method => @moderator.profiles.get,
505 :authenticated => false
507 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
508 'https://www.googleapis.com/moderator/v1/profiles/@me'
511 it 'should not be able to execute requests without authorization' do
512 result = CLIENT.execute(
513 'moderator.profiles.get',
517 {:authenticated => false}
519 result.response.status.should == 401
523 describe 'with the adsense API' do
525 CLIENT.authorization = nil
526 @adsense = CLIENT.discovered_api('adsense', 'v1')
529 it 'should correctly determine the discovery URI' do
530 CLIENT.discovery_uri('adsense').should ===
531 'https://www.googleapis.com/discovery/v1/apis/adsense/v1/rest'
534 it 'should find APIs that are in the discovery document' do
535 CLIENT.discovered_api('adsense').name.should == 'adsense'
536 CLIENT.discovered_api('adsense').version.should == 'v1'
539 it 'should return a batch path' do
540 CLIENT.discovered_api('adsense').batch_path.should_not be_nil
543 it 'should find methods that are in the discovery document' do
544 CLIENT.discovered_method(
545 'adsense.reports.generate', 'adsense'
546 ).name.should == 'generate'
549 it 'should not find methods that are not in the discovery document' do
550 CLIENT.discovered_method('adsense.bogus', 'adsense').should == nil
553 it 'should generate requests against the correct URIs' do
554 request = CLIENT.generate_request(
555 :api_method => 'adsense.adclients.list',
556 :authenticated => false
558 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
559 'https://www.googleapis.com/adsense/v1/adclients'
562 it 'should generate requests against the correct URIs' do
563 request = CLIENT.generate_request(
564 :api_method => @adsense.adclients.list,
565 :authenticated => false
567 request.to_http_request.to_env(Faraday.default_connection)[:url].to_s.should ===
568 'https://www.googleapis.com/adsense/v1/adclients'
571 it 'should not be able to execute requests without authorization' do
572 result = CLIENT.execute(
573 :api_method => 'adsense.adclients.list',
574 :authenticated => false
576 result.response.status.should == 401
579 it 'should fail when validating missing required parameters' do
581 CLIENT.generate_request(
582 :api_method => @adsense.reports.generate,
583 :authenticated => false
585 end).should raise_error(ArgumentError)
588 it 'should succeed when validating parameters in a correct call' do
590 CLIENT.generate_request(
591 :api_method => @adsense.reports.generate,
593 'startDate' => '2000-01-01',
594 'endDate' => '2010-01-01',
595 'dimension' => 'DATE',
596 'metric' => 'PAGE_VIEWS'
598 :authenticated => false
600 end).should_not raise_error
603 it 'should fail when validating parameters with invalid values' do
605 CLIENT.generate_request(
606 :api_method => @adsense.reports.generate,
608 'startDate' => '2000-01-01',
609 'endDate' => '2010-01-01',
610 'dimension' => 'BAD_CHARACTERS=-&*(£&',
611 'metric' => 'PAGE_VIEWS'
613 :authenticated => false
615 end).should raise_error(ArgumentError)
618 it 'should succeed when validating repeated parameters in a correct call' do
620 CLIENT.generate_request(
621 :api_method => @adsense.reports.generate,
623 'startDate' => '2000-01-01',
624 'endDate' => '2010-01-01',
625 'dimension' => ['DATE', 'PRODUCT_CODE'],
626 'metric' => ['PAGE_VIEWS', 'CLICKS']
628 :authenticated => false
630 end).should_not raise_error
633 it 'should fail when validating incorrect repeated parameters' do
635 CLIENT.generate_request(
636 :api_method => @adsense.reports.generate,
638 'startDate' => '2000-01-01',
639 'endDate' => '2010-01-01',
640 'dimension' => ['DATE', 'BAD_CHARACTERS=-&*(£&'],
641 'metric' => ['PAGE_VIEWS', 'CLICKS']
643 :authenticated => false
645 end).should raise_error(ArgumentError)
649 describe 'with the Drive API' do
651 CLIENT.authorization = nil
652 @drive = CLIENT.discovered_api('drive', 'v1')
655 it 'should include media upload info methods' do
656 @drive.files.insert.media_upload.should_not == nil
659 it 'should include accepted media types' do
660 @drive.files.insert.media_upload.accepted_types.should_not be_empty
663 it 'should have an upload path' do
664 @drive.files.insert.media_upload.uri_template.should_not == nil
667 it 'should have a max file size' do
668 @drive.files.insert.media_upload.max_size.should_not == nil