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