google-api-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,40 @@
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 'json'
16
+
17
+ module Google
18
+ class APIClient
19
+ ##
20
+ # Provides a consistent interface by which to parse request and response
21
+ # content.
22
+ # TODO(mattpok): ensure floats, URLs, dates are parsed correctly
23
+ module JSONParser
24
+
25
+ def self.serialize(hash)
26
+ # JSON parser used can accept arrays as well, but we will limit
27
+ # to only allow hash to JSON string parsing to keep a simple interface
28
+ unless hash.instance_of? Hash
29
+ raise ArgumentError,
30
+ "JSON generate expected a Hash but got a #{hash.class}."
31
+ end
32
+ return JSON.generate(hash)
33
+ end
34
+
35
+ def self.parse(json_string)
36
+ return JSON.parse(json_string)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,25 @@
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
+ module Google
16
+ class APIClient
17
+ module VERSION
18
+ MAJOR = 0
19
+ MINOR = 1
20
+ TINY = 0
21
+
22
+ STRING = [MAJOR, MINOR, TINY].join('.')
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,428 @@
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, 'unconfigured' do
25
+ before do
26
+ @client = Google::APIClient.new
27
+ end
28
+
29
+ it 'should not be able to determine the discovery URI' do
30
+ (lambda do
31
+ @client.discovery_uri
32
+ end).should raise_error(ArgumentError)
33
+ end
34
+ end
35
+
36
+ describe Google::APIClient, 'configured for a bogus API' do
37
+ before do
38
+ @client = Google::APIClient.new(:service => 'bogus')
39
+ end
40
+
41
+ it 'should not be able to retrieve the discovery document' do
42
+ (lambda do
43
+ @client.discovery_document
44
+ end).should raise_error(Google::APIClient::TransmissionError)
45
+ end
46
+ end
47
+
48
+ describe Google::APIClient, 'configured for bogus authorization' do
49
+ it 'should raise a type error' do
50
+ (lambda do
51
+ Google::APIClient.new(:service => 'prediction', :authorization => 42)
52
+ end).should raise_error(TypeError)
53
+ end
54
+ end
55
+
56
+ describe Google::APIClient, 'configured for the prediction API' do
57
+ before do
58
+ @client = Google::APIClient.new(:service => 'prediction')
59
+ end
60
+
61
+ it 'should correctly determine the discovery URI' do
62
+ @client.discovery_uri.should ===
63
+ 'http://www.googleapis.com/discovery/0.1/describe?api=prediction'
64
+ end
65
+
66
+ it 'should have multiple versions available' do
67
+ @client.discovered_services.size.should > 1
68
+ end
69
+
70
+ it 'should find APIs that are in the discovery document' do
71
+ @client.discovered_service('prediction').name.should == 'prediction'
72
+ @client.discovered_service('prediction').version.should == 'v1'
73
+ @client.discovered_service(:prediction).name.should == 'prediction'
74
+ @client.discovered_service(:prediction).version.should == 'v1'
75
+ end
76
+
77
+ it 'should find API versions that are in the discovery document' do
78
+ @client.discovered_service('prediction', 'v1.1').version.should == 'v1.1'
79
+ end
80
+
81
+ it 'should not find APIs that are not in the discovery document' do
82
+ @client.discovered_service('bogus').should == nil
83
+ end
84
+
85
+ it 'should raise an error for bogus services' do
86
+ (lambda do
87
+ @client.discovered_service(42)
88
+ end).should raise_error(TypeError)
89
+ end
90
+
91
+ it 'should find methods that are in the discovery document' do
92
+ @client.discovered_method('prediction.training.insert').name.should ==
93
+ 'insert'
94
+ @client.discovered_method(:'prediction.training.insert').name.should ==
95
+ 'insert'
96
+ end
97
+
98
+ it 'should find methods for versions that are in the discovery document' do
99
+ @client.discovered_method(
100
+ 'prediction.training.delete', 'v1.1'
101
+ ).should_not == nil
102
+ end
103
+
104
+ it 'should not find methods that are not in the discovery document' do
105
+ @client.discovered_method('prediction.training.delete', 'v1').should == nil
106
+ @client.discovered_method('prediction.bogus').should == nil
107
+ end
108
+
109
+ it 'should raise an error for bogus methods' do
110
+ (lambda do
111
+ @client.discovered_method(42)
112
+ end).should raise_error(TypeError)
113
+ end
114
+
115
+ it 'should correctly determine the latest version' do
116
+ @client.latest_service_version('prediction').version.should_not == 'v1'
117
+ @client.latest_service_version(:prediction).version.should_not == 'v1'
118
+ end
119
+
120
+ it 'should raise an error for bogus services' do
121
+ (lambda do
122
+ @client.latest_service_version(42)
123
+ end).should raise_error(TypeError)
124
+ end
125
+
126
+ it 'should correctly determine the latest version' do
127
+ # Sanity check the algorithm
128
+ @client.discovered_services.clear
129
+ @client.discovered_services <<
130
+ Google::APIClient::Service.new('magic', 'v1', {})
131
+ @client.discovered_services <<
132
+ Google::APIClient::Service.new('magic', 'v1.1', {})
133
+ @client.discovered_services <<
134
+ Google::APIClient::Service.new('magic', 'v1.10', {})
135
+ @client.discovered_services <<
136
+ Google::APIClient::Service.new('magic', 'v10.0.1', {})
137
+ @client.discovered_services <<
138
+ Google::APIClient::Service.new('magic', 'v10.1', {})
139
+ @client.discovered_services <<
140
+ Google::APIClient::Service.new('magic', 'v2.1', {})
141
+ @client.discovered_services <<
142
+ Google::APIClient::Service.new('magic', 'v10.0', {})
143
+ @client.latest_service_version('magic').version.should == 'v10.1'
144
+ end
145
+
146
+ it 'should correctly determine the latest version' do
147
+ # Sanity check the algorithm
148
+ @client.discovered_services.clear
149
+ @client.discovered_services <<
150
+ Google::APIClient::Service.new('one', 'v3', {})
151
+ @client.discovered_services <<
152
+ Google::APIClient::Service.new('two', 'v1', {})
153
+ @client.discovered_services <<
154
+ Google::APIClient::Service.new('two', 'v1.1-r1c3', {})
155
+ @client.discovered_services <<
156
+ Google::APIClient::Service.new('two', 'v2', {})
157
+ @client.discovered_services <<
158
+ Google::APIClient::Service.new('two', 'v2beta1', {})
159
+ @client.latest_service_version('two').version.should == 'v2'
160
+ end
161
+
162
+ it 'should return nil for bogus service names' do
163
+ # Sanity check the algorithm
164
+ @client.latest_service_version('bogus').should == nil
165
+ end
166
+
167
+ it 'should generate valid requests' do
168
+ request = @client.generate_request(
169
+ 'prediction.training.insert',
170
+ {'query' => '12345'}
171
+ )
172
+ method, uri, headers, body = request
173
+ method.should == 'POST'
174
+ uri.should ==
175
+ 'https://www.googleapis.com/prediction/v1/training?query=12345'
176
+ (headers.inject({}) { |h,(k,v)| h[k]=v; h }).should == {}
177
+ body.should respond_to(:each)
178
+ end
179
+
180
+ it 'should generate requests against the correct URIs' do
181
+ request = @client.generate_request(
182
+ :'prediction.training.insert',
183
+ {'query' => '12345'}
184
+ )
185
+ method, uri, headers, body = request
186
+ uri.should ==
187
+ 'https://www.googleapis.com/prediction/v1/training?query=12345'
188
+ end
189
+
190
+ it 'should generate requests against the correct URIs' do
191
+ prediction = @client.discovered_service('prediction', 'v1')
192
+ request = @client.generate_request(
193
+ prediction.training.insert,
194
+ {'query' => '12345'}
195
+ )
196
+ method, uri, headers, body = request
197
+ uri.should ==
198
+ 'https://www.googleapis.com/prediction/v1/training?query=12345'
199
+ end
200
+
201
+ it 'should generate signed requests' do
202
+ @client.authorization = :oauth_1
203
+ @client.authorization.token_credential_key = '12345'
204
+ @client.authorization.token_credential_secret = '12345'
205
+ request = @client.generate_request(
206
+ 'prediction.training.insert',
207
+ {'query' => '12345'}
208
+ )
209
+ method, uri, headers, body = request
210
+ headers = headers.inject({}) { |h,(k,v)| h[k]=v; h }
211
+ headers.keys.should include('Authorization')
212
+ headers['Authorization'].should =~ /^OAuth/
213
+ end
214
+
215
+ it 'should not be able to execute improperly authorized requests' do
216
+ @client.authorization = :oauth_1
217
+ @client.authorization.token_credential_key = '12345'
218
+ @client.authorization.token_credential_secret = '12345'
219
+ response = @client.execute(
220
+ 'prediction.training.insert',
221
+ {'query' => '12345'}
222
+ )
223
+ status, headers, body = response
224
+ status.should == 401
225
+ end
226
+
227
+ it 'should raise an error for bogus methods' do
228
+ (lambda do
229
+ @client.generate_request(42)
230
+ end).should raise_error(TypeError)
231
+ end
232
+
233
+ it 'should raise an error for bogus methods' do
234
+ (lambda do
235
+ @client.generate_request(@client.discovered_service('prediction'))
236
+ end).should raise_error(TypeError)
237
+ end
238
+ end
239
+
240
+ describe Google::APIClient, 'configured for the buzz API' do
241
+ before do
242
+ @client = Google::APIClient.new(:service => 'buzz')
243
+ end
244
+
245
+ it 'should correctly determine the discovery URI' do
246
+ @client.discovery_uri.should ===
247
+ 'http://www.googleapis.com/discovery/0.1/describe?api=buzz'
248
+ end
249
+
250
+ it 'should find APIs that are in the discovery document' do
251
+ @client.discovered_service('buzz').name.should == 'buzz'
252
+ @client.discovered_service('buzz').version.should == 'v1'
253
+ end
254
+
255
+ it 'should not find APIs that are not in the discovery document' do
256
+ @client.discovered_service('bogus').should == nil
257
+ end
258
+
259
+ it 'should find methods that are in the discovery document' do
260
+ # TODO(bobaman) Fix this when the RPC names are correct
261
+ @client.discovered_method('chili.activities.list').name.should == 'list'
262
+ end
263
+
264
+ it 'should not find methods that are not in the discovery document' do
265
+ @client.discovered_method('buzz.bogus').should == nil
266
+ end
267
+
268
+ it 'should generate requests against the correct URIs' do
269
+ # TODO(bobaman) Fix this when the RPC names are correct
270
+ request = @client.generate_request(
271
+ 'chili.activities.list',
272
+ {'userId' => 'hikingfan', 'scope' => '@public'},
273
+ '',
274
+ [],
275
+ {:signed => false}
276
+ )
277
+ method, uri, headers, body = request
278
+ uri.should ==
279
+ 'https://www.googleapis.com/buzz/v1/activities/hikingfan/@public'
280
+ end
281
+
282
+ it 'should correctly validate parameters' do
283
+ # TODO(bobaman) Fix this when the RPC names are correct
284
+ (lambda do
285
+ @client.generate_request(
286
+ 'chili.activities.list',
287
+ {'alt' => 'json'},
288
+ '',
289
+ [],
290
+ {:signed => false}
291
+ )
292
+ end).should raise_error(ArgumentError)
293
+ end
294
+
295
+ it 'should correctly validate parameters' do
296
+ # TODO(bobaman) Fix this when the RPC names are correct
297
+ (lambda do
298
+ @client.generate_request(
299
+ 'chili.activities.list',
300
+ {'userId' => 'hikingfan', 'scope' => '@bogus'},
301
+ '',
302
+ [],
303
+ {:signed => false}
304
+ )
305
+ end).should raise_error(ArgumentError)
306
+ end
307
+
308
+ it 'should be able to execute requests without authorization' do
309
+ # TODO(bobaman) Fix this when the RPC names are correct
310
+ response = @client.execute(
311
+ 'chili.activities.list',
312
+ {'alt' => 'json', 'userId' => 'hikingfan', 'scope' => '@public'},
313
+ '',
314
+ [],
315
+ {:signed => false}
316
+ )
317
+ status, headers, body = response
318
+ status.should == 200
319
+ end
320
+ end
321
+
322
+ describe Google::APIClient, 'configured for the latitude API' do
323
+ before do
324
+ @client = Google::APIClient.new(:service => 'latitude')
325
+ end
326
+
327
+ it 'should correctly determine the discovery URI' do
328
+ @client.discovery_uri.should ===
329
+ 'http://www.googleapis.com/discovery/0.1/describe?api=latitude'
330
+ end
331
+
332
+ it 'should find APIs that are in the discovery document' do
333
+ @client.discovered_service('latitude').name.should == 'latitude'
334
+ @client.discovered_service('latitude').version.should == 'v1'
335
+ end
336
+
337
+ it 'should not find APIs that are not in the discovery document' do
338
+ @client.discovered_service('bogus').should == nil
339
+ end
340
+
341
+ it 'should find methods that are in the discovery document' do
342
+ @client.discovered_method('latitude.currentLocation.get').name.should ==
343
+ 'get'
344
+ end
345
+
346
+ it 'should not find methods that are not in the discovery document' do
347
+ @client.discovered_method('latitude.bogus').should == nil
348
+ end
349
+
350
+ it 'should generate requests against the correct URIs' do
351
+ request = @client.generate_request(
352
+ 'latitude.currentLocation.get',
353
+ {},
354
+ '',
355
+ [],
356
+ {:signed => false}
357
+ )
358
+ method, uri, headers, body = request
359
+ uri.should ==
360
+ 'https://www.googleapis.com/latitude/v1/currentLocation'
361
+ end
362
+
363
+ it 'should not be able to execute requests without authorization' do
364
+ response = @client.execute(
365
+ 'latitude.currentLocation.get',
366
+ {},
367
+ '',
368
+ [],
369
+ {:signed => false}
370
+ )
371
+ status, headers, body = response
372
+ status.should == 401
373
+ end
374
+ end
375
+
376
+ describe Google::APIClient, 'configured for the moderator API' do
377
+ before do
378
+ @client = Google::APIClient.new(:service => 'moderator')
379
+ end
380
+
381
+ it 'should correctly determine the discovery URI' do
382
+ @client.discovery_uri.should ===
383
+ 'http://www.googleapis.com/discovery/0.1/describe?api=moderator'
384
+ end
385
+
386
+ it 'should find APIs that are in the discovery document' do
387
+ @client.discovered_service('moderator').name.should == 'moderator'
388
+ @client.discovered_service('moderator').version.should == 'v1'
389
+ end
390
+
391
+ it 'should not find APIs that are not in the discovery document' do
392
+ @client.discovered_service('bogus').should == nil
393
+ end
394
+
395
+ it 'should find methods that are in the discovery document' do
396
+ @client.discovered_method('moderator.profiles.get').name.should ==
397
+ 'get'
398
+ end
399
+
400
+ it 'should not find methods that are not in the discovery document' do
401
+ @client.discovered_method('moderator.bogus').should == nil
402
+ end
403
+
404
+ it 'should generate requests against the correct URIs' do
405
+ request = @client.generate_request(
406
+ 'moderator.profiles.get',
407
+ {},
408
+ '',
409
+ [],
410
+ {:signed => false}
411
+ )
412
+ method, uri, headers, body = request
413
+ uri.should ==
414
+ 'https://www.googleapis.com/moderator/v1/profiles/@me'
415
+ end
416
+
417
+ it 'should not be able to execute requests without authorization' do
418
+ response = @client.execute(
419
+ 'moderator.profiles.get',
420
+ {},
421
+ '',
422
+ [],
423
+ {:signed => false}
424
+ )
425
+ status, headers, body = response
426
+ status.should == 401
427
+ end
428
+ end