changed readme to direct issue reporting on github
[arvados.git] / spec / google / api_client / batch_spec.rb
1 # Copyright 2012 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 require 'google/api_client'
17 require 'google/api_client/version'
18
19 describe Google::APIClient::BatchRequest do
20   CLIENT = Google::APIClient.new(:application_name => 'API Client Tests') unless defined?(CLIENT)
21
22   after do
23     # Reset client to not-quite-pristine state
24     CLIENT.key = nil
25     CLIENT.user_ip = nil
26   end
27
28   it 'should raise an error if making an empty batch request' do
29     batch = Google::APIClient::BatchRequest.new
30
31     (lambda do
32       CLIENT.execute(batch)
33     end).should raise_error(Google::APIClient::BatchError)
34   end
35
36   it 'should allow query parameters in batch requests' do
37     batch = Google::APIClient::BatchRequest.new
38     batch.add(:uri => 'https://example.com', :parameters => {
39       'a' => '12345'
40     })
41     method, uri, headers, body = batch.to_http_request
42     body.read.should include("/?a=12345")
43   end
44
45   describe 'with the discovery API' do
46     before do
47       CLIENT.authorization = nil
48       @discovery = CLIENT.discovered_api('discovery', 'v1')
49     end
50
51     describe 'with two valid requests' do
52       before do
53         @call1 = {
54           :api_method => @discovery.apis.get_rest,
55           :parameters => {
56             'api' => 'adsense',
57             'version' => 'v1'
58           }
59         }
60
61         @call2 = {
62           :api_method => @discovery.apis.get_rest,
63           :parameters => {
64             'api' => 'discovery',
65             'version' => 'v1'
66           }
67         }
68       end
69
70       it 'should execute both when using a global callback' do
71         block_called = 0
72         ids = ['first_call', 'second_call']
73         expected_ids = ids.clone
74         batch = Google::APIClient::BatchRequest.new do |result|
75           block_called += 1
76           result.status.should == 200
77           expected_ids.should include(result.response.call_id)
78           expected_ids.delete(result.response.call_id)
79         end
80
81         batch.add(@call1, ids[0])
82         batch.add(@call2, ids[1])
83
84         CLIENT.execute(batch)
85         block_called.should == 2
86       end
87
88       it 'should execute both when using individual callbacks' do
89         batch = Google::APIClient::BatchRequest.new
90
91         call1_returned, call2_returned = false, false
92         batch.add(@call1) do |result|
93           call1_returned = true
94           result.status.should == 200
95         end
96         batch.add(@call2) do |result|
97           call2_returned = true
98           result.status.should == 200
99         end
100
101         CLIENT.execute(batch)
102         call1_returned.should == true
103         call2_returned.should == true
104       end
105
106       it 'should raise an error if using the same call ID more than once' do
107         batch = Google::APIClient::BatchRequest.new
108
109         (lambda do
110           batch.add(@call1, 'my_id')
111           batch.add(@call2, 'my_id')
112         end).should raise_error(Google::APIClient::BatchError)
113       end
114     end
115
116     describe 'with a valid request and an invalid one' do
117       before do
118         @call1 = {
119           :api_method => @discovery.apis.get_rest,
120           :parameters => {
121             'api' => 'adsense',
122             'version' => 'v1'
123           }
124         }
125
126         @call2 = {
127           :api_method => @discovery.apis.get_rest,
128           :parameters => {
129             'api' => 0,
130             'version' => 1
131           }
132         }
133       end
134
135       it 'should execute both when using a global callback' do
136         block_called = 0
137         ids = ['first_call', 'second_call']
138         expected_ids = ids.clone
139         batch = Google::APIClient::BatchRequest.new do |result|
140           block_called += 1
141           expected_ids.should include(result.response.call_id)
142           expected_ids.delete(result.response.call_id)
143           if result.response.call_id == ids[0]
144             result.status.should == 200
145           else
146             result.status.should >= 400
147             result.status.should < 500
148           end
149         end
150
151         batch.add(@call1, ids[0])
152         batch.add(@call2, ids[1])
153
154         CLIENT.execute(batch)
155         block_called.should == 2
156       end
157
158       it 'should execute both when using individual callbacks' do
159         batch = Google::APIClient::BatchRequest.new
160
161         call1_returned, call2_returned = false, false
162         batch.add(@call1) do |result|
163           call1_returned = true
164           result.status.should == 200
165         end
166         batch.add(@call2) do |result|
167           call2_returned = true
168           result.status.should >= 400
169           result.status.should < 500
170         end
171
172         CLIENT.execute(batch)
173         call1_returned.should == true
174         call2_returned.should == true
175       end
176     end
177   end
178
179   describe 'with the calendar API' do
180     before do
181       CLIENT.authorization = nil
182       @calendar = CLIENT.discovered_api('calendar', 'v3')
183     end
184
185     describe 'with two valid requests' do
186       before do
187         event1 = {
188           'summary' => 'Appointment 1',
189           'location' => 'Somewhere',
190           'start' => {
191             'dateTime' => '2011-01-01T10:00:00.000-07:00'
192           },
193           'end' => {
194             'dateTime' => '2011-01-01T10:25:00.000-07:00'
195           },
196           'attendees' => [
197             {
198               'email' => 'myemail@mydomain.tld'
199             }
200           ]
201         }
202
203         event2 = {
204           'summary' => 'Appointment 2',
205           'location' => 'Somewhere as well',
206           'start' => {
207             'dateTime' => '2011-01-02T10:00:00.000-07:00'
208           },
209           'end' => {
210             'dateTime' => '2011-01-02T10:25:00.000-07:00'
211           },
212           'attendees' => [
213             {
214               'email' => 'myemail@mydomain.tld'
215             }
216           ]
217         }
218
219         @call1 = {
220           :api_method => @calendar.events.insert,
221           :parameters => {'calendarId' => 'myemail@mydomain.tld'},
222           :body => MultiJson.dump(event1),
223           :headers => {'Content-Type' => 'application/json'}
224         }
225
226         @call2 = {
227           :api_method => @calendar.events.insert,
228           :parameters => {'calendarId' => 'myemail@mydomain.tld'},
229           :body => MultiJson.dump(event2),
230           :headers => {'Content-Type' => 'application/json'}
231         }
232       end
233
234       it 'should convert to a correct HTTP request' do
235         batch = Google::APIClient::BatchRequest.new { |result| }
236         batch.add(@call1, '1').add(@call2, '2')
237         request = batch.to_env(CLIENT.connection)
238         boundary = Google::APIClient::BatchRequest::BATCH_BOUNDARY
239         request[:method].to_s.downcase.should == 'post'
240         request[:url].to_s.should == 'https://www.googleapis.com/batch'
241         request[:request_headers]['Content-Type'].should == "multipart/mixed;boundary=#{boundary}"
242         # TODO - Fix headers
243         #expected_body = /--#{Regexp.escape(boundary)}\nContent-Type: +application\/http\nContent-ID: +<[\w-]+\+1>\n\nPOST +https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/myemail@mydomain.tld\/events +HTTP\/1.1\nContent-Type: +application\/json\n\n#{Regexp.escape(@call1[:body])}\n\n--#{boundary}\nContent-Type: +application\/http\nContent-ID: +<[\w-]+\+2>\n\nPOST +https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/myemail@mydomain.tld\/events HTTP\/1.1\nContent-Type: +application\/json\n\n#{Regexp.escape(@call2[:body])}\n\n--#{Regexp.escape(boundary)}--/
244         #request[:body].read.gsub("\r", "").should =~ expected_body
245       end
246     end
247     
248   end
249 end