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_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 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.method.should == :post
200 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_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_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_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 request.headers.should have_key('Authorization')
247 request.headers['Authorization'].should =~ /^OAuth/
250 it 'should generate OAuth 2 requests' do
251 CLIENT.authorization = :oauth_2
252 CLIENT.authorization.access_token = '12345'
253 request = CLIENT.generate_request(
254 :api_method => @prediction.training.insert,
255 :parameters => {'data' => '12345'}
257 request.headers.should have_key('Authorization')
258 request.headers['Authorization'].should =~ /^Bearer/
261 it 'should not be able to execute improperly authorized requests' do
262 CLIENT.authorization = :oauth_1
263 CLIENT.authorization.token_credential_key = '12345'
264 CLIENT.authorization.token_credential_secret = '12345'
265 result = CLIENT.execute(
266 @prediction.training.insert,
269 result.response.status.should == 401
272 it 'should not be able to execute improperly authorized requests' do
273 CLIENT.authorization = :oauth_2
274 CLIENT.authorization.access_token = '12345'
275 result = CLIENT.execute(
276 @prediction.training.insert,
279 result.response.status.should == 401
282 it 'should not be able to execute improperly authorized requests' do
284 CLIENT.authorization = :oauth_1
285 CLIENT.authorization.token_credential_key = '12345'
286 CLIENT.authorization.token_credential_secret = '12345'
287 result = CLIENT.execute!(
288 @prediction.training.insert,
291 end).should raise_error(Google::APIClient::ClientError)
294 it 'should not be able to execute improperly authorized requests' do
296 CLIENT.authorization = :oauth_2
297 CLIENT.authorization.access_token = '12345'
298 result = CLIENT.execute!(
299 @prediction.training.insert,
302 end).should raise_error(Google::APIClient::ClientError)
305 it 'should correctly handle unnamed parameters' do
306 CLIENT.authorization = :oauth_2
307 CLIENT.authorization.access_token = '12345'
308 result = CLIENT.execute(
309 @prediction.training.insert,
311 MultiJson.dump({"id" => "bucket/object"}),
312 {'Content-Type' => 'application/json'}
314 result.request.headers['Content-Type'].should == 'application/json'
318 describe 'with the plus API' do
320 CLIENT.authorization = nil
321 @plus = CLIENT.discovered_api('plus')
324 it 'should correctly determine the discovery URI' do
325 CLIENT.discovery_uri('plus').should ===
326 'https://www.googleapis.com/discovery/v1/apis/plus/v1/rest'
329 it 'should find APIs that are in the discovery document' do
330 CLIENT.discovered_api('plus').name.should == 'plus'
331 CLIENT.discovered_api('plus').version.should == 'v1'
332 CLIENT.discovered_api(:plus).name.should == 'plus'
333 CLIENT.discovered_api(:plus).version.should == 'v1'
336 it 'should find methods that are in the discovery document' do
337 # TODO(bobaman) Fix this when the RPC names are correct
338 CLIENT.discovered_method(
339 'plus.activities.list', 'plus'
340 ).name.should == 'list'
343 it 'should define the origin API in discovered methods' do
344 CLIENT.discovered_method(
345 'plus.activities.list', 'plus'
346 ).api.name.should == 'plus'
349 it 'should not find methods that are not in the discovery document' do
350 CLIENT.discovered_method('plus.bogus', 'plus').should == nil
353 it 'should generate requests against the correct URIs' do
354 request = CLIENT.generate_request(
355 :api_method => @plus.activities.list,
357 'userId' => '107807692475771887386', 'collection' => 'public'
359 :authenticated => false
361 request.to_env(Faraday.default_connection)[:url].to_s.should === (
362 'https://www.googleapis.com/plus/v1/' +
363 'people/107807692475771887386/activities/public'
367 it 'should correctly validate parameters' do
369 CLIENT.generate_request(
370 :api_method => @plus.activities.list,
371 :parameters => {'alt' => 'json'},
372 :authenticated => false
374 end).should raise_error(ArgumentError)
377 it 'should correctly validate parameters' do
379 CLIENT.generate_request(
380 :api_method => @plus.activities.list,
382 'userId' => '107807692475771887386', 'collection' => 'bogus'
384 :authenticated => false
386 end).should raise_error(ArgumentError)
391 describe 'with the latitude API' do
393 CLIENT.authorization = nil
394 @latitude = CLIENT.discovered_api('latitude')
397 it 'should correctly determine the discovery URI' do
398 CLIENT.discovery_uri('latitude').should ===
399 'https://www.googleapis.com/discovery/v1/apis/latitude/v1/rest'
402 it 'should find APIs that are in the discovery document' do
403 CLIENT.discovered_api('latitude').name.should == 'latitude'
404 CLIENT.discovered_api('latitude').version.should == 'v1'
407 it 'should return a batch path' do
408 CLIENT.discovered_api('latitude').batch_path.should_not be_nil
411 it 'should find methods that are in the discovery document' do
412 CLIENT.discovered_method(
413 'latitude.currentLocation.get', 'latitude'
414 ).name.should == 'get'
417 it 'should define the origin API in discovered methods' do
418 CLIENT.discovered_method(
419 'latitude.currentLocation.get', 'latitude'
420 ).api.name.should == 'latitude'
423 it 'should not find methods that are not in the discovery document' do
424 CLIENT.discovered_method('latitude.bogus', 'latitude').should == nil
427 it 'should generate requests against the correct URIs' do
428 request = CLIENT.generate_request(
429 :api_method => 'latitude.currentLocation.get',
430 :authenticated => false
432 request.to_env(Faraday.default_connection)[:url].to_s.should ===
433 'https://www.googleapis.com/latitude/v1/currentLocation'
436 it 'should generate requests against the correct URIs' do
437 request = CLIENT.generate_request(
438 :api_method => @latitude.current_location.get,
439 :authenticated => false
441 request.to_env(Faraday.default_connection)[:url].to_s.should ===
442 'https://www.googleapis.com/latitude/v1/currentLocation'
445 it 'should not be able to execute requests without authorization' do
446 result = CLIENT.execute(
447 :api_method => 'latitude.currentLocation.get',
448 :authenticated => false
450 result.response.status.should == 401
455 describe 'with the moderator API' do
457 CLIENT.authorization = nil
458 @moderator = CLIENT.discovered_api('moderator')
461 it 'should correctly determine the discovery URI' do
462 CLIENT.discovery_uri('moderator').should ===
463 'https://www.googleapis.com/discovery/v1/apis/moderator/v1/rest'
466 it 'should find APIs that are in the discovery document' do
467 CLIENT.discovered_api('moderator').name.should == 'moderator'
468 CLIENT.discovered_api('moderator').version.should == 'v1'
471 it 'should find methods that are in the discovery document' do
472 CLIENT.discovered_method(
473 'moderator.profiles.get', 'moderator'
474 ).name.should == 'get'
477 it 'should define the origin API in discovered methods' do
478 CLIENT.discovered_method(
479 'moderator.profiles.get', 'moderator'
480 ).api.name.should == 'moderator'
483 it 'should not find methods that are not in the discovery document' do
484 CLIENT.discovered_method('moderator.bogus', 'moderator').should == nil
487 it 'should return a batch path' do
488 CLIENT.discovered_api('moderator').batch_path.should_not be_nil
491 it 'should generate requests against the correct URIs' do
492 request = CLIENT.generate_request(
493 :api_method => 'moderator.profiles.get',
494 :authenticated => false
496 request.to_env(Faraday.default_connection)[:url].to_s.should ===
497 'https://www.googleapis.com/moderator/v1/profiles/@me'
500 it 'should generate requests against the correct URIs' do
501 request = CLIENT.generate_request(
502 :api_method => @moderator.profiles.get,
503 :authenticated => false
505 request.to_env(Faraday.default_connection)[:url].to_s.should ===
506 'https://www.googleapis.com/moderator/v1/profiles/@me'
509 it 'should not be able to execute requests without authorization' do
510 result = CLIENT.execute(
511 'moderator.profiles.get',
515 {:authenticated => false}
517 result.response.status.should == 401
521 describe 'with the adsense API' do
523 CLIENT.authorization = nil
524 @adsense = CLIENT.discovered_api('adsense', 'v1')
527 it 'should correctly determine the discovery URI' do
528 CLIENT.discovery_uri('adsense').should ===
529 'https://www.googleapis.com/discovery/v1/apis/adsense/v1/rest'
532 it 'should find APIs that are in the discovery document' do
533 CLIENT.discovered_api('adsense').name.should == 'adsense'
534 CLIENT.discovered_api('adsense').version.should == 'v1'
537 it 'should return a batch path' do
538 CLIENT.discovered_api('adsense').batch_path.should_not be_nil
541 it 'should find methods that are in the discovery document' do
542 CLIENT.discovered_method(
543 'adsense.reports.generate', 'adsense'
544 ).name.should == 'generate'
547 it 'should not find methods that are not in the discovery document' do
548 CLIENT.discovered_method('adsense.bogus', 'adsense').should == nil
551 it 'should generate requests against the correct URIs' do
552 request = CLIENT.generate_request(
553 :api_method => 'adsense.adclients.list',
554 :authenticated => false
556 request.to_env(Faraday.default_connection)[:url].to_s.should ===
557 'https://www.googleapis.com/adsense/v1/adclients'
560 it 'should generate requests against the correct URIs' do
561 request = CLIENT.generate_request(
562 :api_method => @adsense.adclients.list,
563 :authenticated => false
565 request.to_env(Faraday.default_connection)[:url].to_s.should ===
566 'https://www.googleapis.com/adsense/v1/adclients'
569 it 'should not be able to execute requests without authorization' do
570 result = CLIENT.execute(
571 :api_method => 'adsense.adclients.list',
572 :authenticated => false
574 result.response.status.should == 401
577 it 'should fail when validating missing required parameters' do
579 CLIENT.generate_request(
580 :api_method => @adsense.reports.generate,
581 :authenticated => false
583 end).should raise_error(ArgumentError)
586 it 'should succeed when validating parameters in a correct call' do
588 CLIENT.generate_request(
589 :api_method => @adsense.reports.generate,
591 'startDate' => '2000-01-01',
592 'endDate' => '2010-01-01',
593 'dimension' => 'DATE',
594 'metric' => 'PAGE_VIEWS'
596 :authenticated => false
598 end).should_not raise_error
601 it 'should fail when validating parameters with invalid values' do
603 CLIENT.generate_request(
604 :api_method => @adsense.reports.generate,
606 'startDate' => '2000-01-01',
607 'endDate' => '2010-01-01',
608 'dimension' => 'BAD_CHARACTERS=-&*(£&',
609 'metric' => 'PAGE_VIEWS'
611 :authenticated => false
613 end).should raise_error(ArgumentError)
616 it 'should succeed when validating repeated parameters in a correct call' do
618 CLIENT.generate_request(
619 :api_method => @adsense.reports.generate,
621 'startDate' => '2000-01-01',
622 'endDate' => '2010-01-01',
623 'dimension' => ['DATE', 'PRODUCT_CODE'],
624 'metric' => ['PAGE_VIEWS', 'CLICKS']
626 :authenticated => false
628 end).should_not raise_error
631 it 'should fail when validating incorrect repeated parameters' do
633 CLIENT.generate_request(
634 :api_method => @adsense.reports.generate,
636 'startDate' => '2000-01-01',
637 'endDate' => '2010-01-01',
638 'dimension' => ['DATE', 'BAD_CHARACTERS=-&*(£&'],
639 'metric' => ['PAGE_VIEWS', 'CLICKS']
641 :authenticated => false
643 end).should raise_error(ArgumentError)
647 describe 'with the Drive API' do
649 CLIENT.authorization = nil
650 @drive = CLIENT.discovered_api('drive', 'v1')
653 it 'should include media upload info methods' do
654 @drive.files.insert.media_upload.should_not == nil
657 it 'should include accepted media types' do
658 @drive.files.insert.media_upload.accepted_types.should_not be_empty
661 it 'should have an upload path' do
662 @drive.files.insert.media_upload.uri_template.should_not == nil
665 it 'should have a max file size' do
666 @drive.files.insert.media_upload.max_size.should_not == nil