3 # Copyright 2013 Google Inc.
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
19 require 'google/api_client'
20 require 'google/api_client/service'
22 fixtures_path = File.expand_path('../../../fixtures', __FILE__)
24 describe Google::APIClient::Service do
25 include ConnectionHelpers
27 APPLICATION_NAME = 'API Client Tests'
29 it 'should error out when called without an API name or version' do
31 Google::APIClient::Service.new
32 end).should raise_error(ArgumentError)
35 it 'should error out when called without an API version' do
37 Google::APIClient::Service.new('foo')
38 end).should raise_error(ArgumentError)
41 it 'should error out when the options hash is not a hash' do
43 Google::APIClient::Service.new('foo', 'v1', 42)
44 end).should raise_error(ArgumentError)
47 describe 'with the AdSense Management API' do
49 it 'should make a valid call for a method with no parameters' do
50 conn = stub_connection do |stub|
51 stub.get('/adsense/v1.3/adclients') do |env|
54 adsense = Google::APIClient::Service.new(
58 :application_name => APPLICATION_NAME,
59 :authenticated => false,
64 req = adsense.adclients.list.execute()
68 it 'should make a valid call for a method with parameters' do
69 conn = stub_connection do |stub|
70 stub.get('/adsense/v1.3/adclients/1/adunits') do |env|
73 adsense = Google::APIClient::Service.new(
77 :application_name => APPLICATION_NAME,
78 :authenticated => false,
82 req = adsense.adunits.list(:adClientId => '1').execute()
85 it 'should make a valid call for a deep method' do
86 conn = stub_connection do |stub|
87 stub.get('/adsense/v1.3/accounts/1/adclients') do |env|
90 adsense = Google::APIClient::Service.new(
94 :application_name => APPLICATION_NAME,
95 :authenticated => false,
99 req = adsense.accounts.adclients.list(:accountId => '1').execute()
102 describe 'with no connection' do
104 @adsense = Google::APIClient::Service.new('adsense', 'v1.3',
105 {:application_name => APPLICATION_NAME})
108 it 'should return a resource when using a valid resource name' do
109 @adsense.accounts.should be_a(Google::APIClient::Service::Resource)
112 it 'should throw an error when using an invalid resource name' do
114 @adsense.invalid_resource
115 end).should raise_error
118 it 'should return a request when using a valid method name' do
119 req = @adsense.adclients.list
120 req.should be_a(Google::APIClient::Service::Request)
121 req.method.id.should == 'adsense.adclients.list'
122 req.parameters.should be_nil
125 it 'should throw an error when using an invalid method name' do
127 @adsense.adclients.invalid_method
128 end).should raise_error
131 it 'should return a valid request with parameters' do
132 req = @adsense.adunits.list(:adClientId => '1')
133 req.should be_a(Google::APIClient::Service::Request)
134 req.method.id.should == 'adsense.adunits.list'
135 req.parameters.should_not be_nil
136 req.parameters[:adClientId].should == '1'
141 describe 'with the Prediction API' do
143 it 'should make a valid call with an object body' do
144 conn = stub_connection do |stub|
145 stub.post('/prediction/v1.5/trainedmodels?project=1') do |env|
146 env.body.should == '{"id":"1"}'
149 prediction = Google::APIClient::Service.new(
153 :application_name => APPLICATION_NAME,
154 :authenticated => false,
158 req = prediction.trainedmodels.insert(:project => '1').body({'id' => '1'}).execute()
162 it 'should make a valid call with a text body' do
163 conn = stub_connection do |stub|
164 stub.post('/prediction/v1.5/trainedmodels?project=1') do |env|
165 env.body.should == '{"id":"1"}'
168 prediction = Google::APIClient::Service.new(
172 :application_name => APPLICATION_NAME,
173 :authenticated => false,
177 req = prediction.trainedmodels.insert(:project => '1').body('{"id":"1"}').execute()
181 describe 'with no connection' do
183 @prediction = Google::APIClient::Service.new('prediction', 'v1.5',
184 {:application_name => APPLICATION_NAME})
187 it 'should return a valid request with a body' do
188 req = @prediction.trainedmodels.insert(:project => '1').body({'id' => '1'})
189 req.should be_a(Google::APIClient::Service::Request)
190 req.method.id.should == 'prediction.trainedmodels.insert'
191 req.body.should == {'id' => '1'}
192 req.parameters.should_not be_nil
193 req.parameters[:project].should == '1'
196 it 'should return a valid request with a body when using resource name' do
197 req = @prediction.trainedmodels.insert(:project => '1').training({'id' => '1'})
198 req.should be_a(Google::APIClient::Service::Request)
199 req.method.id.should == 'prediction.trainedmodels.insert'
200 req.training.should == {'id' => '1'}
201 req.parameters.should_not be_nil
202 req.parameters[:project].should == '1'
207 describe 'with the Drive API' do
211 'title' => 'My movie',
212 'description' => 'The best home movie ever made'
214 @file = File.expand_path('files/sample.txt', fixtures_path)
215 @media = Google::APIClient::UploadIO.new(@file, 'text/plain')
218 it 'should make a valid call with an object body and media upload' do
219 conn = stub_connection do |stub|
220 stub.post('/upload/drive/v1/files?uploadType=multipart') do |env|
221 env.body.should be_a Faraday::CompositeReadIO
224 drive = Google::APIClient::Service.new(
228 :application_name => APPLICATION_NAME,
229 :authenticated => false,
233 req = drive.files.insert(:uploadType => 'multipart').body(@metadata).media(@media).execute()
237 describe 'with no connection' do
239 @drive = Google::APIClient::Service.new('drive', 'v1',
240 {:application_name => APPLICATION_NAME})
243 it 'should return a valid request with a body and media upload' do
244 req = @drive.files.insert(:uploadType => 'multipart').body(@metadata).media(@media)
245 req.should be_a(Google::APIClient::Service::Request)
246 req.method.id.should == 'drive.files.insert'
247 req.body.should == @metadata
248 req.media.should == @media
249 req.parameters.should_not be_nil
250 req.parameters[:uploadType].should == 'multipart'
253 it 'should return a valid request with a body and media upload when using resource name' do
254 req = @drive.files.insert(:uploadType => 'multipart').file(@metadata).media(@media)
255 req.should be_a(Google::APIClient::Service::Request)
256 req.method.id.should == 'drive.files.insert'
257 req.file.should == @metadata
258 req.media.should == @media
259 req.parameters.should_not be_nil
260 req.parameters[:uploadType].should == 'multipart'
265 describe 'with the Discovery API' do
266 it 'should make a valid end-to-end request' do
267 discovery = Google::APIClient::Service.new('discovery', 'v1',
268 {:application_name => APPLICATION_NAME, :authenticated => false})
269 result = discovery.apis.get_rest(:api => 'discovery', :version => 'v1').execute
270 result.should_not be_nil
271 result.data.name.should == 'discovery'
272 result.data.version.should == 'v1'
278 describe Google::APIClient::Service::Result do
280 describe 'with the plus API' do
282 @plus = Google::APIClient::Service.new('plus', 'v1',
283 {:application_name => APPLICATION_NAME})
284 @reference = Google::APIClient::Reference.new({
285 :api_method => @plus.activities.list.method,
288 'collection' => 'public',
292 @request = @plus.activities.list(:userId => 'me', :collection => 'public',
296 @response = double("response")
297 @response.stub(:status).and_return(200)
298 @response.stub(:headers).and_return({
300 'x-google-apiary-auth-scopes' =>
301 'https://www.googleapis.com/auth/plus.me',
302 'content-type' => 'application/json; charset=UTF-8',
303 'date' => 'Mon, 23 Apr 2012 00:00:00 GMT',
304 'cache-control' => 'private, max-age=0, must-revalidate, no-transform',
306 'connection' => 'close'
310 describe 'with a next page token' do
312 @body = <<-END_OF_STRING
314 "kind": "plus#activityFeed",
316 "nextPageToken": "NEXT+PAGE+TOKEN",
317 "selfLink": "https://www.googleapis.com/plus/v1/people/foo/activities/public?",
318 "nextLink": "https://www.googleapis.com/plus/v1/people/foo/activities/public?maxResults=20&pageToken=NEXT%2BPAGE%2BTOKEN",
319 "title": "Plus Public Activity Feed for ",
320 "updated": "2012-04-23T00:00:00.000Z",
325 @response.stub(:body).and_return(@body)
326 base_result = Google::APIClient::Result.new(@reference, @response)
327 @result = Google::APIClient::Service::Result.new(@request, base_result)
330 it 'should indicate a successful response' do
331 @result.error?.should be_false
334 it 'should return the correct next page token' do
335 @result.next_page_token.should == 'NEXT+PAGE+TOKEN'
338 it 'generate a correct request when calling next_page' do
339 next_page_request = @result.next_page
340 next_page_request.parameters.should include('pageToken')
341 next_page_request.parameters['pageToken'].should == 'NEXT+PAGE+TOKEN'
342 @request.parameters.each_pair do |param, value|
343 next_page_request.parameters[param].should == value
347 it 'should return content type correctly' do
348 @result.media_type.should == 'application/json'
351 it 'should return the body correctly' do
352 @result.body.should == @body
355 it 'should return the result data correctly' do
356 @result.data?.should be_true
357 @result.data.class.to_s.should ==
358 'Google::APIClient::Schema::Plus::V1::ActivityFeed'
359 @result.data.kind.should == 'plus#activityFeed'
360 @result.data.etag.should == 'FOO'
361 @result.data.nextPageToken.should == 'NEXT+PAGE+TOKEN'
362 @result.data.selfLink.should ==
363 'https://www.googleapis.com/plus/v1/people/foo/activities/public?'
364 @result.data.nextLink.should ==
365 'https://www.googleapis.com/plus/v1/people/foo/activities/public?' +
366 'maxResults=20&pageToken=NEXT%2BPAGE%2BTOKEN'
367 @result.data.title.should == 'Plus Public Activity Feed for '
368 @result.data.id.should == "123456790"
369 @result.data.items.should be_empty
373 describe 'without a next page token' do
375 @body = <<-END_OF_STRING
377 "kind": "plus#activityFeed",
379 "selfLink": "https://www.googleapis.com/plus/v1/people/foo/activities/public?",
380 "title": "Plus Public Activity Feed for ",
381 "updated": "2012-04-23T00:00:00.000Z",
386 @response.stub(:body).and_return(@body)
387 base_result = Google::APIClient::Result.new(@reference, @response)
388 @result = Google::APIClient::Service::Result.new(@request, base_result)
391 it 'should not return a next page token' do
392 @result.next_page_token.should == nil
395 it 'should return content type correctly' do
396 @result.media_type.should == 'application/json'
399 it 'should return the body correctly' do
400 @result.body.should == @body
403 it 'should return the result data correctly' do
404 @result.data?.should be_true
405 @result.data.class.to_s.should ==
406 'Google::APIClient::Schema::Plus::V1::ActivityFeed'
407 @result.data.kind.should == 'plus#activityFeed'
408 @result.data.etag.should == 'FOO'
409 @result.data.selfLink.should ==
410 'https://www.googleapis.com/plus/v1/people/foo/activities/public?'
411 @result.data.title.should == 'Plus Public Activity Feed for '
412 @result.data.id.should == "123456790"
413 @result.data.items.should be_empty
417 describe 'with JSON error response' do
419 @body = <<-END_OF_STRING
425 "reason": "parseError",
426 "message": "Parse Error"
430 "message": "Parse Error"
434 @response.stub(:body).and_return(@body)
435 @response.stub(:status).and_return(400)
436 base_result = Google::APIClient::Result.new(@reference, @response)
437 @result = Google::APIClient::Service::Result.new(@request, base_result)
440 it 'should return error status correctly' do
441 @result.error?.should be_true
444 it 'should return the correct error message' do
445 @result.error_message.should == 'Parse Error'
448 it 'should return the body correctly' do
449 @result.body.should == @body
453 describe 'with 204 No Content response' do
455 @response.stub(:body).and_return('')
456 @response.stub(:status).and_return(204)
457 @response.stub(:headers).and_return({})
458 base_result = Google::APIClient::Result.new(@reference, @response)
459 @result = Google::APIClient::Service::Result.new(@request, base_result)
462 it 'should indicate no data is available' do
463 @result.data?.should be_false
466 it 'should return nil for data' do
467 @result.data.should == nil
470 it 'should return nil for media_type' do
471 @result.media_type.should == nil