Updating dependencies.
[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].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].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       request.to_env(Faraday.default_connection)[:url].query_values.should == {
121         'key' => 'qwerty',
122         'userIp' => '127.0.0.1'
123       }
124     end
125
126     it 'should correctly generate API objects' do
127       @client.discovered_api('prediction', 'v1.2').name.should == 'prediction'
128       @client.discovered_api('prediction', 'v1.2').version.should == 'v1.2'
129       @client.discovered_api(:prediction, 'v1.2').name.should == 'prediction'
130       @client.discovered_api(:prediction, 'v1.2').version.should == 'v1.2'
131     end
132
133     it 'should discover methods' do
134       @client.discovered_method(
135         'prediction.training.insert', 'prediction', 'v1.2'
136       ).name.should == 'insert'
137       @client.discovered_method(
138         :'prediction.training.insert', :prediction, 'v1.2'
139       ).name.should == 'insert'
140       @client.discovered_method(
141         'prediction.training.delete', 'prediction', 'v1.2'
142       ).name.should == 'delete'
143     end
144
145     it 'should define the origin API in discovered methods' do
146       @client.discovered_method(
147         'prediction.training.insert', 'prediction', 'v1.2'
148       ).api.name.should == 'prediction'
149     end
150
151     it 'should not find methods that are not in the discovery document' do
152       @client.discovered_method(
153         'prediction.bogus', 'prediction', 'v1.2'
154       ).should == nil
155     end
156
157     it 'should raise an error for bogus methods' do
158       (lambda do
159         @client.discovered_method(42, 'prediction', 'v1.2')
160       end).should raise_error(TypeError)
161     end
162
163     it 'should raise an error for bogus methods' do
164       (lambda do
165         @client.generate_request(@client.discovered_api('prediction', 'v1.2'))
166       end).should raise_error(TypeError)
167     end
168
169     it 'should correctly determine the preferred version' do
170       @client.preferred_version('prediction').version.should_not == 'v1'
171       @client.preferred_version(:prediction).version.should_not == 'v1'
172     end
173
174     it 'should return a batch path' do
175       @client.discovered_api('prediction', 'v1.2').batch_path.should_not be_nil
176     end
177
178     it 'should generate valid requests' do
179       request = @client.generate_request(
180         :api_method => @prediction.training.insert,
181         :parameters => {'data' => '12345', }
182       )
183       request.method.should == :post
184       request.to_env(Faraday.default_connection)[:url].should ===
185         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
186       request.headers.should be_empty
187       request.body.should == ''
188     end
189
190     it 'should generate valid requests when repeated parameters are passed' do
191       request = @client.generate_request(
192         :api_method => @prediction.training.insert,
193         :parameters => [['data', '1'],['data','2']]
194       )
195       request.method.should == :post
196       request.to_env(Faraday.default_connection)[:url].should ===
197         'https://www.googleapis.com/prediction/v1.2/training?data=1&data=2'
198     end
199
200     it 'should generate requests against the correct URIs' do
201       request = @client.generate_request(
202         :api_method => @prediction.training.insert,
203         :parameters => {'data' => '12345'}
204       )
205       request.to_env(Faraday.default_connection)[:url].should ===
206         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
207     end
208
209     it 'should generate requests against the correct URIs' do
210       request = @client.generate_request(
211         :api_method => @prediction.training.insert,
212         :parameters => {'data' => '12345'}
213       )
214       request.to_env(Faraday.default_connection)[:url].should ===
215         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
216     end
217
218     it 'should allow modification to the base URIs for testing purposes' do
219       prediction = @client.discovered_api('prediction', 'v1.2')
220       prediction.method_base =
221         'https://testing-domain.googleapis.com/prediction/v1.2/'
222       request = @client.generate_request(
223         :api_method => prediction.training.insert,
224         :parameters => {'data' => '123'}
225       )
226       request.to_env(Faraday.default_connection)[:url].should === (
227         'https://testing-domain.googleapis.com/' +
228         'prediction/v1.2/training?data=123'
229       )
230     end
231
232     it 'should generate OAuth 1 requests' do
233       @client.authorization = :oauth_1
234       @client.authorization.token_credential_key = '12345'
235       @client.authorization.token_credential_secret = '12345'
236       request = @client.generate_request(
237         :api_method => @prediction.training.insert,
238         :parameters => {'data' => '12345'}
239       )
240       request.headers.should have_key('Authorization')
241       request.headers['Authorization'].should =~ /^OAuth/
242     end
243
244     it 'should generate OAuth 2 requests' do
245       @client.authorization = :oauth_2
246       @client.authorization.access_token = '12345'
247       request = @client.generate_request(
248         :api_method => @prediction.training.insert,
249         :parameters => {'data' => '12345'}
250       )
251       request.headers.should have_key('Authorization')
252       request.headers['Authorization'].should =~ /^Bearer/
253     end
254
255     it 'should not be able to execute improperly authorized requests' do
256       @client.authorization = :oauth_1
257       @client.authorization.token_credential_key = '12345'
258       @client.authorization.token_credential_secret = '12345'
259       result = @client.execute(
260         @prediction.training.insert,
261         {'data' => '12345'}
262       )
263       result.response.status.should == 401
264     end
265
266     it 'should not be able to execute improperly authorized requests' do
267       @client.authorization = :oauth_2
268       @client.authorization.access_token = '12345'
269       result = @client.execute(
270         @prediction.training.insert,
271         {'data' => '12345'}
272       )
273       result.response.status.should == 401
274     end
275
276     it 'should not be able to execute improperly authorized requests' do
277       (lambda do
278         @client.authorization = :oauth_1
279         @client.authorization.token_credential_key = '12345'
280         @client.authorization.token_credential_secret = '12345'
281         result = @client.execute!(
282           @prediction.training.insert,
283           {'data' => '12345'}
284         )
285       end).should raise_error(Google::APIClient::ClientError)
286     end
287
288     it 'should not be able to execute improperly authorized requests' do
289       (lambda do
290         @client.authorization = :oauth_2
291         @client.authorization.access_token = '12345'
292         result = @client.execute!(
293           @prediction.training.insert,
294           {'data' => '12345'}
295         )
296       end).should raise_error(Google::APIClient::ClientError)
297     end
298
299     it 'should correctly handle unnamed parameters' do
300       @client.authorization = :oauth_2
301       @client.authorization.access_token = '12345'
302       result = @client.execute(
303         @prediction.training.insert,
304         {},
305         MultiJson.dump({"id" => "bucket/object"}),
306         {'Content-Type' => 'application/json'}
307       )
308       result.request.headers['Content-Type'].should == 'application/json'
309     end
310   end
311
312   describe 'with the plus API' do
313     before do
314       @client.authorization = nil
315       @plus = @client.discovered_api('plus')
316     end
317
318     it 'should correctly determine the discovery URI' do
319       @client.discovery_uri('plus').should ===
320         'https://www.googleapis.com/discovery/v1/apis/plus/v1/rest'
321     end
322
323     it 'should find APIs that are in the discovery document' do
324       @client.discovered_api('plus').name.should == 'plus'
325       @client.discovered_api('plus').version.should == 'v1'
326       @client.discovered_api(:plus).name.should == 'plus'
327       @client.discovered_api(:plus).version.should == 'v1'
328     end
329
330     it 'should find methods that are in the discovery document' do
331       # TODO(bobaman) Fix this when the RPC names are correct
332       @client.discovered_method(
333         'plus.activities.list', 'plus'
334       ).name.should == 'list'
335     end
336
337     it 'should define the origin API in discovered methods' do
338       @client.discovered_method(
339         'plus.activities.list', 'plus'
340       ).api.name.should == 'plus'
341     end
342
343     it 'should not find methods that are not in the discovery document' do
344       @client.discovered_method('plus.bogus', 'plus').should == nil
345     end
346
347     it 'should generate requests against the correct URIs' do
348       request = @client.generate_request(
349         :api_method => @plus.activities.list,
350         :parameters => {
351           'userId' => '107807692475771887386', 'collection' => 'public'
352         },
353         :authenticated => false
354       )
355       request.to_env(Faraday.default_connection)[:url].should === (
356         'https://www.googleapis.com/plus/v1/' +
357         'people/107807692475771887386/activities/public'
358       )
359     end
360
361     it 'should correctly validate parameters' do
362       (lambda do
363         @client.generate_request(
364           :api_method => @plus.activities.list,
365           :parameters => {'alt' => 'json'},
366           :authenticated => false
367         )
368       end).should raise_error(ArgumentError)
369     end
370
371     it 'should correctly validate parameters' do
372       (lambda do
373         @client.generate_request(
374           :api_method => @plus.activities.list,
375           :parameters => {
376             'userId' => '107807692475771887386', 'collection' => 'bogus'
377           },
378           :authenticated => false
379         )
380       end).should raise_error(ArgumentError)
381     end
382   end
383
384   describe 'with the latitude API' do
385     before do
386       @client.authorization = nil
387       @latitude = @client.discovered_api('latitude')
388     end
389
390     it 'should correctly determine the discovery URI' do
391       @client.discovery_uri('latitude').should ===
392         'https://www.googleapis.com/discovery/v1/apis/latitude/v1/rest'
393     end
394
395     it 'should find APIs that are in the discovery document' do
396       @client.discovered_api('latitude').name.should == 'latitude'
397       @client.discovered_api('latitude').version.should == 'v1'
398     end
399
400     it 'should return a batch path' do
401       @client.discovered_api('latitude').batch_path.should_not be_nil
402     end
403
404     it 'should find methods that are in the discovery document' do
405       @client.discovered_method(
406         'latitude.currentLocation.get', 'latitude'
407       ).name.should == 'get'
408     end
409
410     it 'should define the origin API in discovered methods' do
411       @client.discovered_method(
412         'latitude.currentLocation.get', 'latitude'
413       ).api.name.should == 'latitude'
414     end
415
416     it 'should not find methods that are not in the discovery document' do
417       @client.discovered_method('latitude.bogus', 'latitude').should == nil
418     end
419
420     it 'should generate requests against the correct URIs' do
421       request = @client.generate_request(
422         :api_method => 'latitude.currentLocation.get',
423         :authenticated => false
424       )
425       request.to_env(Faraday.default_connection)[:url].should ===
426         'https://www.googleapis.com/latitude/v1/currentLocation'
427     end
428
429     it 'should generate requests against the correct URIs' do
430       request = @client.generate_request(
431         :api_method => @latitude.current_location.get,
432         :authenticated => false
433       )
434       request.to_env(Faraday.default_connection)[:url].should ===
435         'https://www.googleapis.com/latitude/v1/currentLocation'
436     end
437
438     it 'should not be able to execute requests without authorization' do
439       result = @client.execute(
440         :api_method => 'latitude.currentLocation.get',
441         :authenticated => false
442       )
443       result.response.status.should == 401
444     end
445   end
446
447   describe 'with the moderator API' do
448     before do
449       @client.authorization = nil
450       @moderator = @client.discovered_api('moderator')
451     end
452
453     it 'should correctly determine the discovery URI' do
454       @client.discovery_uri('moderator').should ===
455         'https://www.googleapis.com/discovery/v1/apis/moderator/v1/rest'
456     end
457
458     it 'should find APIs that are in the discovery document' do
459       @client.discovered_api('moderator').name.should == 'moderator'
460       @client.discovered_api('moderator').version.should == 'v1'
461     end
462
463     it 'should find methods that are in the discovery document' do
464       @client.discovered_method(
465         'moderator.profiles.get', 'moderator'
466       ).name.should == 'get'
467     end
468
469     it 'should define the origin API in discovered methods' do
470       @client.discovered_method(
471         'moderator.profiles.get', 'moderator'
472       ).api.name.should == 'moderator'
473     end
474
475     it 'should not find methods that are not in the discovery document' do
476       @client.discovered_method('moderator.bogus', 'moderator').should == nil
477     end
478
479     it 'should return a batch path' do
480       @client.discovered_api('moderator').batch_path.should_not be_nil
481     end
482
483     it 'should generate requests against the correct URIs' do
484       request = @client.generate_request(
485         :api_method => 'moderator.profiles.get',
486         :authenticated => false
487       )
488       request.to_env(Faraday.default_connection)[:url].should ===
489         'https://www.googleapis.com/moderator/v1/profiles/@me'
490     end
491
492     it 'should generate requests against the correct URIs' do
493       request = @client.generate_request(
494         :api_method => @moderator.profiles.get,
495         :authenticated => false
496       )
497       request.to_env(Faraday.default_connection)[:url].should ===
498         'https://www.googleapis.com/moderator/v1/profiles/@me'
499     end
500
501     it 'should not be able to execute requests without authorization' do
502       result = @client.execute(
503         'moderator.profiles.get',
504         {},
505         '',
506         [],
507         {:authenticated => false}
508       )
509       result.response.status.should == 401
510     end
511   end
512
513   describe 'with the adsense API' do
514     before do
515       @client.authorization = nil
516       @adsense = @client.discovered_api('adsense', 'v1')
517     end
518
519     it 'should correctly determine the discovery URI' do
520       @client.discovery_uri('adsense').should ===
521         'https://www.googleapis.com/discovery/v1/apis/adsense/v1/rest'
522     end
523
524     it 'should find APIs that are in the discovery document' do
525       @client.discovered_api('adsense').name.should == 'adsense'
526       @client.discovered_api('adsense').version.should == 'v1'
527     end
528
529     it 'should return a batch path' do
530       @client.discovered_api('adsense').batch_path.should_not be_nil
531     end
532
533     it 'should find methods that are in the discovery document' do
534       @client.discovered_method(
535         'adsense.reports.generate', 'adsense'
536       ).name.should == 'generate'
537     end
538
539     it 'should not find methods that are not in the discovery document' do
540       @client.discovered_method('adsense.bogus', 'adsense').should == nil
541     end
542
543     it 'should generate requests against the correct URIs' do
544       request = @client.generate_request(
545         :api_method => 'adsense.adclients.list',
546         :authenticated => false
547       )
548       request.to_env(Faraday.default_connection)[:url].should ===
549         'https://www.googleapis.com/adsense/v1/adclients'
550     end
551
552     it 'should generate requests against the correct URIs' do
553       request = @client.generate_request(
554         :api_method => @adsense.adclients.list,
555         :authenticated => false
556       )
557       request.to_env(Faraday.default_connection)[:url].should ===
558         'https://www.googleapis.com/adsense/v1/adclients'
559     end
560
561     it 'should not be able to execute requests without authorization' do
562       result = @client.execute(
563         :api_method => 'adsense.adclients.list',
564         :authenticated => false
565       )
566       result.response.status.should == 401
567     end
568
569     it 'should fail when validating missing required parameters' do
570       (lambda do
571         @client.generate_request(
572           :api_method => @adsense.reports.generate,
573           :authenticated => false
574         )
575       end).should raise_error(ArgumentError)
576     end
577
578     it 'should succeed when validating parameters in a correct call' do
579       (lambda do
580         @client.generate_request(
581           :api_method => @adsense.reports.generate,
582           :parameters => {
583             'startDate' => '2000-01-01',
584             'endDate' => '2010-01-01',
585             'dimension' => 'DATE',
586             'metric' => 'PAGE_VIEWS'
587           },
588           :authenticated => false
589         )
590       end).should_not raise_error
591     end
592
593     it 'should fail when validating parameters with invalid values' do
594       (lambda do
595         @client.generate_request(
596           :api_method => @adsense.reports.generate,
597           :parameters => {
598             'startDate' => '2000-01-01',
599             'endDate' => '2010-01-01',
600             'dimension' => 'BAD_CHARACTERS=-&*(£&',
601             'metric' => 'PAGE_VIEWS'
602           },
603           :authenticated => false
604         )
605       end).should raise_error(ArgumentError)
606     end
607
608     it 'should succeed when validating repeated parameters in a correct call' do
609       (lambda do
610         @client.generate_request(
611           :api_method => @adsense.reports.generate,
612           :parameters => {
613             'startDate' => '2000-01-01',
614             'endDate' => '2010-01-01',
615             'dimension' => ['DATE', 'PRODUCT_CODE'],
616             'metric' => ['PAGE_VIEWS', 'CLICKS']
617           },
618           :authenticated => false
619         )
620       end).should_not raise_error
621     end
622
623     it 'should fail when validating incorrect repeated parameters' do
624       (lambda do
625         @client.generate_request(
626           :api_method => @adsense.reports.generate,
627           :parameters => {
628             'startDate' => '2000-01-01',
629             'endDate' => '2010-01-01',
630             'dimension' => ['DATE', 'BAD_CHARACTERS=-&*(£&'],
631             'metric' => ['PAGE_VIEWS', 'CLICKS']
632           },
633           :authenticated => false
634         )
635       end).should raise_error(ArgumentError)
636     end
637   end
638   
639   describe 'with the Drive API' do
640     before do
641       @client.authorization = nil
642       @drive = @client.discovered_api('drive', 'v1')
643     end
644     
645     it 'should include media upload info methods' do
646       @drive.files.insert.media_upload.should_not == nil
647     end
648     
649     it 'should include accepted media types' do
650       @drive.files.insert.media_upload.accepted_types.should_not be_empty
651     end
652     
653     it 'should have an upload path' do
654       @drive.files.insert.media_upload.uri_template.should_not == nil
655     end
656     
657     it 'should have a max file size' do
658       @drive.files.insert.media_upload.max_size.should_not == nil
659     end
660   end
661 end