Updated to avoid deprecation of encode and decode methods in multi_json gem.
[arvados.git] / spec / google / api_client / discovery_spec.rb
1 # Copyright 2010 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 require 'spec_helper'
16
17 gem 'faraday', '~> 0.7.0'
18 require 'faraday'
19 require 'faraday/utils'
20 require 'multi_json'
21
22 gem 'signet', '~> 0.3.0'
23 require 'signet/oauth_1/client'
24
25 require 'google/api_client'
26 require 'google/api_client/version'
27
28 describe Google::APIClient do
29   before do
30     @client = Google::APIClient.new
31   end
32
33   it 'should raise a type error for bogus authorization' do
34     (lambda do
35       Google::APIClient.new(:authorization => 42)
36     end).should raise_error(TypeError)
37   end
38
39   it 'should not be able to retrieve the discovery document for a bogus API' do
40     (lambda do
41       @client.discovery_document('bogus')
42     end).should raise_error(Google::APIClient::TransmissionError)
43     (lambda do
44       @client.discovered_api('bogus')
45     end).should raise_error(Google::APIClient::TransmissionError)
46   end
47
48   it 'should raise an error for bogus services' do
49     (lambda do
50       @client.discovered_api(42)
51     end).should raise_error(TypeError)
52   end
53
54   it 'should raise an error for bogus services' do
55     (lambda do
56       @client.preferred_version(42)
57     end).should raise_error(TypeError)
58   end
59
60   it 'should raise an error for bogus methods' do
61     (lambda do
62       @client.generate_request(42)
63     end).should raise_error(TypeError)
64   end
65
66   it 'should not return a preferred version for bogus service names' do
67     @client.preferred_version('bogus').should == nil
68   end
69
70   describe 'with the prediction API' do
71     before do
72       @client.authorization = nil
73       # The prediction API no longer exposes a v1, so we have to be
74       # careful about looking up the wrong API version.
75       @prediction = @client.discovered_api('prediction', 'v1.2')
76     end
77
78     it 'should correctly determine the discovery URI' do
79       @client.discovery_uri('prediction').should ===
80         'https://www.googleapis.com/discovery/v1/apis/prediction/v1/rest'
81     end
82
83     it 'should correctly determine the discovery URI if :user_ip is set' do
84       @client.user_ip = '127.0.0.1'
85       request = @client.generate_request(
86         :http_method => 'GET',
87         :uri => @client.discovery_uri('prediction', 'v1.2'),
88         :authenticated => false
89       )
90       request.to_env(Faraday.default_connection)[:url].should === (
91         'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
92         '?userIp=127.0.0.1'
93       )
94     end
95
96     it 'should correctly determine the discovery URI if :key is set' do
97       @client.key = 'qwerty'
98       request = @client.generate_request(
99         :http_method => 'GET',
100         :uri => @client.discovery_uri('prediction', 'v1.2'),
101         :authenticated => false
102       )
103       request.to_env(Faraday.default_connection)[:url].should === (
104         'https://www.googleapis.com/discovery/v1/apis/prediction/v1.2/rest' +
105         '?key=qwerty'
106       )
107     end
108
109     it 'should correctly determine the discovery URI if both are set' do
110       @client.key = 'qwerty'
111       @client.user_ip = '127.0.0.1'
112       request = @client.generate_request(
113         :http_method => 'GET',
114         :uri => @client.discovery_uri('prediction', 'v1.2'),
115         :authenticated => false
116       )
117       request.to_env(Faraday.default_connection)[:url].query_values.should == {
118         'key' => 'qwerty',
119         'userIp' => '127.0.0.1'
120       }
121     end
122
123     it 'should correctly generate API objects' do
124       @client.discovered_api('prediction', 'v1.2').name.should == 'prediction'
125       @client.discovered_api('prediction', 'v1.2').version.should == 'v1.2'
126       @client.discovered_api(:prediction, 'v1.2').name.should == 'prediction'
127       @client.discovered_api(:prediction, 'v1.2').version.should == 'v1.2'
128     end
129
130     it 'should discover methods' do
131       @client.discovered_method(
132         'prediction.training.insert', 'prediction', 'v1.2'
133       ).name.should == 'insert'
134       @client.discovered_method(
135         :'prediction.training.insert', :prediction, 'v1.2'
136       ).name.should == 'insert'
137       @client.discovered_method(
138         'prediction.training.delete', 'prediction', 'v1.2'
139       ).name.should == 'delete'
140     end
141
142     it 'should not find methods that are not in the discovery document' do
143       @client.discovered_method(
144         'prediction.bogus', 'prediction', 'v1.2'
145       ).should == nil
146     end
147
148     it 'should raise an error for bogus methods' do
149       (lambda do
150         @client.discovered_method(42, 'prediction', 'v1.2')
151       end).should raise_error(TypeError)
152     end
153
154     it 'should raise an error for bogus methods' do
155       (lambda do
156         @client.generate_request(@client.discovered_api('prediction', 'v1.2'))
157       end).should raise_error(TypeError)
158     end
159
160     it 'should correctly determine the preferred version' do
161       @client.preferred_version('prediction').version.should_not == 'v1'
162       @client.preferred_version(:prediction).version.should_not == 'v1'
163     end
164
165     it 'should generate valid requests' do
166       request = @client.generate_request(
167         :api_method => @prediction.training.insert,
168         :parameters => {'data' => '12345', }
169       )
170       request.method.should == :post
171       request.to_env(Faraday.default_connection)[:url].should ===
172         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
173       request.headers.should be_empty
174       request.body.should == ''
175     end
176
177     it 'should generate valid requests when repeated parameters are passed' do
178       request = @client.generate_request(
179         :api_method => @prediction.training.insert,
180         :parameters => [['data', '1'],['data','2']]
181       )
182       request.method.should == :post
183       request.to_env(Faraday.default_connection)[:url].should ===
184         'https://www.googleapis.com/prediction/v1.2/training?data=1&data=2'
185     end
186
187     it 'should generate requests against the correct URIs' do
188       request = @client.generate_request(
189         :api_method => @prediction.training.insert,
190         :parameters => {'data' => '12345'}
191       )
192       request.to_env(Faraday.default_connection)[:url].should ===
193         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
194     end
195
196     it 'should generate requests against the correct URIs' do
197       request = @client.generate_request(
198         :api_method => @prediction.training.insert,
199         :parameters => {'data' => '12345'}
200       )
201       request.to_env(Faraday.default_connection)[:url].should ===
202         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
203     end
204
205     it 'should allow modification to the base URIs for testing purposes' do
206       prediction = @client.discovered_api('prediction', 'v1.2')
207       prediction.method_base =
208         'https://testing-domain.googleapis.com/prediction/v1.2/'
209       request = @client.generate_request(
210         :api_method => prediction.training.insert,
211         :parameters => {'data' => '123'}
212       )
213       request.to_env(Faraday.default_connection)[:url].should === (
214         'https://testing-domain.googleapis.com/' +
215         'prediction/v1.2/training?data=123'
216       )
217     end
218
219     it 'should generate OAuth 1 requests' do
220       @client.authorization = :oauth_1
221       @client.authorization.token_credential_key = '12345'
222       @client.authorization.token_credential_secret = '12345'
223       request = @client.generate_request(
224         :api_method => @prediction.training.insert,
225         :parameters => {'data' => '12345'}
226       )
227       request.headers.should have_key('Authorization')
228       request.headers['Authorization'].should =~ /^OAuth/
229     end
230
231     it 'should generate OAuth 2 requests' do
232       @client.authorization = :oauth_2
233       @client.authorization.access_token = '12345'
234       request = @client.generate_request(
235         :api_method => @prediction.training.insert,
236         :parameters => {'data' => '12345'}
237       )
238       request.headers.should have_key('Authorization')
239       request.headers['Authorization'].should =~ /^Bearer/
240     end
241
242     it 'should not be able to execute improperly authorized requests' do
243       @client.authorization = :oauth_1
244       @client.authorization.token_credential_key = '12345'
245       @client.authorization.token_credential_secret = '12345'
246       result = @client.execute(
247         @prediction.training.insert,
248         {'data' => '12345'}
249       )
250       result.response.status.should == 401
251     end
252
253     it 'should not be able to execute improperly authorized requests' do
254       @client.authorization = :oauth_2
255       @client.authorization.access_token = '12345'
256       result = @client.execute(
257         @prediction.training.insert,
258         {'data' => '12345'}
259       )
260       result.response.status.should == 401
261     end
262
263     it 'should not be able to execute improperly authorized requests' do
264       (lambda do
265         @client.authorization = :oauth_1
266         @client.authorization.token_credential_key = '12345'
267         @client.authorization.token_credential_secret = '12345'
268         result = @client.execute!(
269           @prediction.training.insert,
270           {'data' => '12345'}
271         )
272       end).should raise_error(Google::APIClient::ClientError)
273     end
274
275     it 'should not be able to execute improperly authorized requests' do
276       (lambda do
277         @client.authorization = :oauth_2
278         @client.authorization.access_token = '12345'
279         result = @client.execute!(
280           @prediction.training.insert,
281           {'data' => '12345'}
282         )
283       end).should raise_error(Google::APIClient::ClientError)
284     end
285
286     it 'should correctly handle unnamed parameters' do
287       @client.authorization = :oauth_2
288       @client.authorization.access_token = '12345'
289       result = @client.execute(
290         @prediction.training.insert,
291         {},
292         MultiJson.dump({"id" => "bucket/object"}),
293         {'Content-Type' => 'application/json'}
294       )
295       result.request.headers['Content-Type'].should == 'application/json'
296     end
297   end
298
299   describe 'with the plus API' do
300     before do
301       @client.authorization = nil
302       @plus = @client.discovered_api('plus')
303     end
304
305     it 'should correctly determine the discovery URI' do
306       @client.discovery_uri('plus').should ===
307         'https://www.googleapis.com/discovery/v1/apis/plus/v1/rest'
308     end
309
310     it 'should find APIs that are in the discovery document' do
311       @client.discovered_api('plus').name.should == 'plus'
312       @client.discovered_api('plus').version.should == 'v1'
313       @client.discovered_api(:plus).name.should == 'plus'
314       @client.discovered_api(:plus).version.should == 'v1'
315     end
316
317     it 'should find methods that are in the discovery document' do
318       # TODO(bobaman) Fix this when the RPC names are correct
319       @client.discovered_method(
320         'plus.activities.list', 'plus'
321       ).name.should == 'list'
322     end
323
324     it 'should not find methods that are not in the discovery document' do
325       @client.discovered_method('plus.bogus', 'plus').should == nil
326     end
327
328     it 'should generate requests against the correct URIs' do
329       request = @client.generate_request(
330         :api_method => @plus.activities.list,
331         :parameters => {
332           'userId' => '107807692475771887386', 'collection' => 'public'
333         },
334         :authenticated => false
335       )
336       request.to_env(Faraday.default_connection)[:url].should === (
337         'https://www.googleapis.com/plus/v1/' +
338         'people/107807692475771887386/activities/public'
339       )
340     end
341
342     it 'should correctly validate parameters' do
343       (lambda do
344         @client.generate_request(
345           :api_method => @plus.activities.list,
346           :parameters => {'alt' => 'json'},
347           :authenticated => false
348         )
349       end).should raise_error(ArgumentError)
350     end
351
352     it 'should correctly validate parameters' do
353       (lambda do
354         @client.generate_request(
355           :api_method => @plus.activities.list,
356           :parameters => {
357             'userId' => '107807692475771887386', 'collection' => 'bogus'
358           },
359           :authenticated => false
360         )
361       end).should raise_error(ArgumentError)
362     end
363   end
364
365   describe 'with the latitude API' do
366     before do
367       @client.authorization = nil
368       @latitude = @client.discovered_api('latitude')
369     end
370
371     it 'should correctly determine the discovery URI' do
372       @client.discovery_uri('latitude').should ===
373         'https://www.googleapis.com/discovery/v1/apis/latitude/v1/rest'
374     end
375
376     it 'should find APIs that are in the discovery document' do
377       @client.discovered_api('latitude').name.should == 'latitude'
378       @client.discovered_api('latitude').version.should == 'v1'
379     end
380
381     it 'should find methods that are in the discovery document' do
382       @client.discovered_method(
383         'latitude.currentLocation.get', 'latitude'
384       ).name.should == 'get'
385     end
386
387     it 'should not find methods that are not in the discovery document' do
388       @client.discovered_method('latitude.bogus', 'latitude').should == nil
389     end
390
391     it 'should generate requests against the correct URIs' do
392       request = @client.generate_request(
393         :api_method => 'latitude.currentLocation.get',
394         :authenticated => false
395       )
396       request.to_env(Faraday.default_connection)[:url].should ===
397         'https://www.googleapis.com/latitude/v1/currentLocation'
398     end
399
400     it 'should generate requests against the correct URIs' do
401       request = @client.generate_request(
402         :api_method => @latitude.current_location.get,
403         :authenticated => false
404       )
405       request.to_env(Faraday.default_connection)[:url].should ===
406         'https://www.googleapis.com/latitude/v1/currentLocation'
407     end
408
409     it 'should not be able to execute requests without authorization' do
410       result = @client.execute(
411         :api_method => 'latitude.currentLocation.get',
412         :authenticated => false
413       )
414       result.response.status.should == 401
415     end
416   end
417
418   describe 'with the moderator API' do
419     before do
420       @client.authorization = nil
421       @moderator = @client.discovered_api('moderator')
422     end
423
424     it 'should correctly determine the discovery URI' do
425       @client.discovery_uri('moderator').should ===
426         'https://www.googleapis.com/discovery/v1/apis/moderator/v1/rest'
427     end
428
429     it 'should find APIs that are in the discovery document' do
430       @client.discovered_api('moderator').name.should == 'moderator'
431       @client.discovered_api('moderator').version.should == 'v1'
432     end
433
434     it 'should find methods that are in the discovery document' do
435       @client.discovered_method(
436         'moderator.profiles.get', 'moderator'
437       ).name.should == 'get'
438     end
439
440     it 'should not find methods that are not in the discovery document' do
441       @client.discovered_method('moderator.bogus', 'moderator').should == nil
442     end
443
444     it 'should generate requests against the correct URIs' do
445       request = @client.generate_request(
446         :api_method => 'moderator.profiles.get',
447         :authenticated => false
448       )
449       request.to_env(Faraday.default_connection)[:url].should ===
450         'https://www.googleapis.com/moderator/v1/profiles/@me'
451     end
452
453     it 'should generate requests against the correct URIs' do
454       request = @client.generate_request(
455         :api_method => @moderator.profiles.get,
456         :authenticated => false
457       )
458       request.to_env(Faraday.default_connection)[:url].should ===
459         'https://www.googleapis.com/moderator/v1/profiles/@me'
460     end
461
462     it 'should not be able to execute requests without authorization' do
463       result = @client.execute(
464         'moderator.profiles.get',
465         {},
466         '',
467         [],
468         {:authenticated => false}
469       )
470       result.response.status.should == 401
471     end
472   end
473 end