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