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.
Files changed (39) hide show
  1. data/.autotest +12 -0
  2. data/.gitignore +3 -1
  3. data/.travis.yml +8 -0
  4. data/CHANGELOG +26 -2
  5. data/Gemfile +4 -0
  6. data/autotest/discover.rb +1 -0
  7. data/koala.gemspec +8 -8
  8. data/lib/koala/batch_operation.rb +74 -0
  9. data/lib/koala/graph_api.rb +103 -102
  10. data/lib/koala/graph_batch_api.rb +87 -0
  11. data/lib/koala/graph_collection.rb +54 -0
  12. data/lib/koala/http_services/net_http_service.rb +92 -0
  13. data/lib/koala/http_services/typhoeus_service.rb +37 -0
  14. data/lib/koala/http_services.rb +13 -113
  15. data/lib/koala/oauth.rb +181 -0
  16. data/lib/koala/realtime_updates.rb +5 -14
  17. data/lib/koala/rest_api.rb +13 -8
  18. data/lib/koala/uploadable_io.rb +137 -77
  19. data/lib/koala.rb +36 -196
  20. data/readme.md +51 -32
  21. data/spec/cases/api_base_spec.rb +4 -4
  22. data/spec/cases/graph_api_batch_spec.rb +609 -0
  23. data/spec/cases/http_services/http_service_spec.rb +87 -12
  24. data/spec/cases/http_services/net_http_service_spec.rb +259 -77
  25. data/spec/cases/http_services/typhoeus_service_spec.rb +29 -21
  26. data/spec/cases/koala_spec.rb +55 -0
  27. data/spec/cases/oauth_spec.rb +1 -1
  28. data/spec/cases/realtime_updates_spec.rb +3 -3
  29. data/spec/cases/test_users_spec.rb +1 -1
  30. data/spec/cases/uploadable_io_spec.rb +56 -14
  31. data/spec/fixtures/cat.m4v +0 -0
  32. data/spec/fixtures/mock_facebook_responses.yml +100 -5
  33. data/spec/spec_helper.rb +2 -1
  34. data/spec/support/graph_api_shared_examples.rb +106 -35
  35. data/spec/support/json_testing_fix.rb +18 -0
  36. data/spec/support/mock_http_service.rb +57 -56
  37. data/spec/support/rest_api_shared_examples.rb +131 -7
  38. data/spec/support/setup_mocks_or_live.rb +3 -4
  39. 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