Resolve merge conflict on gemspec
[arvados.git] / spec / google / api_client_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 'faraday'
18 require 'signet/oauth_1/client'
19 require 'google/api_client'
20 require 'google/api_client/version'
21
22 shared_examples_for 'configurable user agent' do
23   include ConnectionHelpers
24   
25   it 'should allow the user agent to be modified' do
26     client.user_agent = 'Custom User Agent/1.2.3'
27     client.user_agent.should == 'Custom User Agent/1.2.3'
28   end
29
30   it 'should allow the user agent to be set to nil' do
31     client.user_agent = nil
32     client.user_agent.should == nil
33   end
34
35   it 'should not allow the user agent to be used with bogus values' do
36     (lambda do
37       client.user_agent = 42
38       client.execute(:uri=>'https://www.google.com/')
39     end).should raise_error(TypeError)
40   end
41
42   it 'should transmit a User-Agent header when sending requests' do
43     client.user_agent = 'Custom User Agent/1.2.3'
44
45     conn = stub_connection do |stub|
46       stub.get('/') do |env|
47         headers = env[:request_headers]
48         headers.should have_key('User-Agent')
49         headers['User-Agent'].should == client.user_agent
50         [200, {}, ['']]
51       end
52     end
53     client.execute(:uri=>'https://www.google.com/', :connection => conn)
54     conn.verify
55   end
56 end
57
58 describe Google::APIClient do
59   include ConnectionHelpers
60
61   let(:client) { Google::APIClient.new(:application_name => 'API Client Tests') }
62
63   it 'should make its version number available' do
64     Google::APIClient::VERSION::STRING.should be_instance_of(String)
65   end
66
67   it 'should default to OAuth 2' do
68     Signet::OAuth2::Client.should === client.authorization
69   end
70
71   describe 'configure for no authentication' do
72     before do
73       client.authorization = nil
74     end
75     it_should_behave_like 'configurable user agent'
76   end
77     
78   describe 'configured for OAuth 1' do
79     before do
80       client.authorization = :oauth_1
81       client.authorization.token_credential_key = 'abc'
82       client.authorization.token_credential_secret = '123'
83     end
84
85     it 'should use the default OAuth1 client configuration' do
86       client.authorization.temporary_credential_uri.to_s.should ==
87         'https://www.google.com/accounts/OAuthGetRequestToken'
88       client.authorization.authorization_uri.to_s.should include(
89         'https://www.google.com/accounts/OAuthAuthorizeToken'
90       )
91       client.authorization.token_credential_uri.to_s.should ==
92         'https://www.google.com/accounts/OAuthGetAccessToken'
93       client.authorization.client_credential_key.should == 'anonymous'
94       client.authorization.client_credential_secret.should == 'anonymous'
95     end
96
97     it_should_behave_like 'configurable user agent'
98   end
99
100   describe 'configured for OAuth 2' do
101     before do
102       client.authorization = :oauth_2
103       client.authorization.access_token = '12345'
104     end
105
106     # TODO
107     it_should_behave_like 'configurable user agent'
108   end
109   
110   describe 'when executing requests' do
111     before do
112       @prediction = client.discovered_api('prediction', 'v1.2')
113       client.authorization = :oauth_2
114       @connection = stub_connection do |stub|
115         stub.post('/prediction/v1.2/training?data=12345') do |env|
116           env[:request_headers]['Authorization'].should == 'Bearer 12345'
117           [200, {}, '{}']
118         end
119       end
120     end
121
122     after do
123       @connection.verify
124     end
125     
126     it 'should use default authorization' do
127       client.authorization.access_token = "12345"
128       client.execute(  
129         :api_method => @prediction.training.insert,
130         :parameters => {'data' => '12345'},
131         :connection => @connection
132       )
133     end
134
135     it 'should use request scoped authorization when provided' do
136       client.authorization.access_token = "abcdef"
137       new_auth = Signet::OAuth2::Client.new(:access_token => '12345')
138       client.execute(  
139         :api_method => @prediction.training.insert,
140         :parameters => {'data' => '12345'},
141         :authorization => new_auth,
142         :connection => @connection
143       )
144     end
145     
146     it 'should accept options with batch/request style execute' do
147       client.authorization.access_token = "abcdef"
148       new_auth = Signet::OAuth2::Client.new(:access_token => '12345')
149       request = client.generate_request(
150         :api_method => @prediction.training.insert,
151         :parameters => {'data' => '12345'}
152       )
153       client.execute(
154         request,
155         :authorization => new_auth,
156         :connection => @connection
157       )
158     end
159     
160     
161     it 'should accept options in array style execute' do
162        client.authorization.access_token = "abcdef"
163        new_auth = Signet::OAuth2::Client.new(:access_token => '12345')
164        client.execute(  
165          @prediction.training.insert, {'data' => '12345'}, '', {},
166          { :authorization => new_auth, :connection => @connection }         
167        )
168      end
169   end  
170
171   describe 'when retiries enabled' do
172     before do
173       client.retries = 2
174     end
175
176     after do
177       @connection.verify
178     end
179     
180     it 'should follow redirects' do
181       client.authorization = nil
182       @connection = stub_connection do |stub|
183         stub.get('/foo') do |env|
184           [302, {'location' => 'https://www.google.com/bar'}, '{}']
185         end
186         stub.get('/bar') do |env|
187           [200, {}, '{}']
188         end
189       end
190
191       client.execute(  
192         :uri => 'https://www.gogole.com/foo',
193         :connection => @connection
194       )
195     end
196
197     it 'should refresh tokens on 401 tokens' do
198       client.authorization.access_token = '12345'
199       expect(client.authorization).to receive(:fetch_access_token!)
200
201       @connection = stub_connection do |stub|
202         stub.get('/foo') do |env|
203           [401, {}, '{}']
204         end
205         stub.get('/foo') do |env|
206           [200, {}, '{}']
207         end
208       end
209
210       client.execute(  
211         :uri => 'https://www.gogole.com/foo',
212         :connection => @connection
213       )
214     end
215
216     it 'should retry on 500 errors' do
217       client.authorization = nil
218
219       @connection = stub_connection do |stub|
220         stub.get('/foo') do |env|
221           [500, {}, '{}']
222         end
223         stub.get('/foo') do |env|
224           [200, {}, '{}']
225         end
226       end
227
228       client.execute(  
229         :uri => 'https://www.gogole.com/foo',
230         :connection => @connection
231       ).status.should == 200
232
233     end
234
235     it 'should fail after max retries' do
236       client.authorization = nil
237       count = 0
238       @connection = stub_connection do |stub|
239         stub.get('/foo') do |env|
240           count += 1
241           [500, {}, '{}']
242         end
243       end
244
245       client.execute(  
246         :uri => 'https://www.gogole.com/foo',
247         :connection => @connection
248       ).status.should == 500
249       count.should == 3
250     end
251
252   end  
253 end