Resolving issues introduced by Faraday dependency upgrade.
[arvados.git] / spec / google / api_client / discovery_spec.rb
1 # encoding:utf-8
2
3 # Copyright 2010 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
18 require 'spec_helper'
19
20 gem 'faraday', '~> 0.8.1'
21 require 'faraday'
22 require 'faraday/utils'
23 require 'multi_json'
24
25 gem 'signet', '~> 0.4.0'
26 require 'signet/oauth_1/client'
27
28 require 'google/api_client'
29 require 'google/api_client/version'
30
31 describe Google::APIClient do
32   before do
33     @client = Google::APIClient.new
34   end
35
36   it 'should raise a type error for bogus authorization' do
37     (lambda do
38       Google::APIClient.new(:authorization => 42)
39     end).should raise_error(TypeError)
40   end
41
42   it 'should not be able to retrieve the discovery document for a bogus API' do
43     (lambda do
44       @client.discovery_document('bogus')
45     end).should raise_error(Google::APIClient::TransmissionError)
46     (lambda do
47       @client.discovered_api('bogus')
48     end).should raise_error(Google::APIClient::TransmissionError)
49   end
50
51   it 'should raise an error for bogus services' do
52     (lambda do
53       @client.discovered_api(42)
54     end).should raise_error(TypeError)
55   end
56
57   it 'should raise an error for bogus services' do
58     (lambda do
59       @client.preferred_version(42)
60     end).should raise_error(TypeError)
61   end
62
63   it 'should raise an error for bogus methods' do
64     (lambda do
65       @client.generate_request(42)
66     end).should raise_error(TypeError)
67   end
68
69   it 'should not return a preferred version for bogus service names' do
70     @client.preferred_version('bogus').should == nil
71   end
72
73   describe 'with the prediction API' do
74     before 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')
79     end
80
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'
84     end
85
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
92       )
93       request.to_env(Faraday.default_connection)[:url].to_s.should === (
94         'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
95         '?userIp=127.0.0.1'
96       )
97     end
98
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
105       )
106       request.to_env(Faraday.default_connection)[:url].to_s.should === (
107         'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
108         '?key=qwerty'
109       )
110     end
111
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
119       )
120       Addressable::URI.parse(
121         request.to_env(Faraday.default_connection)[:url]
122       ).query_values.should == {
123         'key' => 'qwerty',
124         'userIp' => '127.0.0.1'
125       }
126     end
127
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'
133     end
134
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'
145     end
146
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'
151     end
152
153     it 'should not find methods that are not in the discovery document' do
154       @client.discovered_method(
155         'prediction.bogus', 'prediction', 'v1.2'
156       ).should == nil
157     end
158
159     it 'should raise an error for bogus methods' do
160       (lambda do
161         @client.discovered_method(42, 'prediction', 'v1.2')
162       end).should raise_error(TypeError)
163     end
164
165     it 'should raise an error for bogus methods' do
166       (lambda do
167         @client.generate_request(@client.discovered_api('prediction', 'v1.2'))
168       end).should raise_error(TypeError)
169     end
170
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'
174     end
175
176     it 'should return a batch path' do
177       @client.discovered_api('prediction', 'v1.2').batch_path.should_not be_nil
178     end
179
180     it 'should generate valid requests' do
181       request = @client.generate_request(
182         :api_method => @prediction.training.insert,
183         :parameters => {'data' => '12345'}
184       )
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 == ''
190     end
191
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']]
196       )
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'
200     end
201
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'}
206       )
207       request.to_env(Faraday.default_connection)[:url].to_s.should ===
208         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
209     end
210
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'}
215       )
216       request.to_env(Faraday.default_connection)[:url].to_s.should ===
217         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
218     end
219
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'}
227       )
228       request.to_env(Faraday.default_connection)[:url].to_s.should === (
229         'https://testing-domain.googleapis.com/' +
230         'prediction/v1.2/training?data=123'
231       )
232     end
233
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'}
241       )
242       request.headers.should have_key('Authorization')
243       request.headers['Authorization'].should =~ /^OAuth/
244     end
245
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'}
252       )
253       request.headers.should have_key('Authorization')
254       request.headers['Authorization'].should =~ /^Bearer/
255     end
256
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,
263         {'data' => '12345'}
264       )
265       result.response.status.should == 401
266     end
267
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,
273         {'data' => '12345'}
274       )
275       result.response.status.should == 401
276     end
277
278     it 'should not be able to execute improperly authorized requests' do
279       (lambda 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,
285           {'data' => '12345'}
286         )
287       end).should raise_error(Google::APIClient::ClientError)
288     end
289
290     it 'should not be able to execute improperly authorized requests' do
291       (lambda do
292         @client.authorization = :oauth_2
293         @client.authorization.access_token = '12345'
294         result = @client.execute!(
295           @prediction.training.insert,
296           {'data' => '12345'}
297         )
298       end).should raise_error(Google::APIClient::ClientError)
299     end
300
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,
306         {},
307         MultiJson.dump({"id" => "bucket/object"}),
308         {'Content-Type' => 'application/json'}
309       )
310       result.request.headers['Content-Type'].should == 'application/json'
311     end
312   end
313
314   describe 'with the plus API' do
315     before do
316       @client.authorization = nil
317       @plus = @client.discovered_api('plus')
318     end
319
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'
323     end
324
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'
330     end
331
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'
337     end
338
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'
343     end
344
345     it 'should not find methods that are not in the discovery document' do
346       @client.discovered_method('plus.bogus', 'plus').should == nil
347     end
348
349     it 'should generate requests against the correct URIs' do
350       request = @client.generate_request(
351         :api_method => @plus.activities.list,
352         :parameters => {
353           'userId' => '107807692475771887386', 'collection' => 'public'
354         },
355         :authenticated => false
356       )
357       request.to_env(Faraday.default_connection)[:url].to_s.should === (
358         'https://www.googleapis.com/plus/v1/' +
359         'people/107807692475771887386/activities/public'
360       )
361     end
362
363     it 'should correctly validate parameters' do
364       (lambda do
365         @client.generate_request(
366           :api_method => @plus.activities.list,
367           :parameters => {'alt' => 'json'},
368           :authenticated => false
369         )
370       end).should raise_error(ArgumentError)
371     end
372
373     it 'should correctly validate parameters' do
374       (lambda do
375         @client.generate_request(
376           :api_method => @plus.activities.list,
377           :parameters => {
378             'userId' => '107807692475771887386', 'collection' => 'bogus'
379           },
380           :authenticated => false
381         )
382       end).should raise_error(ArgumentError)
383     end
384   end
385
386   describe 'with the latitude API' do
387     before do
388       @client.authorization = nil
389       @latitude = @client.discovered_api('latitude')
390     end
391
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'
395     end
396
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'
400     end
401
402     it 'should return a batch path' do
403       @client.discovered_api('latitude').batch_path.should_not be_nil
404     end
405
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'
410     end
411
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'
416     end
417
418     it 'should not find methods that are not in the discovery document' do
419       @client.discovered_method('latitude.bogus', 'latitude').should == nil
420     end
421
422     it 'should generate requests against the correct URIs' do
423       request = @client.generate_request(
424         :api_method => 'latitude.currentLocation.get',
425         :authenticated => false
426       )
427       request.to_env(Faraday.default_connection)[:url].to_s.should ===
428         'https://www.googleapis.com/latitude/v1/currentLocation'
429     end
430
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
435       )
436       request.to_env(Faraday.default_connection)[:url].to_s.should ===
437         'https://www.googleapis.com/latitude/v1/currentLocation'
438     end
439
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
444       )
445       result.response.status.should == 401
446     end
447   end
448
449   describe 'with the moderator API' do
450     before do
451       @client.authorization = nil
452       @moderator = @client.discovered_api('moderator')
453     end
454
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'
458     end
459
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'
463     end
464
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'
469     end
470
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'
475     end
476
477     it 'should not find methods that are not in the discovery document' do
478       @client.discovered_method('moderator.bogus', 'moderator').should == nil
479     end
480
481     it 'should return a batch path' do
482       @client.discovered_api('moderator').batch_path.should_not be_nil
483     end
484
485     it 'should generate requests against the correct URIs' do
486       request = @client.generate_request(
487         :api_method => 'moderator.profiles.get',
488         :authenticated => false
489       )
490       request.to_env(Faraday.default_connection)[:url].to_s.should ===
491         'https://www.googleapis.com/moderator/v1/profiles/@me'
492     end
493
494     it 'should generate requests against the correct URIs' do
495       request = @client.generate_request(
496         :api_method => @moderator.profiles.get,
497         :authenticated => false
498       )
499       request.to_env(Faraday.default_connection)[:url].to_s.should ===
500         'https://www.googleapis.com/moderator/v1/profiles/@me'
501     end
502
503     it 'should not be able to execute requests without authorization' do
504       result = @client.execute(
505         'moderator.profiles.get',
506         {},
507         '',
508         [],
509         {:authenticated => false}
510       )
511       result.response.status.should == 401
512     end
513   end
514
515   describe 'with the adsense API' do
516     before do
517       @client.authorization = nil
518       @adsense = @client.discovered_api('adsense', 'v1')
519     end
520
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'
524     end
525
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'
529     end
530
531     it 'should return a batch path' do
532       @client.discovered_api('adsense').batch_path.should_not be_nil
533     end
534
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'
539     end
540
541     it 'should not find methods that are not in the discovery document' do
542       @client.discovered_method('adsense.bogus', 'adsense').should == nil
543     end
544
545     it 'should generate requests against the correct URIs' do
546       request = @client.generate_request(
547         :api_method => 'adsense.adclients.list',
548         :authenticated => false
549       )
550       request.to_env(Faraday.default_connection)[:url].to_s.should ===
551         'https://www.googleapis.com/adsense/v1/adclients'
552     end
553
554     it 'should generate requests against the correct URIs' do
555       request = @client.generate_request(
556         :api_method => @adsense.adclients.list,
557         :authenticated => false
558       )
559       request.to_env(Faraday.default_connection)[:url].to_s.should ===
560         'https://www.googleapis.com/adsense/v1/adclients'
561     end
562
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
567       )
568       result.response.status.should == 401
569     end
570
571     it 'should fail when validating missing required parameters' do
572       (lambda do
573         @client.generate_request(
574           :api_method => @adsense.reports.generate,
575           :authenticated => false
576         )
577       end).should raise_error(ArgumentError)
578     end
579
580     it 'should succeed when validating parameters in a correct call' do
581       (lambda do
582         @client.generate_request(
583           :api_method => @adsense.reports.generate,
584           :parameters => {
585             'startDate' => '2000-01-01',
586             'endDate' => '2010-01-01',
587             'dimension' => 'DATE',
588             'metric' => 'PAGE_VIEWS'
589           },
590           :authenticated => false
591         )
592       end).should_not raise_error
593     end
594
595     it 'should fail when validating parameters with invalid values' do
596       (lambda do
597         @client.generate_request(
598           :api_method => @adsense.reports.generate,
599           :parameters => {
600             'startDate' => '2000-01-01',
601             'endDate' => '2010-01-01',
602             'dimension' => 'BAD_CHARACTERS=-&*(£&',
603             'metric' => 'PAGE_VIEWS'
604           },
605           :authenticated => false
606         )
607       end).should raise_error(ArgumentError)
608     end
609
610     it 'should succeed when validating repeated parameters in a correct call' do
611       (lambda do
612         @client.generate_request(
613           :api_method => @adsense.reports.generate,
614           :parameters => {
615             'startDate' => '2000-01-01',
616             'endDate' => '2010-01-01',
617             'dimension' => ['DATE', 'PRODUCT_CODE'],
618             'metric' => ['PAGE_VIEWS', 'CLICKS']
619           },
620           :authenticated => false
621         )
622       end).should_not raise_error
623     end
624
625     it 'should fail when validating incorrect repeated parameters' do
626       (lambda do
627         @client.generate_request(
628           :api_method => @adsense.reports.generate,
629           :parameters => {
630             'startDate' => '2000-01-01',
631             'endDate' => '2010-01-01',
632             'dimension' => ['DATE', 'BAD_CHARACTERS=-&*(£&'],
633             'metric' => ['PAGE_VIEWS', 'CLICKS']
634           },
635           :authenticated => false
636         )
637       end).should raise_error(ArgumentError)
638     end
639   end
640   
641   describe 'with the Drive API' do
642     before do
643       @client.authorization = nil
644       @drive = @client.discovered_api('drive', 'v1')
645     end
646     
647     it 'should include media upload info methods' do
648       @drive.files.insert.media_upload.should_not == nil
649     end
650     
651     it 'should include accepted media types' do
652       @drive.files.insert.media_upload.accepted_types.should_not be_empty
653     end
654     
655     it 'should have an upload path' do
656       @drive.files.insert.media_upload.uri_template.should_not == nil
657     end
658     
659     it 'should have a max file size' do
660       @drive.files.insert.media_upload.max_size.should_not == nil
661     end
662   end
663 end