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.
20 gem 'faraday', '~> 0.8.1'
22 require 'faraday/utils'
25 gem 'signet', '~> 0.4.0'
26 require 'signet/oauth_1/client'
28 require 'google/api_client'
29 require 'google/api_client/version'
31 describe Google::APIClient do
33 @client = Google::APIClient.new
36 it 'should raise a type error for bogus authorization' do
38 Google::APIClient.new(:authorization => 42)
39 end).should raise_error(TypeError)
42 it 'should not be able to retrieve the discovery document for a bogus API' do
44 @client.discovery_document('bogus')
45 end).should raise_error(Google::APIClient::TransmissionError)
47 @client.discovered_api('bogus')
48 end).should raise_error(Google::APIClient::TransmissionError)
51 it 'should raise an error for bogus services' do
53 @client.discovered_api(42)
54 end).should raise_error(TypeError)
57 it 'should raise an error for bogus services' do
59 @client.preferred_version(42)
60 end).should raise_error(TypeError)
63 it 'should raise an error for bogus methods' do
65 @client.generate_request(42)
66 end).should raise_error(TypeError)
69 it 'should not return a preferred version for bogus service names' do
70 @client.preferred_version('bogus').should == nil
73 describe 'with the prediction API' do
75 @client.authorization = nil
76 # The prediction API no longer exposes a v1, so we have to be
77 # careful about looking up the wrong API version.
78 @prediction = @client.discovered_api('prediction', 'v1.2')
81 it 'should correctly determine the discovery URI' do
82 @client.discovery_uri('prediction').should ===
83 'https://www.googleapis.com/discovery/v1/apis/prediction/v1/rest'
86 it 'should correctly determine the discovery URI if :user_ip is set' do
87 @client.user_ip = '127.0.0.1'
88 request = @client.generate_request(
89 :http_method => 'GET',
90 :uri => @client.discovery_uri('prediction', 'v1.2'),
91 :authenticated => false
93 request.to_env(Faraday.default_connection)[:url].to_s.should === (
94 'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
99 it 'should correctly determine the discovery URI if :key is set' do
100 @client.key = 'qwerty'
101 request = @client.generate_request(
102 :http_method => 'GET',
103 :uri => @client.discovery_uri('prediction', 'v1.2'),
104 :authenticated => false
106 request.to_env(Faraday.default_connection)[:url].to_s.should === (
107 'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
112 it 'should correctly determine the discovery URI if both are set' do
113 @client.key = 'qwerty'
114 @client.user_ip = '127.0.0.1'
115 request = @client.generate_request(
116 :http_method => 'GET',
117 :uri => @client.discovery_uri('prediction', 'v1.2'),
118 :authenticated => false
120 Addressable::URI.parse(
121 request.to_env(Faraday.default_connection)[:url]
122 ).query_values.should == {
124 'userIp' => '127.0.0.1'
128 it 'should correctly generate API objects' do
129 @client.discovered_api('prediction', 'v1.2').name.should == 'prediction'
130 @client.discovered_api('prediction', 'v1.2').version.should == 'v1.2'
131 @client.discovered_api(:prediction, 'v1.2').name.should == 'prediction'
132 @client.discovered_api(:prediction, 'v1.2').version.should == 'v1.2'
135 it 'should discover methods' do
136 @client.discovered_method(
137 'prediction.training.insert', 'prediction', 'v1.2'
138 ).name.should == 'insert'
139 @client.discovered_method(
140 :'prediction.training.insert', :prediction, 'v1.2'
141 ).name.should == 'insert'
142 @client.discovered_method(
143 'prediction.training.delete', 'prediction', 'v1.2'
144 ).name.should == 'delete'
147 it 'should define the origin API in discovered methods' do
148 @client.discovered_method(
149 'prediction.training.insert', 'prediction', 'v1.2'
150 ).api.name.should == 'prediction'
153 it 'should not find methods that are not in the discovery document' do
154 @client.discovered_method(
155 'prediction.bogus', 'prediction', 'v1.2'
159 it 'should raise an error for bogus methods' do
161 @client.discovered_method(42, 'prediction', 'v1.2')
162 end).should raise_error(TypeError)
165 it 'should raise an error for bogus methods' do
167 @client.generate_request(@client.discovered_api('prediction', 'v1.2'))
168 end).should raise_error(TypeError)
171 it 'should correctly determine the preferred version' do
172 @client.preferred_version('prediction').version.should_not == 'v1'
173 @client.preferred_version(:prediction).version.should_not == 'v1'
176 it 'should return a batch path' do
177 @client.discovered_api('prediction', 'v1.2').batch_path.should_not be_nil
180 it 'should generate valid requests' do
181 request = @client.generate_request(
182 :api_method => @prediction.training.insert,
183 :parameters => {'data' => '12345'}
185 request.method.should == :post
186 request.to_env(Faraday.default_connection)[:url].to_s.should ===
187 'https://www.googleapis.com/prediction/v1.2/training?data=12345'
188 request.headers.should be_empty
189 request.body.should == ''
192 it 'should generate valid requests when repeated parameters are passed' do
193 request = @client.generate_request(
194 :api_method => @prediction.training.insert,
195 :parameters => [['data', '1'], ['data','2']]
197 request.method.should == :post
198 request.to_env(Faraday.default_connection)[:url].to_s.should ===
199 'https://www.googleapis.com/prediction/v1.2/training?data=1&data=2'
202 it 'should generate requests against the correct URIs' do
203 request = @client.generate_request(
204 :api_method => @prediction.training.insert,
205 :parameters => {'data' => '12345'}
207 request.to_env(Faraday.default_connection)[:url].to_s.should ===
208 'https://www.googleapis.com/prediction/v1.2/training?data=12345'
211 it 'should generate requests against the correct URIs' do
212 request = @client.generate_request(
213 :api_method => @prediction.training.insert,
214 :parameters => {'data' => '12345'}
216 request.to_env(Faraday.default_connection)[:url].to_s.should ===
217 'https://www.googleapis.com/prediction/v1.2/training?data=12345'
220 it 'should allow modification to the base URIs for testing purposes' do
221 prediction = @client.discovered_api('prediction', 'v1.2')
222 prediction.method_base =
223 'https://testing-domain.googleapis.com/prediction/v1.2/'
224 request = @client.generate_request(
225 :api_method => prediction.training.insert,
226 :parameters => {'data' => '123'}
228 request.to_env(Faraday.default_connection)[:url].to_s.should === (
229 'https://testing-domain.googleapis.com/' +
230 'prediction/v1.2/training?data=123'
234 it 'should generate OAuth 1 requests' do
235 @client.authorization = :oauth_1
236 @client.authorization.token_credential_key = '12345'
237 @client.authorization.token_credential_secret = '12345'
238 request = @client.generate_request(
239 :api_method => @prediction.training.insert,
240 :parameters => {'data' => '12345'}
242 request.headers.should have_key('Authorization')
243 request.headers['Authorization'].should =~ /^OAuth/
246 it 'should generate OAuth 2 requests' do
247 @client.authorization = :oauth_2
248 @client.authorization.access_token = '12345'
249 request = @client.generate_request(
250 :api_method => @prediction.training.insert,
251 :parameters => {'data' => '12345'}
253 request.headers.should have_key('Authorization')
254 request.headers['Authorization'].should =~ /^Bearer/
257 it 'should not be able to execute improperly authorized requests' do
258 @client.authorization = :oauth_1
259 @client.authorization.token_credential_key = '12345'
260 @client.authorization.token_credential_secret = '12345'
261 result = @client.execute(
262 @prediction.training.insert,
265 result.response.status.should == 401
268 it 'should not be able to execute improperly authorized requests' do
269 @client.authorization = :oauth_2
270 @client.authorization.access_token = '12345'
271 result = @client.execute(
272 @prediction.training.insert,
275 result.response.status.should == 401
278 it 'should not be able to execute improperly authorized requests' do
280 @client.authorization = :oauth_1
281 @client.authorization.token_credential_key = '12345'
282 @client.authorization.token_credential_secret = '12345'
283 result = @client.execute!(
284 @prediction.training.insert,
287 end).should raise_error(Google::APIClient::ClientError)
290 it 'should not be able to execute improperly authorized requests' do
292 @client.authorization = :oauth_2
293 @client.authorization.access_token = '12345'
294 result = @client.execute!(
295 @prediction.training.insert,
298 end).should raise_error(Google::APIClient::ClientError)
301 it 'should correctly handle unnamed parameters' do
302 @client.authorization = :oauth_2
303 @client.authorization.access_token = '12345'
304 result = @client.execute(
305 @prediction.training.insert,
307 MultiJson.dump({"id" => "bucket/object"}),
308 {'Content-Type' => 'application/json'}
310 result.request.headers['Content-Type'].should == 'application/json'
314 describe 'with the plus API' do
316 @client.authorization = nil
317 @plus = @client.discovered_api('plus')
320 it 'should correctly determine the discovery URI' do
321 @client.discovery_uri('plus').should ===
322 'https://www.googleapis.com/discovery/v1/apis/plus/v1/rest'
325 it 'should find APIs that are in the discovery document' do
326 @client.discovered_api('plus').name.should == 'plus'
327 @client.discovered_api('plus').version.should == 'v1'
328 @client.discovered_api(:plus).name.should == 'plus'
329 @client.discovered_api(:plus).version.should == 'v1'
332 it 'should find methods that are in the discovery document' do
333 # TODO(bobaman) Fix this when the RPC names are correct
334 @client.discovered_method(
335 'plus.activities.list', 'plus'
336 ).name.should == 'list'
339 it 'should define the origin API in discovered methods' do
340 @client.discovered_method(
341 'plus.activities.list', 'plus'
342 ).api.name.should == 'plus'
345 it 'should not find methods that are not in the discovery document' do
346 @client.discovered_method('plus.bogus', 'plus').should == nil
349 it 'should generate requests against the correct URIs' do
350 request = @client.generate_request(
351 :api_method => @plus.activities.list,
353 'userId' => '107807692475771887386', 'collection' => 'public'
355 :authenticated => false
357 request.to_env(Faraday.default_connection)[:url].to_s.should === (
358 'https://www.googleapis.com/plus/v1/' +
359 'people/107807692475771887386/activities/public'
363 it 'should correctly validate parameters' do
365 @client.generate_request(
366 :api_method => @plus.activities.list,
367 :parameters => {'alt' => 'json'},
368 :authenticated => false
370 end).should raise_error(ArgumentError)
373 it 'should correctly validate parameters' do
375 @client.generate_request(
376 :api_method => @plus.activities.list,
378 'userId' => '107807692475771887386', 'collection' => 'bogus'
380 :authenticated => false
382 end).should raise_error(ArgumentError)
386 describe 'with the latitude API' do
388 @client.authorization = nil
389 @latitude = @client.discovered_api('latitude')
392 it 'should correctly determine the discovery URI' do
393 @client.discovery_uri('latitude').should ===
394 'https://www.googleapis.com/discovery/v1/apis/latitude/v1/rest'
397 it 'should find APIs that are in the discovery document' do
398 @client.discovered_api('latitude').name.should == 'latitude'
399 @client.discovered_api('latitude').version.should == 'v1'
402 it 'should return a batch path' do
403 @client.discovered_api('latitude').batch_path.should_not be_nil
406 it 'should find methods that are in the discovery document' do
407 @client.discovered_method(
408 'latitude.currentLocation.get', 'latitude'
409 ).name.should == 'get'
412 it 'should define the origin API in discovered methods' do
413 @client.discovered_method(
414 'latitude.currentLocation.get', 'latitude'
415 ).api.name.should == 'latitude'
418 it 'should not find methods that are not in the discovery document' do
419 @client.discovered_method('latitude.bogus', 'latitude').should == nil
422 it 'should generate requests against the correct URIs' do
423 request = @client.generate_request(
424 :api_method => 'latitude.currentLocation.get',
425 :authenticated => false
427 request.to_env(Faraday.default_connection)[:url].to_s.should ===
428 'https://www.googleapis.com/latitude/v1/currentLocation'
431 it 'should generate requests against the correct URIs' do
432 request = @client.generate_request(
433 :api_method => @latitude.current_location.get,
434 :authenticated => false
436 request.to_env(Faraday.default_connection)[:url].to_s.should ===
437 'https://www.googleapis.com/latitude/v1/currentLocation'
440 it 'should not be able to execute requests without authorization' do
441 result = @client.execute(
442 :api_method => 'latitude.currentLocation.get',
443 :authenticated => false
445 result.response.status.should == 401
449 describe 'with the moderator API' do
451 @client.authorization = nil
452 @moderator = @client.discovered_api('moderator')
455 it 'should correctly determine the discovery URI' do
456 @client.discovery_uri('moderator').should ===
457 'https://www.googleapis.com/discovery/v1/apis/moderator/v1/rest'
460 it 'should find APIs that are in the discovery document' do
461 @client.discovered_api('moderator').name.should == 'moderator'
462 @client.discovered_api('moderator').version.should == 'v1'
465 it 'should find methods that are in the discovery document' do
466 @client.discovered_method(
467 'moderator.profiles.get', 'moderator'
468 ).name.should == 'get'
471 it 'should define the origin API in discovered methods' do
472 @client.discovered_method(
473 'moderator.profiles.get', 'moderator'
474 ).api.name.should == 'moderator'
477 it 'should not find methods that are not in the discovery document' do
478 @client.discovered_method('moderator.bogus', 'moderator').should == nil
481 it 'should return a batch path' do
482 @client.discovered_api('moderator').batch_path.should_not be_nil
485 it 'should generate requests against the correct URIs' do
486 request = @client.generate_request(
487 :api_method => 'moderator.profiles.get',
488 :authenticated => false
490 request.to_env(Faraday.default_connection)[:url].to_s.should ===
491 'https://www.googleapis.com/moderator/v1/profiles/@me'
494 it 'should generate requests against the correct URIs' do
495 request = @client.generate_request(
496 :api_method => @moderator.profiles.get,
497 :authenticated => false
499 request.to_env(Faraday.default_connection)[:url].to_s.should ===
500 'https://www.googleapis.com/moderator/v1/profiles/@me'
503 it 'should not be able to execute requests without authorization' do
504 result = @client.execute(
505 'moderator.profiles.get',
509 {:authenticated => false}
511 result.response.status.should == 401
515 describe 'with the adsense API' do
517 @client.authorization = nil
518 @adsense = @client.discovered_api('adsense', 'v1')
521 it 'should correctly determine the discovery URI' do
522 @client.discovery_uri('adsense').should ===
523 'https://www.googleapis.com/discovery/v1/apis/adsense/v1/rest'
526 it 'should find APIs that are in the discovery document' do
527 @client.discovered_api('adsense').name.should == 'adsense'
528 @client.discovered_api('adsense').version.should == 'v1'
531 it 'should return a batch path' do
532 @client.discovered_api('adsense').batch_path.should_not be_nil
535 it 'should find methods that are in the discovery document' do
536 @client.discovered_method(
537 'adsense.reports.generate', 'adsense'
538 ).name.should == 'generate'
541 it 'should not find methods that are not in the discovery document' do
542 @client.discovered_method('adsense.bogus', 'adsense').should == nil
545 it 'should generate requests against the correct URIs' do
546 request = @client.generate_request(
547 :api_method => 'adsense.adclients.list',
548 :authenticated => false
550 request.to_env(Faraday.default_connection)[:url].to_s.should ===
551 'https://www.googleapis.com/adsense/v1/adclients'
554 it 'should generate requests against the correct URIs' do
555 request = @client.generate_request(
556 :api_method => @adsense.adclients.list,
557 :authenticated => false
559 request.to_env(Faraday.default_connection)[:url].to_s.should ===
560 'https://www.googleapis.com/adsense/v1/adclients'
563 it 'should not be able to execute requests without authorization' do
564 result = @client.execute(
565 :api_method => 'adsense.adclients.list',
566 :authenticated => false
568 result.response.status.should == 401
571 it 'should fail when validating missing required parameters' do
573 @client.generate_request(
574 :api_method => @adsense.reports.generate,
575 :authenticated => false
577 end).should raise_error(ArgumentError)
580 it 'should succeed when validating parameters in a correct call' do
582 @client.generate_request(
583 :api_method => @adsense.reports.generate,
585 'startDate' => '2000-01-01',
586 'endDate' => '2010-01-01',
587 'dimension' => 'DATE',
588 'metric' => 'PAGE_VIEWS'
590 :authenticated => false
592 end).should_not raise_error
595 it 'should fail when validating parameters with invalid values' do
597 @client.generate_request(
598 :api_method => @adsense.reports.generate,
600 'startDate' => '2000-01-01',
601 'endDate' => '2010-01-01',
602 'dimension' => 'BAD_CHARACTERS=-&*(£&',
603 'metric' => 'PAGE_VIEWS'
605 :authenticated => false
607 end).should raise_error(ArgumentError)
610 it 'should succeed when validating repeated parameters in a correct call' do
612 @client.generate_request(
613 :api_method => @adsense.reports.generate,
615 'startDate' => '2000-01-01',
616 'endDate' => '2010-01-01',
617 'dimension' => ['DATE', 'PRODUCT_CODE'],
618 'metric' => ['PAGE_VIEWS', 'CLICKS']
620 :authenticated => false
622 end).should_not raise_error
625 it 'should fail when validating incorrect repeated parameters' do
627 @client.generate_request(
628 :api_method => @adsense.reports.generate,
630 'startDate' => '2000-01-01',
631 'endDate' => '2010-01-01',
632 'dimension' => ['DATE', 'BAD_CHARACTERS=-&*(£&'],
633 'metric' => ['PAGE_VIEWS', 'CLICKS']
635 :authenticated => false
637 end).should raise_error(ArgumentError)
641 describe 'with the Drive API' do
643 @client.authorization = nil
644 @drive = @client.discovered_api('drive', 'v1')
647 it 'should include media upload info methods' do
648 @drive.files.insert.media_upload.should_not == nil
651 it 'should include accepted media types' do
652 @drive.files.insert.media_upload.accepted_types.should_not be_empty
655 it 'should have an upload path' do
656 @drive.files.insert.media_upload.uri_template.should_not == nil
659 it 'should have a max file size' do
660 @drive.files.insert.media_upload.max_size.should_not == nil