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