Major update, primarily to add pagination support.
[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 require 'signet/oauth_1/client'
18 require 'httpadapter/adapters/net_http'
19
20 require 'google/api_client'
21 require 'google/api_client/version'
22 require 'google/api_client/parsers/json_parser'
23
24 describe Google::APIClient do
25   before do
26     @client = Google::APIClient.new
27   end
28
29   it 'should raise a type error for bogus authorization' do
30     (lambda do
31       Google::APIClient.new(:authorization => 42)
32     end).should raise_error(TypeError)
33   end
34
35   it 'should not be able to retrieve the discovery document for a bogus API' do
36     (lambda do
37       @client.discovery_document('bogus')
38     end).should raise_error(Google::APIClient::TransmissionError)
39     (lambda do
40       @client.discovered_api('bogus')
41     end).should raise_error(Google::APIClient::TransmissionError)
42   end
43
44   it 'should raise an error for bogus services' do
45     (lambda do
46       @client.discovered_api(42)
47     end).should raise_error(TypeError)
48   end
49
50   it 'should raise an error for bogus services' do
51     (lambda do
52       @client.preferred_version(42)
53     end).should raise_error(TypeError)
54   end
55
56   it 'should raise an error for bogus methods' do
57     (lambda do
58       @client.generate_request(42)
59     end).should raise_error(TypeError)
60   end
61
62   it 'should not return a preferred version for bogus service names' do
63     @client.preferred_version('bogus').should == nil
64   end
65
66   describe 'with the prediction API' do
67     before do
68       @client.authorization = nil
69       # The prediction API no longer exposes a v1, so we have to be
70       # careful about looking up the wrong API version.
71       @prediction = @client.discovered_api('prediction', 'v1.2')
72     end
73
74     it 'should correctly determine the discovery URI' do
75       @client.discovery_uri('prediction').should ===
76         'https://www.googleapis.com/discovery/v1/apis/prediction/v1/rest'
77     end
78
79     it 'should correctly generate API objects' do
80       @client.discovered_api('prediction', 'v1.2').name.should == 'prediction'
81       @client.discovered_api('prediction', 'v1.2').version.should == 'v1.2'
82       @client.discovered_api(:prediction, 'v1.2').name.should == 'prediction'
83       @client.discovered_api(:prediction, 'v1.2').version.should == 'v1.2'
84     end
85
86     it 'should discover methods' do
87       @client.discovered_method(
88         'prediction.training.insert', 'prediction', 'v1.2'
89       ).name.should == 'insert'
90       @client.discovered_method(
91         :'prediction.training.insert', :prediction, 'v1.2'
92       ).name.should == 'insert'
93       @client.discovered_method(
94         'prediction.training.delete', 'prediction', 'v1.2'
95       ).name.should == 'delete'
96     end
97
98     it 'should not find methods that are not in the discovery document' do
99       @client.discovered_method(
100         'prediction.bogus', 'prediction', 'v1.2'
101       ).should == nil
102     end
103
104     it 'should raise an error for bogus methods' do
105       (lambda do
106         @client.discovered_method(42, 'prediction', 'v1.2')
107       end).should raise_error(TypeError)
108     end
109
110     it 'should raise an error for bogus methods' do
111       (lambda do
112         @client.generate_request(@client.discovered_api('prediction', 'v1.2'))
113       end).should raise_error(TypeError)
114     end
115
116     it 'should correctly determine the preferred version' do
117       @client.preferred_version('prediction').version.should_not == 'v1'
118       @client.preferred_version(:prediction).version.should_not == 'v1'
119     end
120
121     it 'should generate valid requests' do
122       request = @client.generate_request(
123         :api_method => @prediction.training.insert,
124         :parameters => {'data' => '12345', }
125       )
126       method, uri, headers, body = request
127       method.should == 'POST'
128       uri.should ==
129         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
130       (headers.inject({}) { |h,(k,v)| h[k]=v; h }).should == {}
131       body.should respond_to(:each)
132     end
133
134     it 'should generate requests against the correct URIs' do
135       request = @client.generate_request(
136         :api_method => @prediction.training.insert,
137         :parameters => {'data' => '12345'}
138       )
139       method, uri, headers, body = request
140       uri.should ==
141         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
142     end
143
144     it 'should generate requests against the correct URIs' do
145       request = @client.generate_request(
146         :api_method => @prediction.training.insert,
147         :parameters => {'data' => '12345'}
148       )
149       method, uri, headers, body = request
150       uri.should ==
151         'https://www.googleapis.com/prediction/v1.2/training?data=12345'
152     end
153
154     it 'should allow modification to the base URIs for testing purposes' do
155       prediction = @client.discovered_api('prediction', 'v1.2')
156       prediction.method_base =
157         'https://testing-domain.googleapis.com/prediction/v1.2/'
158       request = @client.generate_request(
159         :api_method => prediction.training.insert,
160         :parameters => {'data' => '123'}
161       )
162       method, uri, headers, body = request
163       uri.should == (
164         'https://testing-domain.googleapis.com/' +
165         'prediction/v1.2/training?data=123'
166       )
167     end
168
169     it 'should generate OAuth 1 requests' do
170       @client.authorization = :oauth_1
171       @client.authorization.token_credential_key = '12345'
172       @client.authorization.token_credential_secret = '12345'
173       request = @client.generate_request(
174         :api_method => @prediction.training.insert,
175         :parameters => {'data' => '12345'}
176       )
177       method, uri, headers, body = request
178       headers = headers.inject({}) { |h,(k,v)| h[k]=v; h }
179       headers.keys.should include('Authorization')
180       headers['Authorization'].should =~ /^OAuth/
181     end
182
183     it 'should generate OAuth 2 requests' do
184       @client.authorization = :oauth_2
185       @client.authorization.access_token = '12345'
186       request = @client.generate_request(
187         :api_method => @prediction.training.insert,
188         :parameters => {'data' => '12345'}
189       )
190       method, uri, headers, body = request
191       headers = headers.inject({}) { |h,(k,v)| h[k]=v; h }
192       headers.keys.should include('Authorization')
193       headers['Authorization'].should =~ /^OAuth/
194     end
195
196     it 'should not be able to execute improperly authorized requests' do
197       @client.authorization = :oauth_1
198       @client.authorization.token_credential_key = '12345'
199       @client.authorization.token_credential_secret = '12345'
200       result = @client.execute(
201         @prediction.training.insert,
202         {'data' => '12345'}
203       )
204       status, headers, body = result.response
205       status.should == 401
206     end
207
208     it 'should not be able to execute improperly authorized requests' do
209       @client.authorization = :oauth_2
210       @client.authorization.access_token = '12345'
211       result = @client.execute(
212         @prediction.training.insert,
213         {'data' => '12345'}
214       )
215       status, headers, body = result.response
216       status.should == 401
217     end
218
219     it 'should not be able to execute improperly authorized requests' do
220       (lambda do
221         @client.authorization = :oauth_1
222         @client.authorization.token_credential_key = '12345'
223         @client.authorization.token_credential_secret = '12345'
224         result = @client.execute!(
225           @prediction.training.insert,
226           {'data' => '12345'}
227         )
228       end).should raise_error(Google::APIClient::ClientError)
229     end
230
231     it 'should not be able to execute improperly authorized requests' do
232       (lambda do
233         @client.authorization = :oauth_2
234         @client.authorization.access_token = '12345'
235         result = @client.execute!(
236           @prediction.training.insert,
237           {'data' => '12345'}
238         )
239       end).should raise_error(Google::APIClient::ClientError)
240     end
241   end
242
243   describe 'with the buzz API' do
244     before do
245       @client.authorization = nil
246       @buzz = @client.discovered_api('buzz')
247     end
248
249     it 'should correctly determine the discovery URI' do
250       @client.discovery_uri('buzz').should ===
251         'https://www.googleapis.com/discovery/v1/apis/buzz/v1/rest'
252     end
253
254     it 'should find APIs that are in the discovery document' do
255       @client.discovered_api('buzz').name.should == 'buzz'
256       @client.discovered_api('buzz').version.should == 'v1'
257       @client.discovered_api(:buzz).name.should == 'buzz'
258       @client.discovered_api(:buzz).version.should == 'v1'
259     end
260
261     it 'should find methods that are in the discovery document' do
262       # TODO(bobaman) Fix this when the RPC names are correct
263       @client.discovered_method(
264         'chili.activities.list', 'buzz'
265       ).name.should == 'list'
266     end
267
268     it 'should not find methods that are not in the discovery document' do
269       @client.discovered_method('buzz.bogus', 'buzz').should == nil
270     end
271
272     it 'should fail for string RPC names that do not match API name' do
273       (lambda do
274         @client.generate_request(
275           :api_method => 'chili.activities.list',
276           :parameters => {'alt' => 'json'},
277           :authenticated => false
278         )
279       end).should raise_error(Google::APIClient::TransmissionError)
280     end
281
282     it 'should generate requests against the correct URIs' do
283       request = @client.generate_request(
284         :api_method => @buzz.activities.list,
285         :parameters => {'userId' => 'hikingfan', 'scope' => '@public'},
286         :authenticated => false
287       )
288       method, uri, headers, body = request
289       uri.should ==
290         'https://www.googleapis.com/buzz/v1/activities/hikingfan/@public'
291     end
292
293     it 'should correctly validate parameters' do
294       (lambda do
295         @client.generate_request(
296           :api_method => @buzz.activities.list,
297           :parameters => {'alt' => 'json'},
298           :authenticated => false
299         )
300       end).should raise_error(ArgumentError)
301     end
302
303     it 'should correctly validate parameters' do
304       (lambda do
305         @client.generate_request(
306           :api_method => @buzz.activities.list,
307           :parameters => {'userId' => 'hikingfan', 'scope' => '@bogus'},
308           :authenticated => false
309         )
310       end).should raise_error(ArgumentError)
311     end
312
313     it 'should be able to execute requests without authorization' do
314       result = @client.execute(
315         @buzz.activities.list,
316         {'alt' => 'json', 'userId' => 'hikingfan', 'scope' => '@public'},
317         '',
318         [],
319         :authenticated => false
320       )
321       status, headers, body = result.response
322       status.should == 200
323     end
324
325     it 'should not be able to execute requests without authorization' do
326       result = @client.execute(
327         @buzz.activities.list,
328         'alt' => 'json', 'userId' => '@me', 'scope' => '@self'
329       )
330       status, headers, body = result.response
331       status.should == 401
332     end
333   end
334
335   describe 'with the latitude API' do
336     before do
337       @client.authorization = nil
338       @latitude = @client.discovered_api('latitude')
339     end
340
341     it 'should correctly determine the discovery URI' do
342       @client.discovery_uri('latitude').should ===
343         'https://www.googleapis.com/discovery/v1/apis/latitude/v1/rest'
344     end
345
346     it 'should find APIs that are in the discovery document' do
347       @client.discovered_api('latitude').name.should == 'latitude'
348       @client.discovered_api('latitude').version.should == 'v1'
349     end
350
351     it 'should find methods that are in the discovery document' do
352       @client.discovered_method(
353         'latitude.currentLocation.get', 'latitude'
354       ).name.should == 'get'
355     end
356
357     it 'should not find methods that are not in the discovery document' do
358       @client.discovered_method('latitude.bogus', 'latitude').should == nil
359     end
360
361     it 'should generate requests against the correct URIs' do
362       request = @client.generate_request(
363         :api_method => 'latitude.currentLocation.get',
364         :authenticated => false
365       )
366       method, uri, headers, body = request
367       uri.should ==
368         'https://www.googleapis.com/latitude/v1/currentLocation'
369     end
370
371     it 'should generate requests against the correct URIs' do
372       request = @client.generate_request(
373         :api_method => @latitude.current_location.get,
374         :authenticated => false
375       )
376       method, uri, headers, body = request
377       uri.should ==
378         'https://www.googleapis.com/latitude/v1/currentLocation'
379     end
380
381     it 'should not be able to execute requests without authorization' do
382       result = @client.execute(
383         :api_method => 'latitude.currentLocation.get',
384         :authenticated => false
385       )
386       status, headers, body = result.response
387       status.should == 401
388     end
389   end
390
391   describe 'with the moderator API' do
392     before do
393       @client.authorization = nil
394       @moderator = @client.discovered_api('moderator')
395     end
396
397     it 'should correctly determine the discovery URI' do
398       @client.discovery_uri('moderator').should ===
399         'https://www.googleapis.com/discovery/v1/apis/moderator/v1/rest'
400     end
401
402     it 'should find APIs that are in the discovery document' do
403       @client.discovered_api('moderator').name.should == 'moderator'
404       @client.discovered_api('moderator').version.should == 'v1'
405     end
406
407     it 'should find methods that are in the discovery document' do
408       @client.discovered_method(
409         'moderator.profiles.get', 'moderator'
410       ).name.should == 'get'
411     end
412
413     it 'should not find methods that are not in the discovery document' do
414       @client.discovered_method('moderator.bogus', 'moderator').should == nil
415     end
416
417     it 'should generate requests against the correct URIs' do
418       request = @client.generate_request(
419         :api_method => 'moderator.profiles.get',
420         :authenticated => false
421       )
422       method, uri, headers, body = request
423       uri.should ==
424         'https://www.googleapis.com/moderator/v1/profiles/@me'
425     end
426
427     it 'should generate requests against the correct URIs' do
428       request = @client.generate_request(
429         :api_method => @moderator.profiles.get,
430         :authenticated => false
431       )
432       method, uri, headers, body = request
433       uri.should ==
434         'https://www.googleapis.com/moderator/v1/profiles/@me'
435     end
436
437     it 'should not be able to execute requests without authorization' do
438       result = @client.execute(
439         'moderator.profiles.get',
440         {},
441         '',
442         [],
443         {:authenticated => false}
444       )
445       status, headers, body = result.response
446       status.should == 401
447     end
448   end
449 end