koala 2.4.0 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/test.yml +32 -0
- data/Gemfile +5 -3
- data/ISSUE_TEMPLATE +25 -0
- data/PULL_REQUEST_TEMPLATE +11 -0
- data/changelog.md +161 -4
- data/code_of_conduct.md +64 -12
- data/koala.gemspec +5 -1
- data/lib/koala/api/batch_operation.rb +3 -6
- data/lib/koala/api/{graph_api.rb → graph_api_methods.rb} +29 -104
- data/lib/koala/api/graph_batch_api.rb +112 -65
- data/lib/koala/api/graph_collection.rb +19 -12
- data/lib/koala/api/graph_error_checker.rb +4 -3
- data/lib/koala/api.rb +65 -26
- data/lib/koala/configuration.rb +56 -0
- data/lib/koala/errors.rb +22 -2
- data/lib/koala/http_service/request.rb +133 -0
- data/lib/koala/http_service/response.rb +6 -4
- data/lib/koala/http_service/uploadable_io.rb +0 -5
- data/lib/koala/http_service.rb +29 -76
- data/lib/koala/oauth.rb +8 -8
- data/lib/koala/realtime_updates.rb +26 -21
- data/lib/koala/test_users.rb +9 -8
- data/lib/koala/version.rb +1 -1
- data/lib/koala.rb +7 -9
- data/readme.md +83 -109
- data/spec/cases/api_spec.rb +176 -69
- data/spec/cases/configuration_spec.rb +11 -0
- data/spec/cases/error_spec.rb +16 -3
- data/spec/cases/graph_api_batch_spec.rb +75 -44
- data/spec/cases/graph_api_spec.rb +15 -29
- data/spec/cases/graph_collection_spec.rb +47 -34
- data/spec/cases/graph_error_checker_spec.rb +31 -2
- data/spec/cases/http_service/request_spec.rb +250 -0
- data/spec/cases/http_service/response_spec.rb +24 -0
- data/spec/cases/http_service_spec.rb +126 -286
- data/spec/cases/koala_spec.rb +7 -5
- data/spec/cases/oauth_spec.rb +41 -2
- data/spec/cases/realtime_updates_spec.rb +51 -13
- data/spec/cases/test_users_spec.rb +56 -2
- data/spec/cases/uploadable_io_spec.rb +31 -31
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/facebook_data.yml +4 -6
- data/spec/fixtures/mock_facebook_responses.yml +41 -78
- data/spec/fixtures/vcr_cassettes/app_test_accounts.yml +97 -0
- data/spec/integration/graph_collection_spec.rb +8 -5
- data/spec/spec_helper.rb +2 -2
- data/spec/support/graph_api_shared_examples.rb +152 -337
- data/spec/support/koala_test.rb +11 -13
- data/spec/support/mock_http_service.rb +11 -14
- data/spec/support/uploadable_io_shared_examples.rb +4 -4
- metadata +47 -48
- data/.autotest +0 -12
- data/.travis.yml +0 -17
- data/Guardfile +0 -6
- data/autotest/discover.rb +0 -1
- data/lib/koala/api/rest_api.rb +0 -135
- data/lib/koala/http_service/multipart_request.rb +0 -41
- data/spec/cases/multipart_request_spec.rb +0 -65
- data/spec/support/rest_api_shared_examples.rb +0 -168
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'json' unless Hash.respond_to?(:to_json)
|
2
3
|
|
3
4
|
describe "Koala::Facebook::GraphAPI in batch mode" do
|
4
5
|
|
@@ -58,11 +59,11 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
58
59
|
@batch_queue = []
|
59
60
|
allow(Koala::Facebook::API).to receive(:batch_calls).and_return(@batch_queue)
|
60
61
|
|
61
|
-
allow(Koala::UploadableIO).to receive(:new).with(@binary).and_return(@uploadable_io)
|
62
|
-
allow(Koala::UploadableIO).to receive(:binary_content?).and_return(false)
|
63
|
-
allow(Koala::UploadableIO).to receive(:binary_content?).with(@binary).and_return(true)
|
64
|
-
allow(Koala::UploadableIO).to receive(:binary_content?).with(@uploadable_io).and_return(true)
|
65
|
-
allow(@uploadable_io).to receive(:is_a?).with(Koala::UploadableIO).and_return(true)
|
62
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:new).with(@binary).and_return(@uploadable_io)
|
63
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).and_return(false)
|
64
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).with(@binary).and_return(true)
|
65
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).with(@uploadable_io).and_return(true)
|
66
|
+
allow(@uploadable_io).to receive(:is_a?).with(Koala::HTTPService::UploadableIO).and_return(true)
|
66
67
|
|
67
68
|
@args[:method] = "post" # files are always post
|
68
69
|
end
|
@@ -243,11 +244,11 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
243
244
|
describe "with binary files" do
|
244
245
|
before :each do
|
245
246
|
@binary = double("Binary file")
|
246
|
-
allow(Koala::UploadableIO).to receive(:binary_content?).and_return(false)
|
247
|
-
allow(Koala::UploadableIO).to receive(:binary_content?).with(@binary).and_return(true)
|
247
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).and_return(false)
|
248
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).with(@binary).and_return(true)
|
248
249
|
@uploadable_io = double("UploadableIO")
|
249
|
-
allow(Koala::UploadableIO).to receive(:new).with(@binary).and_return(@uploadable_io)
|
250
|
-
allow(@uploadable_io).to receive(:is_a?).with(Koala::UploadableIO).and_return(true)
|
250
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:new).with(@binary).and_return(@uploadable_io)
|
251
|
+
allow(@uploadable_io).to receive(:is_a?).with(Koala::HTTPService::UploadableIO).and_return(true)
|
251
252
|
|
252
253
|
@batch_queue = []
|
253
254
|
allow(Koala::Facebook::API).to receive(:batch_calls).and_return(@batch_queue)
|
@@ -322,7 +323,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
322
323
|
allow(Koala::Facebook::GraphBatchAPI::BatchOperation).to receive(:new).and_return(op)
|
323
324
|
|
324
325
|
# two requests should generate two batch operations
|
325
|
-
expected =
|
326
|
+
expected = JSON.dump([op.to_batch_params(access_token, nil), op.to_batch_params(access_token, nil)])
|
326
327
|
expect(Koala).to receive(:make_request).with(anything, hash_including("batch" => expected), anything, anything).and_return(@fake_response)
|
327
328
|
Koala::Facebook::API.new(access_token).batch do |batch_api|
|
328
329
|
batch_api.get_object('me')
|
@@ -468,17 +469,57 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
468
469
|
expect(thread_one_count).to eq(first_count)
|
469
470
|
expect(thread_two_count).to eq(second_count)
|
470
471
|
end
|
472
|
+
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
describe '#big_batches' do
|
477
|
+
before :each do
|
478
|
+
payload = [{code: 200, headers: [{name: "Content-Type", value: "text/javascript; charset=UTF-8"}], body: "{\"id\":\"1234\"}"}]
|
479
|
+
allow(Koala).to receive(:make_request) do |_request, args, _verb, _options|
|
480
|
+
request_count = JSON.parse(args['batch']).length
|
481
|
+
expect(request_count).to be <= 50 # check FB's limit
|
482
|
+
Koala::HTTPService::Response.new(200, (payload * request_count).to_json, {})
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
it 'stays within fb limits' do
|
487
|
+
count_calls = 0
|
488
|
+
expected_calls = 100
|
489
|
+
@api.batch do |batch_api|
|
490
|
+
expected_calls.times { |_i| batch_api.get_object('me') { |_ret| count_calls += 1 } }
|
491
|
+
end
|
492
|
+
|
493
|
+
expect(count_calls).to eq(expected_calls)
|
494
|
+
end
|
495
|
+
|
496
|
+
it 'is recursive safe' do
|
497
|
+
# ensure batch operations whose callbacks call batch operations don't resubmit
|
498
|
+
call_count = 0
|
499
|
+
iterations = 60
|
500
|
+
@api.batch do |batch_api|
|
501
|
+
# must do enough calls to provoke a batch submission
|
502
|
+
iterations.times { |_i|
|
503
|
+
batch_api.get_object('me') { |_ret|
|
504
|
+
call_count += 1
|
505
|
+
batch_api.get_object('me') { |_ret|
|
506
|
+
call_count += 1
|
507
|
+
}
|
508
|
+
}
|
509
|
+
}
|
510
|
+
end
|
511
|
+
expect(call_count).to eq(2 * iterations)
|
471
512
|
end
|
472
513
|
end
|
473
514
|
|
474
515
|
describe "usage tests" do
|
475
516
|
it "gets two results at once" do
|
476
|
-
me,
|
517
|
+
me, barackobama = @api.batch do |batch_api|
|
477
518
|
batch_api.get_object('me')
|
478
519
|
batch_api.get_object(KoalaTest.user1)
|
479
520
|
end
|
480
521
|
expect(me['id']).not_to be_nil
|
481
|
-
expect(
|
522
|
+
expect(barackobama['id']).not_to be_nil
|
482
523
|
end
|
483
524
|
|
484
525
|
it 'makes mixed calls inside of a batch' do
|
@@ -486,7 +527,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
486
527
|
batch_api.get_object('me')
|
487
528
|
batch_api.get_connections('me', 'friends')
|
488
529
|
end
|
489
|
-
expect(friends).to be_a(Koala::Facebook::GraphCollection)
|
530
|
+
expect(friends).to be_a(Koala::Facebook::API::GraphCollection)
|
490
531
|
end
|
491
532
|
|
492
533
|
it 'turns pageable results into GraphCollections' do
|
@@ -502,7 +543,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
502
543
|
pictures = @api.batch do |batch_api|
|
503
544
|
batch_api.get_picture('me')
|
504
545
|
end
|
505
|
-
expect(pictures.first).to match(/
|
546
|
+
expect(pictures.first).to match(/https\:\/\//) # works both live & stubbed
|
506
547
|
end
|
507
548
|
|
508
549
|
it 'takes an after processing block for a get_picture call inside of a batch' do
|
@@ -510,40 +551,40 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
510
551
|
@api.batch do |batch_api|
|
511
552
|
batch_api.get_picture('me') { |pic| picture = pic }
|
512
553
|
end
|
513
|
-
expect(picture).to match(/
|
554
|
+
expect(picture).to match(/https\:\/\//) # works both live & stubbed
|
514
555
|
end
|
515
556
|
|
516
557
|
it "handles requests for two different tokens" do
|
517
|
-
me,
|
558
|
+
me, app_event_types = @api.batch do |batch_api|
|
518
559
|
batch_api.get_object('me')
|
519
|
-
batch_api.get_connections(@app_id, '
|
560
|
+
batch_api.get_connections(@app_id, 'app_event_types', {}, {"access_token" => @app_api.access_token})
|
520
561
|
end
|
521
562
|
expect(me['id']).not_to be_nil
|
522
|
-
expect(
|
563
|
+
expect(app_event_types).to be_an(Koala::Facebook::API::GraphCollection)
|
523
564
|
end
|
524
565
|
|
525
566
|
it "handles requests passing the access token option as a symbol instead of a string" do
|
526
|
-
me,
|
567
|
+
me, app_event_types = @api.batch do |batch_api|
|
527
568
|
batch_api.get_object('me')
|
528
|
-
batch_api.get_connections(@app_id, '
|
569
|
+
batch_api.get_connections(@app_id, 'app_event_types', {}, {:access_token => @app_api.access_token})
|
529
570
|
end
|
530
571
|
expect(me['id']).not_to be_nil
|
531
|
-
expect(
|
572
|
+
expect(app_event_types).to be_an(Koala::Facebook::API::GraphCollection)
|
532
573
|
end
|
533
574
|
|
534
575
|
it "preserves batch-op specific access tokens in GraphCollection returned from batch" do
|
535
576
|
# Provide an alternate token for a batch operation
|
536
577
|
@other_access_token_args = { 'access_token' => @app_api.access_token }
|
537
578
|
|
538
|
-
# make a batch call for
|
539
|
-
me,
|
579
|
+
# make a batch call for app_event_types using another token
|
580
|
+
me, app_event_types = @api.batch do |batch_api|
|
540
581
|
batch_api.get_object('me')
|
541
|
-
batch_api.get_connections(@app_id, '
|
582
|
+
batch_api.get_connections(@app_id, 'app_event_types', {}, @other_access_token_args)
|
542
583
|
end
|
543
584
|
|
544
585
|
# The alternate token is returned with the next page parameters
|
545
586
|
# The GraphCollection should receive a request for the next_page_params during paging
|
546
|
-
expect(
|
587
|
+
expect(app_event_types).to receive(:next_page_params).and_return([double("base"), @other_access_token_args.dup])
|
547
588
|
|
548
589
|
# The alternate access token should pass through to making the request
|
549
590
|
# Koala should receive a request during paging using the alternate token
|
@@ -552,41 +593,31 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
552
593
|
hash_including(@other_access_token_args.dup),
|
553
594
|
anything,
|
554
595
|
anything
|
555
|
-
).and_return(Koala::HTTPService::Response.new(200, "",
|
596
|
+
).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
556
597
|
|
557
598
|
# Page the collection
|
558
|
-
|
599
|
+
app_event_types.next_page
|
559
600
|
end
|
560
601
|
|
561
602
|
it "inserts errors in the appropriate place, without breaking other results" do
|
562
|
-
failed_call,
|
603
|
+
failed_call, barackobama = @api.batch do |batch_api|
|
563
604
|
batch_api.get_connection("2", "invalidconnection")
|
564
605
|
batch_api.get_object(KoalaTest.user1, {}, {"access_token" => @app_api.access_token})
|
565
606
|
end
|
566
607
|
expect(failed_call).to be_a(Koala::Facebook::ClientError)
|
567
|
-
expect(
|
608
|
+
expect(barackobama["id"]).not_to be_nil
|
568
609
|
end
|
569
610
|
|
570
611
|
it "handles different request methods" do
|
571
612
|
result = @api.put_wall_post("Hello, world, from the test suite batch API!")
|
572
613
|
wall_post = result["id"]
|
573
614
|
|
574
|
-
wall_post,
|
615
|
+
wall_post, barackobama = @api.batch do |batch_api|
|
575
616
|
batch_api.put_like(wall_post)
|
576
617
|
batch_api.delete_object(wall_post)
|
577
618
|
end
|
578
619
|
end
|
579
620
|
|
580
|
-
it "allows FQL" do
|
581
|
-
result = @api.batch do |batch_api|
|
582
|
-
batch_api.graph_call("method/fql.query", {:query=>"select first_name from user where uid=#{KoalaTest.user1_id}"}, "post")
|
583
|
-
end
|
584
|
-
|
585
|
-
fql_result = result[0]
|
586
|
-
expect(fql_result[0]).to be_a(Hash)
|
587
|
-
expect(fql_result[0]["first_name"]).to eq("Alex")
|
588
|
-
end
|
589
|
-
|
590
621
|
describe 'with post-processing callback' do
|
591
622
|
let(:me_result) { double("me result") }
|
592
623
|
let(:friends_result) { [double("friends result")] }
|
@@ -668,23 +699,23 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
668
699
|
end
|
669
700
|
|
670
701
|
it "allows you to create dependencies" do
|
671
|
-
me,
|
702
|
+
me, barackobama = @api.batch do |batch_api|
|
672
703
|
batch_api.get_object("me", {}, :batch_args => {:name => "getme"})
|
673
704
|
batch_api.get_object(KoalaTest.user1, {}, :batch_args => {:depends_on => "getme"})
|
674
705
|
end
|
675
706
|
|
676
707
|
expect(me).to be_nil # gotcha! it's omitted because it's a successfully-executed dependency
|
677
|
-
expect(
|
708
|
+
expect(barackobama["id"]).not_to be_nil
|
678
709
|
end
|
679
710
|
|
680
711
|
it "properly handles dependencies that fail" do
|
681
|
-
failed_call,
|
712
|
+
failed_call, barackobama = @api.batch do |batch_api|
|
682
713
|
batch_api.get_connections("2", "invalidconnection", {}, :batch_args => {:name => "getdata"})
|
683
714
|
batch_api.get_object(KoalaTest.user1, {}, :batch_args => {:depends_on => "getdata"})
|
684
715
|
end
|
685
716
|
|
686
717
|
expect(failed_call).to be_a(Koala::Facebook::ClientError)
|
687
|
-
expect(
|
718
|
+
expect(barackobama).to be_nil
|
688
719
|
end
|
689
720
|
|
690
721
|
it "throws an error for badly-constructed request relationships" do
|
@@ -9,6 +9,8 @@ describe 'Koala::Facebook::GraphAPIMethods' do
|
|
9
9
|
@app_api = Koala::Facebook::API.new(@app_access_token)
|
10
10
|
end
|
11
11
|
|
12
|
+
let(:dummy_response) { double("fake response", data: {}, status: 200, body: "", headers: {}) }
|
13
|
+
|
12
14
|
describe 'post-processing for' do
|
13
15
|
let(:result) { double("result") }
|
14
16
|
let(:post_processing) { lambda {|arg| {"result" => result, "args" => arg} } }
|
@@ -17,47 +19,31 @@ describe 'Koala::Facebook::GraphAPIMethods' do
|
|
17
19
|
# and the other methods which do some post-processing locally
|
18
20
|
context '#get_object' do
|
19
21
|
it 'returns result of block' do
|
20
|
-
allow(@api).to receive(:api).and_return(
|
21
|
-
expect(@api.get_object('
|
22
|
+
allow(@api).to receive(:api).and_return(dummy_response)
|
23
|
+
expect(@api.get_object('barackobama', &post_processing)["result"]).to eq(result)
|
22
24
|
end
|
23
25
|
|
24
26
|
it "doesn't add token to received arguments" do
|
25
27
|
args = {}.freeze
|
26
|
-
expect(Koala).to receive(:make_request).and_return(
|
27
|
-
expect(@api.get_object('
|
28
|
+
expect(Koala).to receive(:make_request).and_return(dummy_response)
|
29
|
+
expect(@api.get_object('barackobama', args, &post_processing)["result"]).to eq(result)
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
31
33
|
context '#get_picture' do
|
32
34
|
it 'returns result of block' do
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
context '#fql_multiquery' do
|
39
|
-
before do
|
40
|
-
expect(@api).to receive(:get_object).and_return([
|
41
|
-
{"name" => "query1", "fql_result_set" => [{"id" => 123}]},
|
42
|
-
{"name" => "query2", "fql_result_set" => ["id" => 456]}
|
43
|
-
])
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'is called with resolved response' do
|
47
|
-
resolved_result = {
|
48
|
-
'query1' => [{'id' => 123}],
|
49
|
-
'query2' => [{'id' => 456}]
|
50
|
-
}
|
51
|
-
response = @api.fql_multiquery({}, &post_processing)
|
52
|
-
expect(response["args"]).to eq(resolved_result)
|
53
|
-
expect(response["result"]).to eq(result)
|
35
|
+
result_url = "a url"
|
36
|
+
allow(@api).to receive(:api).and_return(Koala::HTTPService::Response.new(200, {"data" => {"is_silhouette" => false, "url" => result_url}}.to_json, {}))
|
37
|
+
expect(@api.get_picture('koppel', &post_processing)["result"]).to eq(result)
|
54
38
|
end
|
55
39
|
end
|
56
40
|
|
57
41
|
context '#get_page_access_token' do
|
58
42
|
it 'returns result of block' do
|
59
43
|
token = Koala::MockHTTPService::APP_ACCESS_TOKEN
|
60
|
-
allow(@api).to receive(:api).and_return(
|
44
|
+
allow(@api).to receive(:api).and_return(
|
45
|
+
Koala::HTTPService::Response.new(200, {"access_token" => token}.to_json, {})
|
46
|
+
)
|
61
47
|
response = @api.get_page_access_token('facebook', &post_processing)
|
62
48
|
expect(response["args"]).to eq(token)
|
63
49
|
expect(response["result"]).to eq(result)
|
@@ -71,18 +57,18 @@ describe 'Koala::Facebook::GraphAPIMethods' do
|
|
71
57
|
|
72
58
|
it "is enabled by default if an app secret is present" do
|
73
59
|
api = Koala::Facebook::API.new(@token, "mysecret")
|
74
|
-
expect(api).to receive(:api).with(path, {}, 'get', :appsecret_proof => true)
|
60
|
+
expect(api).to receive(:api).with(path, {}, 'get', :appsecret_proof => true).and_return(dummy_response)
|
75
61
|
api.graph_call(path)
|
76
62
|
end
|
77
63
|
|
78
64
|
it "can be disabled manually" do
|
79
65
|
api = Koala::Facebook::API.new(@token, "mysecret")
|
80
|
-
expect(api).to receive(:api).with(path, {}, 'get', hash_not_including(appsecret_proof: true))
|
66
|
+
expect(api).to receive(:api).with(path, {}, 'get', hash_not_including(appsecret_proof: true)).and_return(dummy_response)
|
81
67
|
api.graph_call(path, {}, "get", appsecret_proof: false)
|
82
68
|
end
|
83
69
|
|
84
70
|
it "isn't included if no app secret is present" do
|
85
|
-
expect(@api).to receive(:api).with(path, {}, 'get', {})
|
71
|
+
expect(@api).to receive(:api).with(path, {}, 'get', {}).and_return(dummy_response)
|
86
72
|
@api.graph_call(path)
|
87
73
|
end
|
88
74
|
end
|
@@ -1,28 +1,30 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Koala::Facebook::GraphCollection do
|
4
|
-
let(:paging){ {
|
3
|
+
describe Koala::Facebook::API::GraphCollection do
|
4
|
+
let(:paging){ {"paging" => true} }
|
5
5
|
|
6
6
|
before(:each) do
|
7
|
-
@
|
8
|
-
|
7
|
+
@headers = {'Content-Type' => 'application/json'}
|
8
|
+
@data = {
|
9
|
+
"data" => [1, 2, 'three'],
|
9
10
|
"paging" => paging,
|
10
11
|
"summary" => [3]
|
11
12
|
}
|
13
|
+
@result = Koala::HTTPService::Response.new(200, @data.to_json, @headers)
|
12
14
|
@api = Koala::Facebook::API.new("123")
|
13
|
-
@collection = Koala::Facebook::GraphCollection.new(@result, @api)
|
15
|
+
@collection = Koala::Facebook::API::GraphCollection.new(@result, @api)
|
14
16
|
end
|
15
17
|
|
16
18
|
it "subclasses Array" do
|
17
|
-
expect(Koala::Facebook::GraphCollection.ancestors).to include(Array)
|
19
|
+
expect(Koala::Facebook::API::GraphCollection.ancestors).to include(Array)
|
18
20
|
end
|
19
21
|
|
20
22
|
it "creates an array-like object" do
|
21
|
-
expect(Koala::Facebook::GraphCollection.new(@result, @api)).to be_an(Array)
|
23
|
+
expect(Koala::Facebook::API::GraphCollection.new(@result, @api)).to be_an(Array)
|
22
24
|
end
|
23
25
|
|
24
26
|
it "contains the result data" do
|
25
|
-
@
|
27
|
+
@data["data"].each_with_index {|r, i| expect(@collection[i]).to eq(r)}
|
26
28
|
end
|
27
29
|
|
28
30
|
it "has a read-only paging attribute" do
|
@@ -31,43 +33,49 @@ describe Koala::Facebook::GraphCollection do
|
|
31
33
|
end
|
32
34
|
|
33
35
|
it "sets paging to results['paging']" do
|
34
|
-
expect(@collection.paging).to eq(@
|
36
|
+
expect(@collection.paging).to eq(@data["paging"])
|
35
37
|
end
|
36
38
|
|
37
39
|
it "sets summary to results['summary']" do
|
38
|
-
expect(@collection.summary).to eq(@
|
40
|
+
expect(@collection.summary).to eq(@data["summary"])
|
39
41
|
end
|
40
42
|
|
41
43
|
it "sets raw_response to the original results" do
|
42
|
-
expect(@collection.raw_response).to eq(@result)
|
44
|
+
expect(@collection.raw_response).to eq(@result.data)
|
43
45
|
end
|
44
46
|
|
45
47
|
it "sets the API to the provided API" do
|
46
48
|
expect(@collection.api).to eq(@api)
|
47
49
|
end
|
48
50
|
|
51
|
+
it "sets the headers correctly" do
|
52
|
+
expect(@collection.headers).to eq(@headers)
|
53
|
+
end
|
54
|
+
|
49
55
|
describe "when getting a whole page" do
|
50
56
|
before(:each) do
|
51
57
|
@second_page = {
|
52
|
-
"data" => [
|
58
|
+
"data" => ["second", "page", "data"],
|
53
59
|
"paging" => {}
|
54
60
|
}
|
55
61
|
@base = double("base")
|
56
62
|
@args = {"a" => 1}
|
57
63
|
@page_of_results = double("page of results")
|
64
|
+
@result = Koala::HTTPService::Response.new(200, @second_page.to_json, {})
|
65
|
+
@result.data
|
58
66
|
end
|
59
67
|
|
60
68
|
it "should return the previous page of results" do
|
61
69
|
expect(@collection).to receive(:previous_page_params).and_return([@base, @args])
|
62
|
-
expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(@
|
63
|
-
expect(Koala::Facebook::GraphCollection).to receive(:new).with(@
|
70
|
+
expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(@result)
|
71
|
+
expect(Koala::Facebook::API::GraphCollection).to receive(:new).with(@result, @api).and_return(@page_of_results)
|
64
72
|
expect(@collection.previous_page).to eq(@page_of_results)
|
65
73
|
end
|
66
74
|
|
67
75
|
it "should return the next page of results" do
|
68
76
|
expect(@collection).to receive(:next_page_params).and_return([@base, @args])
|
69
|
-
expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(@
|
70
|
-
expect(Koala::Facebook::GraphCollection).to receive(:new).with(@
|
77
|
+
expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(@result)
|
78
|
+
expect(Koala::Facebook::API::GraphCollection).to receive(:new).with(@result, @api).and_return(@page_of_results)
|
71
79
|
|
72
80
|
expect(@collection.next_page).to eq(@page_of_results)
|
73
81
|
end
|
@@ -84,13 +92,13 @@ describe Koala::Facebook::GraphCollection do
|
|
84
92
|
describe "#parse_page_url" do
|
85
93
|
it "should pass the url to the class method" do
|
86
94
|
url = double("url")
|
87
|
-
expect(Koala::Facebook::GraphCollection).to receive(:parse_page_url).with(url)
|
95
|
+
expect(Koala::Facebook::API::GraphCollection).to receive(:parse_page_url).with(url)
|
88
96
|
@collection.parse_page_url(url)
|
89
97
|
end
|
90
98
|
|
91
99
|
it "should return the result of the class method" do
|
92
100
|
parsed_content = double("parsed_content")
|
93
|
-
allow(Koala::Facebook::GraphCollection).to receive(:parse_page_url).and_return(parsed_content)
|
101
|
+
allow(Koala::Facebook::API::GraphCollection).to receive(:parse_page_url).and_return(parsed_content)
|
94
102
|
expect(@collection.parse_page_url(double("url"))).to eq(parsed_content)
|
95
103
|
end
|
96
104
|
end
|
@@ -98,54 +106,59 @@ describe Koala::Facebook::GraphCollection do
|
|
98
106
|
describe ".parse_page_url" do
|
99
107
|
it "should return the base as the first array entry" do
|
100
108
|
base = "url_path"
|
101
|
-
expect(Koala::Facebook::GraphCollection.parse_page_url("http://facebook.com/#{base}?anything").first).to eq(base)
|
109
|
+
expect(Koala::Facebook::API::GraphCollection.parse_page_url("http://facebook.com/#{base}?anything").first).to eq(base)
|
102
110
|
end
|
103
111
|
|
104
112
|
it "should return the arguments as a hash as the last array entry" do
|
105
113
|
args_hash = {"one" => "val_one", "two" => "val_two"}
|
106
|
-
expect(Koala::Facebook::GraphCollection.parse_page_url("http://facebook.com/anything?#{args_hash.map {|k,v| "#{k}=#{v}" }.join("&")}").last).to eq(args_hash)
|
114
|
+
expect(Koala::Facebook::API::GraphCollection.parse_page_url("http://facebook.com/anything?#{args_hash.map {|k,v| "#{k}=#{v}" }.join("&")}").last).to eq(args_hash)
|
107
115
|
end
|
108
116
|
|
109
117
|
it "works with non-.com addresses" do
|
110
118
|
base = "url_path"
|
111
119
|
args_hash = {"one" => "val_one", "two" => "val_two"}
|
112
|
-
expect(Koala::Facebook::GraphCollection.parse_page_url("http://facebook.com/#{base}?#{args_hash.map {|k,v| "#{k}=#{v}" }.join("&")}")).to eq([base, args_hash])
|
120
|
+
expect(Koala::Facebook::API::GraphCollection.parse_page_url("http://facebook.com/#{base}?#{args_hash.map {|k,v| "#{k}=#{v}" }.join("&")}")).to eq([base, args_hash])
|
113
121
|
end
|
114
122
|
|
115
123
|
it "works with addresses with irregular characters" do
|
116
124
|
access_token = "appid123a|fdcba"
|
117
|
-
base, args_hash = Koala::Facebook::GraphCollection.parse_page_url("http://facebook.com/foo?token=#{access_token}")
|
125
|
+
base, args_hash = Koala::Facebook::API::GraphCollection.parse_page_url("http://facebook.com/foo?token=#{access_token}")
|
118
126
|
expect(args_hash["token"]).to eq(access_token)
|
119
127
|
end
|
120
128
|
end
|
121
129
|
end
|
122
130
|
|
123
131
|
describe ".evaluate" do
|
124
|
-
it "returns the original
|
125
|
-
result =
|
126
|
-
|
132
|
+
it "returns the body of the original response if it's provided a Response with a non-hash data key" do
|
133
|
+
result = double('fake response')
|
134
|
+
allow(result).to receive(:is_a?).with(Hash).and_return(false)
|
135
|
+
allow(result).to receive(:data).and_return([])
|
136
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq([])
|
127
137
|
end
|
128
138
|
|
129
139
|
it "returns the original result if it's provided a nil result" do
|
130
140
|
result = nil
|
131
|
-
expect(Koala::Facebook::GraphCollection.evaluate(result, @api)).to eq(result)
|
141
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq(result)
|
132
142
|
end
|
133
143
|
|
134
|
-
it "returns the original result if the result doesn't have a data key" do
|
135
|
-
|
136
|
-
|
144
|
+
it "returns the original result body if the result doesn't have a data key" do
|
145
|
+
paging = {"paging" => {}}
|
146
|
+
result = Koala::HTTPService::Response.new(200, paging.to_json, {})
|
147
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq(paging)
|
137
148
|
end
|
138
149
|
|
139
150
|
it "returns the original result if the result's data key isn't an array" do
|
140
|
-
|
141
|
-
|
151
|
+
body = {"data" => {}, "paging" => {}}
|
152
|
+
result = Koala::HTTPService::Response.new(200, body.to_json, {})
|
153
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq(body)
|
142
154
|
end
|
143
155
|
|
144
156
|
it "returns a new GraphCollection of the result if it has an array data key and a paging key" do
|
145
|
-
|
157
|
+
body = {"data" => [], "paging" => {}}
|
158
|
+
result = Koala::HTTPService::Response.new(200, body.to_json, {})
|
146
159
|
expected = :foo
|
147
|
-
expect(Koala::Facebook::GraphCollection).to receive(:new).with(result, @api).and_return(expected)
|
148
|
-
expect(Koala::Facebook::GraphCollection.evaluate(result, @api)).to eq(expected)
|
160
|
+
expect(Koala::Facebook::API::GraphCollection).to receive(:new).with(result, @api).and_return(expected)
|
161
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq(expected)
|
149
162
|
end
|
150
163
|
end
|
151
164
|
|
@@ -11,7 +11,10 @@ module Koala
|
|
11
11
|
expect(GraphErrorChecker::DEBUG_HEADERS).to match_array([
|
12
12
|
"x-fb-rev",
|
13
13
|
"x-fb-debug",
|
14
|
-
"x-fb-trace-id"
|
14
|
+
"x-fb-trace-id",
|
15
|
+
"x-business-use-case-usage",
|
16
|
+
"x-ad-account-usage",
|
17
|
+
"x-app-usage"
|
15
18
|
])
|
16
19
|
end
|
17
20
|
|
@@ -54,6 +57,18 @@ module Koala
|
|
54
57
|
expect(error.response_body).to eq(body)
|
55
58
|
end
|
56
59
|
|
60
|
+
it "returns a ClientError if the body is empty" do
|
61
|
+
body.replace("")
|
62
|
+
expect(error).to be_a(ClientError)
|
63
|
+
expect(error.response_body).to eq(body)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns a ClientError if the body is null" do
|
67
|
+
body.replace("null")
|
68
|
+
expect(error).to be_a(ClientError)
|
69
|
+
expect(error.response_body).to eq(body)
|
70
|
+
end
|
71
|
+
|
57
72
|
it "adds error data from the body" do
|
58
73
|
error_data = {
|
59
74
|
"type" => "FB error type",
|
@@ -78,10 +93,25 @@ module Koala
|
|
78
93
|
"x-fb-debug" => double("fb debug"),
|
79
94
|
"x-fb-rev" => double("fb rev"),
|
80
95
|
"x-fb-trace-id" => double("fb trace id"),
|
96
|
+
"x-business-use-case-usage" => { 'a' => 1, 'b' => 2 }.to_json,
|
97
|
+
"x-ad-account-usage" => { 'c' => 3, 'd' => 4 }.to_json,
|
98
|
+
"x-app-usage" => { 'e' => 5, 'f' => 6 }.to_json
|
81
99
|
)
|
82
100
|
expect(error.fb_error_trace_id).to eq(headers["x-fb-trace-id"])
|
83
101
|
expect(error.fb_error_debug).to eq(headers["x-fb-debug"])
|
84
102
|
expect(error.fb_error_rev).to eq(headers["x-fb-rev"])
|
103
|
+
expect(error.fb_buc_usage).to eq({ 'a' => 1, 'b' => 2 })
|
104
|
+
expect(error.fb_ada_usage).to eq({ 'c' => 3, 'd' => 4 })
|
105
|
+
expect(error.fb_app_usage).to eq({ 'e' => 5, 'f' => 6 })
|
106
|
+
end
|
107
|
+
|
108
|
+
it "logs if one of the FB debug headers can't be parsed" do
|
109
|
+
headers.merge!(
|
110
|
+
"x-app-usage" => '{invalid:json}'
|
111
|
+
)
|
112
|
+
|
113
|
+
expect(Koala::Utils.logger).to receive(:error).with(/JSON::ParserError:.*unexpected token at '{invalid:json}' while parsing x-app-usage = {invalid:json}/)
|
114
|
+
expect(error.fb_app_usage).to eq(nil)
|
85
115
|
end
|
86
116
|
|
87
117
|
context "it returns an AuthenticationError" do
|
@@ -113,4 +143,3 @@ module Koala
|
|
113
143
|
end
|
114
144
|
end
|
115
145
|
end
|
116
|
-
|