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
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_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_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_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.method.should == :post
187 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 request = CLIENT.generate_request(
195 :api_method => @prediction.training.insert,
196 :parameters => [['data', '1'], ['data','2']]
198 request.method.should == :post
199 request.to_env(Faraday.default_connection)[:url].to_s.should ===
200 'https://www.googleapis.com/prediction/v1.2/training?data=1&data=2'
203 it 'should generate requests against the correct URIs' do
204 request = CLIENT.generate_request(
205 :api_method => @prediction.training.insert,
206 :parameters => {'data' => '12345'}
208 request.to_env(Faraday.default_connection)[:url].to_s.should ===
209 'https://www.googleapis.com/prediction/v1.2/training?data=12345'
212 it 'should generate requests against the correct URIs' do
213 request = CLIENT.generate_request(
214 :api_method => @prediction.training.insert,
215 :parameters => {'data' => '12345'}
217 request.to_env(Faraday.default_connection)[:url].to_s.should ===
218 'https://www.googleapis.com/prediction/v1.2/training?data=12345'
221 it 'should allow modification to the base URIs for testing purposes' do
222 # Using a new client instance here to avoid caching rebased discovery doc
224 Google::APIClient.new.discovered_api('prediction', 'v1.2')
225 prediction_rebase.method_base =
226 'https://testing-domain.example.com/prediction/v1.2/'
227 request = CLIENT.generate_request(
228 :api_method => prediction_rebase.training.insert,
229 :parameters => {'data' => '123'}
231 request.to_env(Faraday.default_connection)[:url].to_s.should === (
232 'https://testing-domain.example.com/' +
233 'prediction/v1.2/training?data=123'
237 it 'should generate OAuth 1 requests' do
238 CLIENT.authorization = :oauth_1
239 CLIENT.authorization.token_credential_key = '12345'
240 CLIENT.authorization.token_credential_secret = '12345'
241 request = CLIENT.generate_request(
242 :api_method => @prediction.training.insert,
243 :parameters => {'data' => '12345'}
245 request.headers.should have_key('Authorization')
246 request.headers['Authorization'].should =~ /^OAuth/
249 it 'should generate OAuth 2 requests' do
250 CLIENT.authorization = :oauth_2
251 CLIENT.authorization.access_token = '12345'
252 request = CLIENT.generate_request(
253 :api_method => @prediction.training.insert,
254 :parameters => {'data' => '12345'}
256 request.headers.should have_key('Authorization')
257 request.headers['Authorization'].should =~ /^Bearer/
260 it 'should not be able to execute improperly authorized requests' do
261 CLIENT.authorization = :oauth_1
262 CLIENT.authorization.token_credential_key = '12345'
263 CLIENT.authorization.token_credential_secret = '12345'
264 result = CLIENT.execute(
265 @prediction.training.insert,
268 result.response.status.should == 401
271 it 'should not be able to execute improperly authorized requests' do
272 CLIENT.authorization = :oauth_2
273 CLIENT.authorization.access_token = '12345'
274 result = CLIENT.execute(
275 @prediction.training.insert,
278 result.response.status.should == 401
281 it 'should not be able to execute improperly authorized requests' do
283 CLIENT.authorization = :oauth_1
284 CLIENT.authorization.token_credential_key = '12345'
285 CLIENT.authorization.token_credential_secret = '12345'
286 result = CLIENT.execute!(
287 @prediction.training.insert,
290 end).should raise_error(Google::APIClient::ClientError)
293 it 'should not be able to execute improperly authorized requests' do
295 CLIENT.authorization = :oauth_2
296 CLIENT.authorization.access_token = '12345'
297 result = CLIENT.execute!(
298 @prediction.training.insert,
301 end).should raise_error(Google::APIClient::ClientError)
304 it 'should correctly handle unnamed parameters' do
305 CLIENT.authorization = :oauth_2
306 CLIENT.authorization.access_token = '12345'
307 result = CLIENT.execute(
308 @prediction.training.insert,
310 MultiJson.dump({"id" => "bucket/object"}),
311 {'Content-Type' => 'application/json'}
313 result.request.headers['Content-Type'].should == 'application/json'
317 describe 'with the plus API' do
319 CLIENT.authorization = nil
320 @plus = CLIENT.discovered_api('plus')
323 it 'should correctly determine the discovery URI' do
324 CLIENT.discovery_uri('plus').should ===
325 'https://www.googleapis.com/discovery/v1/apis/plus/v1/rest'
328 it 'should find APIs that are in the discovery document' do
329 CLIENT.discovered_api('plus').name.should == 'plus'
330 CLIENT.discovered_api('plus').version.should == 'v1'
331 CLIENT.discovered_api(:plus).name.should == 'plus'
332 CLIENT.discovered_api(:plus).version.should == 'v1'
335 it 'should find methods that are in the discovery document' do
336 # TODO(bobaman) Fix this when the RPC names are correct
337 CLIENT.discovered_method(
338 'plus.activities.list', 'plus'
339 ).name.should == 'list'
342 it 'should define the origin API in discovered methods' do
343 CLIENT.discovered_method(
344 'plus.activities.list', 'plus'
345 ).api.name.should == 'plus'
348 it 'should not find methods that are not in the discovery document' do
349 CLIENT.discovered_method('plus.bogus', 'plus').should == nil
352 it 'should generate requests against the correct URIs' do
353 request = CLIENT.generate_request(
354 :api_method => @plus.activities.list,
356 'userId' => '107807692475771887386', 'collection' => 'public'
358 :authenticated => false
360 request.to_env(Faraday.default_connection)[:url].to_s.should === (
361 'https://www.googleapis.com/plus/v1/' +
362 'people/107807692475771887386/activities/public'
366 it 'should correctly validate parameters' do
368 CLIENT.generate_request(
369 :api_method => @plus.activities.list,
370 :parameters => {'alt' => 'json'},
371 :authenticated => false
373 end).should raise_error(ArgumentError)
376 it 'should correctly validate parameters' do
378 CLIENT.generate_request(
379 :api_method => @plus.activities.list,
381 'userId' => '107807692475771887386', 'collection' => 'bogus'
383 :authenticated => false
385 end).should raise_error(ArgumentError)
390 describe 'with the latitude API' do
392 CLIENT.authorization = nil
393 @latitude = CLIENT.discovered_api('latitude')
396 it 'should correctly determine the discovery URI' do
397 CLIENT.discovery_uri('latitude').should ===
398 'https://www.googleapis.com/discovery/v1/apis/latitude/v1/rest'
401 it 'should find APIs that are in the discovery document' do
402 CLIENT.discovered_api('latitude').name.should == 'latitude'
403 CLIENT.discovered_api('latitude').version.should == 'v1'
406 it 'should return a batch path' do
407 CLIENT.discovered_api('latitude').batch_path.should_not be_nil
410 it 'should find methods that are in the discovery document' do
411 CLIENT.discovered_method(
412 'latitude.currentLocation.get', 'latitude'
413 ).name.should == 'get'
416 it 'should define the origin API in discovered methods' do
417 CLIENT.discovered_method(
418 'latitude.currentLocation.get', 'latitude'
419 ).api.name.should == 'latitude'
422 it 'should not find methods that are not in the discovery document' do
423 CLIENT.discovered_method('latitude.bogus', 'latitude').should == nil
426 it 'should generate requests against the correct URIs' do
427 request = CLIENT.generate_request(
428 :api_method => 'latitude.currentLocation.get',
429 :authenticated => false
431 request.to_env(Faraday.default_connection)[:url].to_s.should ===
432 'https://www.googleapis.com/latitude/v1/currentLocation'
435 it 'should generate requests against the correct URIs' do
436 request = CLIENT.generate_request(
437 :api_method => @latitude.current_location.get,
438 :authenticated => false
440 request.to_env(Faraday.default_connection)[:url].to_s.should ===
441 'https://www.googleapis.com/latitude/v1/currentLocation'
444 it 'should not be able to execute requests without authorization' do
445 result = CLIENT.execute(
446 :api_method => 'latitude.currentLocation.get',
447 :authenticated => false
449 result.response.status.should == 401
454 describe 'with the moderator API' do
456 CLIENT.authorization = nil
457 @moderator = CLIENT.discovered_api('moderator')
460 it 'should correctly determine the discovery URI' do
461 CLIENT.discovery_uri('moderator').should ===
462 'https://www.googleapis.com/discovery/v1/apis/moderator/v1/rest'
465 it 'should find APIs that are in the discovery document' do
466 CLIENT.discovered_api('moderator').name.should == 'moderator'
467 CLIENT.discovered_api('moderator').version.should == 'v1'
470 it 'should find methods that are in the discovery document' do
471 CLIENT.discovered_method(
472 'moderator.profiles.get', 'moderator'
473 ).name.should == 'get'
476 it 'should define the origin API in discovered methods' do
477 CLIENT.discovered_method(
478 'moderator.profiles.get', 'moderator'
479 ).api.name.should == 'moderator'
482 it 'should not find methods that are not in the discovery document' do
483 CLIENT.discovered_method('moderator.bogus', 'moderator').should == nil
486 it 'should return a batch path' do
487 CLIENT.discovered_api('moderator').batch_path.should_not be_nil
490 it 'should generate requests against the correct URIs' do
491 request = CLIENT.generate_request(
492 :api_method => 'moderator.profiles.get',
493 :authenticated => false
495 request.to_env(Faraday.default_connection)[:url].to_s.should ===
496 'https://www.googleapis.com/moderator/v1/profiles/@me'
499 it 'should generate requests against the correct URIs' do
500 request = CLIENT.generate_request(
501 :api_method => @moderator.profiles.get,
502 :authenticated => false
504 request.to_env(Faraday.default_connection)[:url].to_s.should ===
505 'https://www.googleapis.com/moderator/v1/profiles/@me'
508 it 'should not be able to execute requests without authorization' do
509 result = CLIENT.execute(
510 'moderator.profiles.get',
514 {:authenticated => false}
516 result.response.status.should == 401
520 describe 'with the adsense API' do
522 CLIENT.authorization = nil
523 @adsense = CLIENT.discovered_api('adsense', 'v1')
526 it 'should correctly determine the discovery URI' do
527 CLIENT.discovery_uri('adsense').should ===
528 'https://www.googleapis.com/discovery/v1/apis/adsense/v1/rest'
531 it 'should find APIs that are in the discovery document' do
532 CLIENT.discovered_api('adsense').name.should == 'adsense'
533 CLIENT.discovered_api('adsense').version.should == 'v1'
536 it 'should return a batch path' do
537 CLIENT.discovered_api('adsense').batch_path.should_not be_nil
540 it 'should find methods that are in the discovery document' do
541 CLIENT.discovered_method(
542 'adsense.reports.generate', 'adsense'
543 ).name.should == 'generate'
546 it 'should not find methods that are not in the discovery document' do
547 CLIENT.discovered_method('adsense.bogus', 'adsense').should == nil
550 it 'should generate requests against the correct URIs' do
551 request = CLIENT.generate_request(
552 :api_method => 'adsense.adclients.list',
553 :authenticated => false
555 request.to_env(Faraday.default_connection)[:url].to_s.should ===
556 'https://www.googleapis.com/adsense/v1/adclients'
559 it 'should generate requests against the correct URIs' do
560 request = CLIENT.generate_request(
561 :api_method => @adsense.adclients.list,
562 :authenticated => false
564 request.to_env(Faraday.default_connection)[:url].to_s.should ===
565 'https://www.googleapis.com/adsense/v1/adclients'
568 it 'should not be able to execute requests without authorization' do
569 result = CLIENT.execute(
570 :api_method => 'adsense.adclients.list',
571 :authenticated => false
573 result.response.status.should == 401
576 it 'should fail when validating missing required parameters' do
578 CLIENT.generate_request(
579 :api_method => @adsense.reports.generate,
580 :authenticated => false
582 end).should raise_error(ArgumentError)
585 it 'should succeed when validating parameters in a correct call' do
587 CLIENT.generate_request(
588 :api_method => @adsense.reports.generate,
590 'startDate' => '2000-01-01',
591 'endDate' => '2010-01-01',
592 'dimension' => 'DATE',
593 'metric' => 'PAGE_VIEWS'
595 :authenticated => false
597 end).should_not raise_error
600 it 'should fail when validating parameters with invalid values' do
602 CLIENT.generate_request(
603 :api_method => @adsense.reports.generate,
605 'startDate' => '2000-01-01',
606 'endDate' => '2010-01-01',
607 'dimension' => 'BAD_CHARACTERS=-&*(£&',
608 'metric' => 'PAGE_VIEWS'
610 :authenticated => false
612 end).should raise_error(ArgumentError)
615 it 'should succeed when validating repeated parameters in a correct call' do
617 CLIENT.generate_request(
618 :api_method => @adsense.reports.generate,
620 'startDate' => '2000-01-01',
621 'endDate' => '2010-01-01',
622 'dimension' => ['DATE', 'PRODUCT_CODE'],
623 'metric' => ['PAGE_VIEWS', 'CLICKS']
625 :authenticated => false
627 end).should_not raise_error
630 it 'should fail when validating incorrect repeated parameters' do
632 CLIENT.generate_request(
633 :api_method => @adsense.reports.generate,
635 'startDate' => '2000-01-01',
636 'endDate' => '2010-01-01',
637 'dimension' => ['DATE', 'BAD_CHARACTERS=-&*(£&'],
638 'metric' => ['PAGE_VIEWS', 'CLICKS']
640 :authenticated => false
642 end).should raise_error(ArgumentError)
646 describe 'with the Drive API' do
648 CLIENT.authorization = nil
649 @drive = CLIENT.discovered_api('drive', 'v1')
652 it 'should include media upload info methods' do
653 @drive.files.insert.media_upload.should_not == nil
656 it 'should include accepted media types' do
657 @drive.files.insert.media_upload.accepted_types.should_not be_empty
660 it 'should have an upload path' do
661 @drive.files.insert.media_upload.uri_template.should_not == nil
664 it 'should have a max file size' do
665 @drive.files.insert.media_upload.max_size.should_not == nil