koala 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +12 -0
- data/.gitignore +3 -1
- data/.travis.yml +8 -0
- data/CHANGELOG +26 -2
- data/Gemfile +4 -0
- data/autotest/discover.rb +1 -0
- data/koala.gemspec +8 -8
- data/lib/koala/batch_operation.rb +74 -0
- data/lib/koala/graph_api.rb +103 -102
- data/lib/koala/graph_batch_api.rb +87 -0
- data/lib/koala/graph_collection.rb +54 -0
- data/lib/koala/http_services/net_http_service.rb +92 -0
- data/lib/koala/http_services/typhoeus_service.rb +37 -0
- data/lib/koala/http_services.rb +13 -113
- data/lib/koala/oauth.rb +181 -0
- data/lib/koala/realtime_updates.rb +5 -14
- data/lib/koala/rest_api.rb +13 -8
- data/lib/koala/uploadable_io.rb +137 -77
- data/lib/koala.rb +36 -196
- data/readme.md +51 -32
- data/spec/cases/api_base_spec.rb +4 -4
- data/spec/cases/graph_api_batch_spec.rb +609 -0
- data/spec/cases/http_services/http_service_spec.rb +87 -12
- data/spec/cases/http_services/net_http_service_spec.rb +259 -77
- data/spec/cases/http_services/typhoeus_service_spec.rb +29 -21
- data/spec/cases/koala_spec.rb +55 -0
- data/spec/cases/oauth_spec.rb +1 -1
- data/spec/cases/realtime_updates_spec.rb +3 -3
- data/spec/cases/test_users_spec.rb +1 -1
- data/spec/cases/uploadable_io_spec.rb +56 -14
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/mock_facebook_responses.yml +100 -5
- data/spec/spec_helper.rb +2 -1
- data/spec/support/graph_api_shared_examples.rb +106 -35
- data/spec/support/json_testing_fix.rb +18 -0
- data/spec/support/mock_http_service.rb +57 -56
- data/spec/support/rest_api_shared_examples.rb +131 -7
- data/spec/support/setup_mocks_or_live.rb +3 -4
- metadata +34 -47
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
4
|
+
include LiveTestingDataHelper
|
|
5
|
+
before :each do
|
|
6
|
+
@api = Koala::Facebook::GraphAPI.new(@token)
|
|
7
|
+
# app API
|
|
8
|
+
@oauth_data = $testing_data["oauth_test_data"]
|
|
9
|
+
@app_id = @oauth_data["app_id"]
|
|
10
|
+
@app_access_token = @oauth_data["app_access_token"]
|
|
11
|
+
@app_api = Koala::Facebook::GraphAPI.new(@app_access_token)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "BatchOperations" do
|
|
15
|
+
before :each do
|
|
16
|
+
@args = {
|
|
17
|
+
:url => "my url",
|
|
18
|
+
:args => {:a => 2, :b => 3},
|
|
19
|
+
:method => "get",
|
|
20
|
+
:access_token => "12345",
|
|
21
|
+
:http_options => {},
|
|
22
|
+
:post_processing => lambda { }
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "#new" do
|
|
27
|
+
it "makes http_options accessible" do
|
|
28
|
+
Koala::Facebook::BatchOperation.new(@args).http_options.should == @args[:http_options]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "makes post_processing accessible" do
|
|
32
|
+
Koala::Facebook::BatchOperation.new(@args).post_processing.should == @args[:post_processing]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "makes access_token accessible" do
|
|
36
|
+
Koala::Facebook::BatchOperation.new(@args).access_token.should == @args[:access_token]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "doesn't change the original http_options" do
|
|
40
|
+
@args[:http_options][:name] = "baz2"
|
|
41
|
+
expected = @args[:http_options].dup
|
|
42
|
+
Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)
|
|
43
|
+
@args[:http_options].should == expected
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "leaves the file array nil by default" do
|
|
47
|
+
Koala::Facebook::BatchOperation.new(@args).files.should be_nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "raises a KoalaError if no access token supplied" do
|
|
51
|
+
expect { Koala::Facebook::BatchOperation.new(@args.merge(:access_token => nil)) }.to raise_exception(Koala::KoalaError)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe "when supplied binary files" do
|
|
55
|
+
before :each do
|
|
56
|
+
@binary = stub("Binary file")
|
|
57
|
+
@uploadable_io = stub("UploadableIO 1")
|
|
58
|
+
|
|
59
|
+
@batch_queue = []
|
|
60
|
+
Koala::Facebook::GraphAPI.stub(:batch_calls).and_return(@batch_queue)
|
|
61
|
+
|
|
62
|
+
Koala::UploadableIO.stub(:new).with(@binary).and_return(@uploadable_io)
|
|
63
|
+
Koala::UploadableIO.stub(:binary_content?).and_return(false)
|
|
64
|
+
Koala::UploadableIO.stub(:binary_content?).with(@binary).and_return(true)
|
|
65
|
+
Koala::UploadableIO.stub(:binary_content?).with(@uploadable_io).and_return(true)
|
|
66
|
+
@uploadable_io.stub(:is_a?).with(Koala::UploadableIO).and_return(true)
|
|
67
|
+
|
|
68
|
+
@args[:method] = "post" # files are always post
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "adds binary files to the files attribute as UploadableIOs" do
|
|
72
|
+
@args[:args].merge!("source" => @binary)
|
|
73
|
+
batch_op = Koala::Facebook::BatchOperation.new(@args)
|
|
74
|
+
batch_op.files.should_not be_nil
|
|
75
|
+
batch_op.files.find {|k, v| v == @uploadable_io}.should_not be_nil
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "works if supplied an UploadableIO as an argument" do
|
|
79
|
+
# as happens with put_picture at the moment
|
|
80
|
+
@args[:args].merge!("source" => @uploadable_io)
|
|
81
|
+
batch_op = Koala::Facebook::BatchOperation.new(@args)
|
|
82
|
+
batch_op.files.should_not be_nil
|
|
83
|
+
batch_op.files.find {|k, v| v == @uploadable_io}.should_not be_nil
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "assigns each binary parameter unique name" do
|
|
87
|
+
@args[:args].merge!("source" => @binary, "source2" => @binary)
|
|
88
|
+
batch_op = Koala::Facebook::BatchOperation.new(@args)
|
|
89
|
+
# if the name wasn't unique, there'd just be one item
|
|
90
|
+
batch_op.files.should have(2).items
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "assigns each binary parameter unique name across batch requests" do
|
|
94
|
+
@args[:args].merge!("source" => @binary, "source2" => @binary)
|
|
95
|
+
batch_op = Koala::Facebook::BatchOperation.new(@args)
|
|
96
|
+
# simulate the batch operation, since it's used in determination
|
|
97
|
+
@batch_queue << batch_op
|
|
98
|
+
batch_op2 = Koala::Facebook::BatchOperation.new(@args)
|
|
99
|
+
@batch_queue << batch_op2
|
|
100
|
+
# if the name wasn't unique, we should have < 4 items since keys would be the same
|
|
101
|
+
batch_op.files.merge(batch_op2.files).should have(4).items
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "removes the value from the arguments" do
|
|
105
|
+
@args[:args].merge!("source" => @binary)
|
|
106
|
+
Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)[:body].should_not =~ /source=/
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe ".to_batch_params" do
|
|
113
|
+
describe "handling arguments and URLs" do
|
|
114
|
+
shared_examples_for "request with no body" do
|
|
115
|
+
it "adds the args to the URL string, with ? if no args previously present" do
|
|
116
|
+
test_args = "foo"
|
|
117
|
+
@args[:url] = url = "/"
|
|
118
|
+
Koala.http_service.stub(:encode_params).and_return(test_args)
|
|
119
|
+
|
|
120
|
+
Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)[:relative_url].should == "#{url}?#{test_args}"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "adds the args to the URL string, with & if args previously present" do
|
|
124
|
+
test_args = "foo"
|
|
125
|
+
@args[:url] = url = "/?a=2"
|
|
126
|
+
Koala.http_service.stub(:encode_params).and_return(test_args)
|
|
127
|
+
|
|
128
|
+
Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)[:relative_url].should == "#{url}&#{test_args}"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "adds nothing to the URL string if there are no args to be added" do
|
|
132
|
+
@args[:args] = {}
|
|
133
|
+
Koala::Facebook::BatchOperation.new(@args).to_batch_params(@args[:access_token])[:relative_url].should == @args[:url]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "adds nothing to the body" do
|
|
137
|
+
Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)[:body].should be_nil
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
shared_examples_for "requests with a body param" do
|
|
142
|
+
it "sets the body to the encoded args string, if there are args" do
|
|
143
|
+
test_args = "foo"
|
|
144
|
+
Koala.http_service.stub(:encode_params).and_return(test_args)
|
|
145
|
+
|
|
146
|
+
Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)[:body].should == test_args
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "does not set the body if there are no args" do
|
|
150
|
+
test_args = ""
|
|
151
|
+
Koala.http_service.stub(:encode_params).and_return(test_args)
|
|
152
|
+
Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)[:body].should be_nil
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
it "doesn't change the url" do
|
|
157
|
+
test_args = "foo"
|
|
158
|
+
Koala.http_service.stub(:encode_params).and_return(test_args)
|
|
159
|
+
|
|
160
|
+
Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)[:relative_url].should == @args[:url]
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
context "for get operations" do
|
|
165
|
+
before :each do
|
|
166
|
+
@args[:method] = :get
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it_should_behave_like "request with no body"
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
context "for delete operations" do
|
|
173
|
+
before :each do
|
|
174
|
+
@args[:method] = :delete
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it_should_behave_like "request with no body"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
context "for get operations" do
|
|
181
|
+
before :each do
|
|
182
|
+
@args[:method] = :put
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it_should_behave_like "requests with a body param"
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
context "for delete operations" do
|
|
189
|
+
before :each do
|
|
190
|
+
@args[:method] = :post
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it_should_behave_like "requests with a body param"
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it "includes the access token if the token is not the main one for the request" do
|
|
198
|
+
params = Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)
|
|
199
|
+
params[:relative_url].should =~ /access_token=#{@args[:access_token]}/
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it "includes the other arguments if the token is not the main one for the request" do
|
|
203
|
+
@args[:args] = {:a => 2}
|
|
204
|
+
params = Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)
|
|
205
|
+
params[:relative_url].should =~ /a=2/
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "does not include the access token if the token is the main one for the request" do
|
|
209
|
+
params = Koala::Facebook::BatchOperation.new(@args).to_batch_params(@args[:access_token])
|
|
210
|
+
params[:relative_url].should_not =~ /access_token=#{@args[:access_token]}/
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "includes the other arguments if the token is the main one for the request" do
|
|
214
|
+
@args[:args] = {:a => 2}
|
|
215
|
+
params = Koala::Facebook::BatchOperation.new(@args).to_batch_params(@args[:access_token])
|
|
216
|
+
params[:relative_url].should =~ /a=2/
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
it "includes any arguments passed as http_options[:batch_args]" do
|
|
220
|
+
batch_args = {:name => "baz", :headers => {:some_param => true}}
|
|
221
|
+
@args[:http_options][:batch_args] = batch_args
|
|
222
|
+
params = Koala::Facebook::BatchOperation.new(@args).to_batch_params(nil)
|
|
223
|
+
params.should include(batch_args)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it "includes the method" do
|
|
227
|
+
params = Koala::Facebook::BatchOperation.new(@args).to_batch_params(@args[:access_token])
|
|
228
|
+
params[:method].should == @args[:method].to_s
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "works with nil http_options" do
|
|
232
|
+
expect { Koala::Facebook::BatchOperation.new(@args.merge(:http_options => nil)).to_batch_params(nil) }.not_to raise_exception
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
it "works with nil args" do
|
|
236
|
+
expect { Koala::Facebook::BatchOperation.new(@args.merge(:args => nil)).to_batch_params(nil) }.not_to raise_exception
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
describe "with binary files" do
|
|
240
|
+
before :each do
|
|
241
|
+
@binary = stub("Binary file")
|
|
242
|
+
Koala::UploadableIO.stub(:binary_content?).and_return(false)
|
|
243
|
+
Koala::UploadableIO.stub(:binary_content?).with(@binary).and_return(true)
|
|
244
|
+
@uploadable_io = stub("UploadableIO")
|
|
245
|
+
Koala::UploadableIO.stub(:new).with(@binary).and_return(@uploadable_io)
|
|
246
|
+
@uploadable_io.stub(:is_a?).with(Koala::UploadableIO).and_return(true)
|
|
247
|
+
|
|
248
|
+
@batch_queue = []
|
|
249
|
+
Koala::Facebook::GraphAPI.stub(:batch_calls).and_return(@batch_queue)
|
|
250
|
+
|
|
251
|
+
@args[:method] = "post" # files are always post
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it "adds file identifiers as attached_files in a comma-separated list" do
|
|
255
|
+
@args[:args].merge!("source" => @binary, "source2" => @binary)
|
|
256
|
+
batch_op = Koala::Facebook::BatchOperation.new(@args)
|
|
257
|
+
file_ids = batch_op.files.find_all {|k, v| v == @uploadable_io}.map {|k, v| k}
|
|
258
|
+
params = batch_op.to_batch_params(nil)
|
|
259
|
+
params[:attached_files].should == file_ids.join(",")
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
describe "GraphAPI batch interface" do
|
|
267
|
+
|
|
268
|
+
it "returns nothing for a batch operation" do
|
|
269
|
+
Koala.stub(:make_request).and_return(Koala::Response.new(200, "[]", {}))
|
|
270
|
+
@api.batch do |batch_api|
|
|
271
|
+
batch_api.get_object('me').should be_nil
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
describe "#batch" do
|
|
276
|
+
before :each do
|
|
277
|
+
@fake_response = Koala::Response.new(200, "[]", {})
|
|
278
|
+
Koala.stub(:make_request).and_return(@fake_response)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
describe "making the request" do
|
|
282
|
+
context "with no calls" do
|
|
283
|
+
it "does not make any requests if batch_calls is empty" do
|
|
284
|
+
Koala.should_not_receive(:make_request)
|
|
285
|
+
@api.batch {|batch_api|}
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it "returns []" do
|
|
289
|
+
@api.batch {|batch_api|}.should == []
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it "includes the first operation's access token as the main one in the args" do
|
|
294
|
+
access_token = "foo"
|
|
295
|
+
Koala.should_receive(:make_request).with(anything, hash_including("access_token" => access_token), anything, anything).and_return(@fake_response)
|
|
296
|
+
Koala::Facebook::GraphAPI.new(access_token).batch do |batch_api|
|
|
297
|
+
batch_api.get_object('me')
|
|
298
|
+
batch_api.get_object('me', {}, {'access_token' => 'bar'})
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it "sets args['batch'] to a json'd map of all the batch params" do
|
|
303
|
+
access_token = "bar"
|
|
304
|
+
op = Koala::Facebook::BatchOperation.new(:access_token => access_token, :method => :get, :url => "/")
|
|
305
|
+
op.stub(:to_batch_params).and_return({:a => 2})
|
|
306
|
+
Koala::Facebook::BatchOperation.stub(:new).and_return(op)
|
|
307
|
+
|
|
308
|
+
# two requests should generate two batch operations
|
|
309
|
+
expected = MultiJson.encode([op.to_batch_params(access_token), op.to_batch_params(access_token)])
|
|
310
|
+
Koala.should_receive(:make_request).with(anything, hash_including("batch" => expected), anything, anything).and_return(@fake_response)
|
|
311
|
+
Koala::Facebook::GraphAPI.new(access_token).batch do |batch_api|
|
|
312
|
+
batch_api.get_object('me')
|
|
313
|
+
batch_api.get_object('me')
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it "adds any files from the batch operations to the arguments" do
|
|
318
|
+
# stub the batch operation
|
|
319
|
+
# we test above to ensure that files are properly assimilated into the BatchOperation instance
|
|
320
|
+
# right now, we want to make sure that batch_api handles them properly
|
|
321
|
+
@key = "file0_0"
|
|
322
|
+
@uploadable_io = stub("UploadableIO")
|
|
323
|
+
batch_op = stub("Koala Batch Operation", :files => {@key => @uploadable_io}, :to_batch_params => {}, :access_token => "foo")
|
|
324
|
+
Koala::Facebook::BatchOperation.stub(:new).and_return(batch_op)
|
|
325
|
+
|
|
326
|
+
Koala.should_receive(:make_request).with(anything, hash_including(@key => @uploadable_io), anything, anything).and_return(@fake_response)
|
|
327
|
+
Koala::Facebook::GraphAPI.new("bar").batch do |batch_api|
|
|
328
|
+
batch_api.put_picture("path/to/file", "image/jpeg")
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
it "preserves operation order" do
|
|
333
|
+
access_token = "bar"
|
|
334
|
+
# two requests should generate two batch operations
|
|
335
|
+
Koala.should_receive(:make_request) do |url, args, method, options|
|
|
336
|
+
# test the batch operations to make sure they appear in the right order
|
|
337
|
+
(args ||= {})["batch"].should =~ /.*me\/farglebarg.*otheruser\/bababa/
|
|
338
|
+
@fake_response
|
|
339
|
+
end
|
|
340
|
+
Koala::Facebook::GraphAPI.new(access_token).batch do |batch_api|
|
|
341
|
+
batch_api.get_connections('me', "farglebarg")
|
|
342
|
+
batch_api.get_connections('otheruser', "bababa")
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it "makes a POST request" do
|
|
347
|
+
Koala.should_receive(:make_request).with(anything, anything, "post", anything).and_return(@fake_response)
|
|
348
|
+
Koala::Facebook::GraphAPI.new("foo").batch do |batch_api|
|
|
349
|
+
batch_api.get_object('me')
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
it "makes a request to /" do
|
|
354
|
+
Koala.should_receive(:make_request).with("/", anything, anything, anything).and_return(@fake_response)
|
|
355
|
+
Koala::Facebook::GraphAPI.new("foo").batch do |batch_api|
|
|
356
|
+
batch_api.get_object('me')
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
it "includes any http options specified at the top level" do
|
|
361
|
+
http_options = {"a" => "baz"}
|
|
362
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(http_options)).and_return(@fake_response)
|
|
363
|
+
Koala::Facebook::GraphAPI.new("foo").batch(http_options) do |batch_api|
|
|
364
|
+
batch_api.get_object('me')
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
describe "processing the request" do
|
|
370
|
+
it "throws an error if the response is not 200" do
|
|
371
|
+
Koala.stub(:make_request).and_return(Koala::Response.new(500, "[]", {}))
|
|
372
|
+
expect { Koala::Facebook::GraphAPI.new("foo").batch do |batch_api|
|
|
373
|
+
batch_api.get_object('me')
|
|
374
|
+
end }.to raise_exception(Koala::Facebook::APIError)
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
it "throws an error if the response is a Batch API-style error" do
|
|
378
|
+
Koala.stub(:make_request).and_return(Koala::Response.new(200, '{"error":190,"error_description":"Error validating access token."}', {}))
|
|
379
|
+
expect { Koala::Facebook::GraphAPI.new("foo").batch do |batch_api|
|
|
380
|
+
batch_api.get_object('me')
|
|
381
|
+
end }.to raise_exception(Koala::Facebook::APIError)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
it "returns the result status if http_component is status" do
|
|
385
|
+
Koala.stub(:make_request).and_return(Koala::Response.new(200, '[{"code":203,"headers":[{"name":"Content-Type","value":"text/javascript; charset=UTF-8"}],"body":"{\"id\":\"1234\"}"}]', {}))
|
|
386
|
+
result = @api.batch do |batch_api|
|
|
387
|
+
batch_api.get_object("koppel", {}, :http_component => :status)
|
|
388
|
+
end
|
|
389
|
+
result[0].should == 203
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
it "returns the result headers as a hash if http_component is headers" do
|
|
393
|
+
Koala.stub(:make_request).and_return(Koala::Response.new(200, '[{"code":203,"headers":[{"name":"Content-Type","value":"text/javascript; charset=UTF-8"}],"body":"{\"id\":\"1234\"}"}]', {}))
|
|
394
|
+
result = @api.batch do |batch_api|
|
|
395
|
+
batch_api.get_object("koppel", {}, :http_component => :headers)
|
|
396
|
+
end
|
|
397
|
+
result[0].should == {"Content-Type" => "text/javascript; charset=UTF-8"}
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
it "is thread safe" do
|
|
402
|
+
# ensure batch operations on one thread don't affect those on another
|
|
403
|
+
thread_one_count = 0
|
|
404
|
+
thread_two_count = 0
|
|
405
|
+
first_count = 20
|
|
406
|
+
second_count = 10
|
|
407
|
+
|
|
408
|
+
Koala.stub(:make_request).and_return(@fake_response)
|
|
409
|
+
|
|
410
|
+
thread1 = Thread.new do
|
|
411
|
+
@api.batch do |batch_api|
|
|
412
|
+
first_count.times {|i| batch_api.get_object("me"); sleep(0.01) }
|
|
413
|
+
thread_one_count = batch_api.batch_calls.count
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
thread2 = Thread.new do
|
|
418
|
+
@api.batch do |batch_api|
|
|
419
|
+
second_count.times {|i| batch_api.get_object("me"); sleep(0.01) }
|
|
420
|
+
thread_two_count = batch_api.batch_calls.count
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
thread1.join
|
|
425
|
+
thread2.join
|
|
426
|
+
|
|
427
|
+
thread_one_count.should == first_count
|
|
428
|
+
thread_two_count.should == second_count
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
describe "usage tests" do
|
|
434
|
+
it "can get two results at once" do
|
|
435
|
+
me, koppel = @api.batch do |batch_api|
|
|
436
|
+
batch_api.get_object('me')
|
|
437
|
+
batch_api.get_object('koppel')
|
|
438
|
+
end
|
|
439
|
+
me['id'].should_not be_nil
|
|
440
|
+
koppel['id'].should_not be_nil
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
it "works with GraphAndRestAPI instances" do
|
|
444
|
+
me, koppel = Koala::Facebook::GraphAndRestAPI.new(@api.access_token).batch do |batch_api|
|
|
445
|
+
batch_api.get_object('me')
|
|
446
|
+
batch_api.get_object('koppel')
|
|
447
|
+
end
|
|
448
|
+
me['id'].should_not be_nil
|
|
449
|
+
koppel['id'].should_not be_nil
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
it 'should be able to make mixed calls inside of a batch' do
|
|
453
|
+
me, friends = @api.batch do |batch_api|
|
|
454
|
+
batch_api.get_object('me')
|
|
455
|
+
batch_api.get_connections('me', 'friends')
|
|
456
|
+
end
|
|
457
|
+
me['id'].should_not be_nil
|
|
458
|
+
friends.should be_an(Array)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
it 'should be able to make a get_picture call inside of a batch' do
|
|
462
|
+
pictures = @api.batch do |batch_api|
|
|
463
|
+
batch_api.get_picture('me')
|
|
464
|
+
end
|
|
465
|
+
pictures.first.should_not be_empty
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
it "should handle requests for two different tokens" do
|
|
469
|
+
me, insights = @api.batch do |batch_api|
|
|
470
|
+
batch_api.get_object('me')
|
|
471
|
+
batch_api.get_connections(@app_id, 'insights', {}, {"access_token" => @app_api.access_token})
|
|
472
|
+
end
|
|
473
|
+
me['id'].should_not be_nil
|
|
474
|
+
insights.should be_an(Array)
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
it "inserts errors in the appropriate place, without breaking other results" do
|
|
478
|
+
failed_insights, koppel = @api.batch do |batch_api|
|
|
479
|
+
batch_api.get_connections(@app_id, 'insights')
|
|
480
|
+
batch_api.get_object("koppel", {}, {"access_token" => @app_api.access_token})
|
|
481
|
+
end
|
|
482
|
+
failed_insights.should be_a(Koala::Facebook::APIError)
|
|
483
|
+
koppel["id"].should_not be_nil
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
it "handles different request methods" do
|
|
487
|
+
result = @api.put_wall_post("Hello, world, from the test suite batch API!")
|
|
488
|
+
wall_post = result["id"]
|
|
489
|
+
|
|
490
|
+
wall_post, koppel = @api.batch do |batch_api|
|
|
491
|
+
batch_api.put_like(wall_post)
|
|
492
|
+
batch_api.delete_object(wall_post)
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
it "allows FQL" do
|
|
497
|
+
result = @api.batch do |batch_api|
|
|
498
|
+
batch_api.graph_call("method/fql.query", {:query=>"select name from user where uid=4"}, "post")
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
fql_result = result[0]
|
|
502
|
+
fql_result[0].should be_a(Hash)
|
|
503
|
+
fql_result[0]["name"].should == "Mark Zuckerberg"
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
describe "binary files" do
|
|
507
|
+
it "posts binary files" do
|
|
508
|
+
file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))
|
|
509
|
+
|
|
510
|
+
Koala::Facebook::BatchOperation.instance_variable_set(:@identifier, 0)
|
|
511
|
+
result = @api.batch do |batch_api|
|
|
512
|
+
batch_api.put_picture(file)
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
@temporary_object_id = result[0]["id"]
|
|
516
|
+
@temporary_object_id.should_not be_nil
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
it "posts binary files with multiple requests" do
|
|
520
|
+
file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))
|
|
521
|
+
|
|
522
|
+
Koala::Facebook::BatchOperation.instance_variable_set(:@identifier, 0)
|
|
523
|
+
results = @api.batch do |batch_api|
|
|
524
|
+
batch_api.put_picture(file)
|
|
525
|
+
batch_api.put_picture(file, {}, "koppel")
|
|
526
|
+
end
|
|
527
|
+
results[0]["id"].should_not be_nil
|
|
528
|
+
results[1]["id"].should_not be_nil
|
|
529
|
+
end
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
describe "relating requests" do
|
|
533
|
+
it "allows you create relationships between requests without omit_response_on_success" do
|
|
534
|
+
results = @api.batch do |batch_api|
|
|
535
|
+
batch_api.get_connections("me", "friends", {:limit => 5}, :batch_args => {:name => "get-friends"})
|
|
536
|
+
batch_api.get_objects("{result=get-friends:$.data.*.id}")
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
results[0].should be_nil
|
|
540
|
+
results[1].should be_an(Hash)
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
it "allows you create relationships between requests with omit_response_on_success" do
|
|
544
|
+
results = @api.batch do |batch_api|
|
|
545
|
+
batch_api.get_connections("me", "friends", {:limit => 5}, :batch_args => {:name => "get-friends", :omit_response_on_success => false})
|
|
546
|
+
batch_api.get_objects("{result=get-friends:$.data.*.id}")
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
results[0].should be_an(Array)
|
|
550
|
+
results[1].should be_an(Hash)
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
it "allows you to create dependencies" do
|
|
554
|
+
me, koppel = @api.batch do |batch_api|
|
|
555
|
+
batch_api.get_object("me", {}, :batch_args => {:name => "getme"})
|
|
556
|
+
batch_api.get_object("koppel", {}, :batch_args => {:depends_on => "getme"})
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
me.should be_nil # gotcha! it's omitted because it's a successfully-executed dependency
|
|
560
|
+
koppel["id"].should_not be_nil
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
it "properly handles dependencies that fail" do
|
|
564
|
+
data, koppel = @api.batch do |batch_api|
|
|
565
|
+
batch_api.get_connections(@app_id, 'insights', {}, :batch_args => {:name => "getdata"})
|
|
566
|
+
batch_api.get_object("koppel", {}, :batch_args => {:depends_on => "getdata"})
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
data.should be_a(Koala::Facebook::APIError)
|
|
570
|
+
koppel.should be_nil
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
it "throws an error for badly-constructed request relationships" do
|
|
574
|
+
expect {
|
|
575
|
+
@api.batch do |batch_api|
|
|
576
|
+
batch_api.get_connections("me", "friends", {:limit => 5})
|
|
577
|
+
batch_api.get_objects("{result=i-dont-exist:$.data.*.id}")
|
|
578
|
+
end
|
|
579
|
+
}.to raise_exception(Koala::Facebook::APIError)
|
|
580
|
+
end
|
|
581
|
+
end
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
describe "new interface" do
|
|
585
|
+
it "includes a deprecation warning on GraphAPI" do
|
|
586
|
+
begin
|
|
587
|
+
Koala::Facebook::GraphAPI.batch do
|
|
588
|
+
end
|
|
589
|
+
rescue NoMethodError => @err
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
# verify the message points people to the wiki page
|
|
593
|
+
@err.should
|
|
594
|
+
@err.message.should =~ /https\:\/\/github.com\/arsduo\/koala\/wiki\/Batch-requests/
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
it "includes a deprecation warning on GraphAndRESTAPI" do
|
|
598
|
+
begin
|
|
599
|
+
Koala::Facebook::GraphAndRestAPI.batch do
|
|
600
|
+
end
|
|
601
|
+
rescue NoMethodError => @err
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
# verify the message points people to the wiki page
|
|
605
|
+
@err.should
|
|
606
|
+
@err.message.should =~ /https\:\/\/github.com\/arsduo\/koala\/wiki\/Batch-requests/
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
end
|