koala 3.0.0.beta1 → 3.0.0.beta2

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.
@@ -14,11 +14,7 @@ module Koala
14
14
  # @option options :beta use the beta tier
15
15
  # @option options :use_ssl force https, even if not needed
16
16
  # @option options :json whether or not to send JSON to Facebook
17
- def initialize(path: nil, args: {}, verb: nil, options: {})
18
- # we still support Ruby 2.0 so we can't use required keyword arguments
19
- raise ArgumentError, "Missing required argument verb" unless verb
20
- raise ArgumentError, "Missing required argument path" unless path
21
-
17
+ def initialize(path:, verb:, args: {}, options: {})
22
18
  @raw_path = path
23
19
  @raw_args = args
24
20
  @raw_verb = verb
@@ -9,6 +9,12 @@ module Koala
9
9
  @body = body
10
10
  @headers = headers
11
11
  end
12
+
13
+ def data
14
+ # quirks_mode is needed because Facebook sometimes returns a raw true or false value --
15
+ # in Ruby 2.4 we can drop that.
16
+ @data ||= JSON.parse(body, quirks_mode: true) unless body.empty?
17
+ end
12
18
  end
13
19
  end
14
20
  end
@@ -146,11 +146,12 @@ module Koala
146
146
  raise ArgumentError, "TestUsers#befriend requires hash arguments for both users with id and access_token"
147
147
  end
148
148
 
149
- u1_graph_api = API.new(user1_token)
150
- u2_graph_api = API.new(user2_token)
149
+ u1_graph_api = API.new(user1_token, secret)
150
+ u2_graph_api = API.new(user2_token, secret)
151
151
 
152
- u1_graph_api.graph_call("#{user1_id}/friends/#{user2_id}", {}, "post", options) &&
153
- u2_graph_api.graph_call("#{user2_id}/friends/#{user1_id}", {}, "post", options)
152
+ # if we have a secret token, flag that we want the appsecret_proof to be generated
153
+ u1_graph_api.graph_call("#{user1_id}/friends/#{user2_id}", {}, "post", options.merge(appsecret_proof: !!secret)) &&
154
+ u2_graph_api.graph_call("#{user2_id}/friends/#{user1_id}", {}, "post", options.merge(appsecret_proof: !!secret))
154
155
  end
155
156
 
156
157
  # Create a network of test users, all of whom are friends and have the same permissions.
@@ -1,3 +1,3 @@
1
1
  module Koala
2
- VERSION = "3.0.0.beta1"
2
+ VERSION = "3.0.0.beta2"
3
3
  end
@@ -1,9 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Koala::Facebook::API" do
4
- before(:each) do
4
+ before :each do
5
5
  @service = Koala::Facebook::API.new
6
6
  end
7
+ let(:dummy_response) { double("fake response", data: {}, status: 200, body: "", headers: {}) }
7
8
 
8
9
  it "doesn't include an access token if none was given" do
9
10
  expect(Koala).to receive(:make_request).with(
@@ -57,24 +58,6 @@ describe "Koala::Facebook::API" do
57
58
  expect(service.app_secret).to eq(secret)
58
59
  end
59
60
 
60
- it "gets the attribute of a Koala::HTTPService::Response given by the http_component parameter" do
61
- http_component = :method_name
62
-
63
- response = double('Mock KoalaResponse', :body => '', :status => 200)
64
- result = double("result")
65
- allow(response).to receive(http_component).and_return(result)
66
- allow(Koala).to receive(:make_request).and_return(response)
67
-
68
- expect(@service.api('anything', {}, 'get', :http_component => http_component)).to eq(result)
69
- end
70
-
71
- it "returns the entire response if http_component => :response" do
72
- http_component = :response
73
- response = double('Mock KoalaResponse', :body => '', :status => 200)
74
- allow(Koala).to receive(:make_request).and_return(response)
75
- expect(@service.api('anything', {}, 'get', :http_component => http_component)).to eq(response)
76
- end
77
-
78
61
  it "turns arrays of non-enumerables into comma-separated arguments by default" do
79
62
  args = [12345, {:foo => [1, 2, "3", :four]}]
80
63
  expected = ["/12345", {:foo => "1,2,3,four"}, "get", {}]
@@ -123,43 +106,12 @@ describe "Koala::Facebook::API" do
123
106
  @service.api(*args)
124
107
  end
125
108
 
126
- it "returns the body of the request as JSON if no http_component is given" do
127
- response = double('response', :body => 'body', :status => 200)
128
- allow(Koala).to receive(:make_request).and_return(response)
129
-
130
- json_body = double('JSON body')
131
- allow(JSON).to receive(:parse).and_return([json_body])
132
-
133
- expect(@service.api('anything')).to eq(json_body)
134
- end
135
-
136
- it "executes an error checking block if provided" do
137
- response = Koala::HTTPService::Response.new(200, '{}', {})
138
- allow(Koala).to receive(:make_request).and_return(response)
139
-
140
- yield_test = double('Yield Tester')
141
- expect(yield_test).to receive(:pass)
142
-
143
- @service.api('anything', {}, "get") do |arg|
144
- yield_test.pass
145
- expect(arg).to eq(response)
146
- end
147
- end
148
-
149
109
  it "raises an API error if the HTTP response code is greater than or equal to 500" do
150
110
  allow(Koala).to receive(:make_request).and_return(Koala::HTTPService::Response.new(500, 'response body', {}))
151
111
 
152
112
  expect { @service.api('anything') }.to raise_exception(Koala::Facebook::APIError)
153
113
  end
154
114
 
155
- it "handles rogue true/false as responses" do
156
- expect(Koala).to receive(:make_request).and_return(Koala::HTTPService::Response.new(200, 'true', {}))
157
- expect(@service.api('anything')).to be_truthy
158
-
159
- expect(Koala).to receive(:make_request).and_return(Koala::HTTPService::Response.new(200, 'false', {}))
160
- expect(@service.api('anything')).to be_falsey
161
- end
162
-
163
115
  describe "path manipulation" do
164
116
  context "leading /" do
165
117
  it "adds a leading / to the path if not present" do
@@ -179,6 +131,7 @@ describe "Koala::Facebook::API" do
179
131
  describe "with an access token" do
180
132
  before(:each) do
181
133
  @api = Koala::Facebook::API.new(@token)
134
+ @app_access_token = KoalaTest.app_access_token
182
135
  end
183
136
 
184
137
  it_should_behave_like "Koala GraphAPI"
@@ -191,9 +144,10 @@ describe "Koala::Facebook::API" do
191
144
  @api = Koala::Facebook::API.new
192
145
  end
193
146
 
147
+ # In theory this should behave the same with a GraphCollection, but those tests currently hit
148
+ # an endpoint that now requires a token.
194
149
  it_should_behave_like "Koala GraphAPI"
195
150
  it_should_behave_like "Koala GraphAPI without an access token"
196
- it_should_behave_like "Koala GraphAPI with GraphCollection"
197
151
  end
198
152
 
199
153
  context '#api' do
@@ -246,4 +200,78 @@ describe "Koala::Facebook::API" do
246
200
  end
247
201
  end
248
202
  end
203
+
204
+ describe "#graph_call" do
205
+ it "passes all arguments to the api method" do
206
+ user = KoalaTest.user1
207
+ args = {}
208
+ verb = 'get'
209
+ opts = {:a => :b}
210
+ expect(@service).to receive(:api).with(user, args, verb, opts).and_return(dummy_response)
211
+ @service.graph_call(user, args, verb, opts)
212
+ end
213
+
214
+ it "throws an APIError if the result hash has an error key" do
215
+ allow(Koala).to receive(:make_request).and_return(Koala::HTTPService::Response.new(500, '{"error": "An error occurred!"}', {}))
216
+ expect { @service.graph_call(KoalaTest.user1, {}) }.to raise_exception(Koala::Facebook::APIError)
217
+ end
218
+
219
+ it "passes the results through GraphCollection.evaluate" do
220
+ allow(@service).to receive(:api).and_return(dummy_response)
221
+ expect(Koala::Facebook::API::GraphCollection).to receive(:evaluate).with(dummy_response.data, @service)
222
+ @service.graph_call("/me")
223
+ end
224
+
225
+ it "returns the results of GraphCollection.evaluate" do
226
+ expected = {}
227
+ allow(@service).to receive(:api).and_return(dummy_response)
228
+ expect(Koala::Facebook::API::GraphCollection).to receive(:evaluate).and_return(expected)
229
+ expect(@service.graph_call("/me")).to eq(expected)
230
+ end
231
+
232
+ it "returns the post_processing block's results if one is supplied" do
233
+ other_result = [:a, 2, :three]
234
+ block = Proc.new {|r| other_result}
235
+ allow(@service).to receive(:api).and_return(dummy_response)
236
+ expect(@service.graph_call("/me", {}, "get", {}, &block)).to eq(other_result)
237
+ end
238
+
239
+ it "gets the status of a Koala::HTTPService::Response if requested" do
240
+ response = Koala::HTTPService::Response.new(200, '', {})
241
+ allow(Koala).to receive(:make_request).and_return(response)
242
+
243
+ expect(@service.graph_call('anything', {}, 'get', http_component: :status)).to eq(200)
244
+ end
245
+
246
+ it "gets the headers of a Koala::HTTPService::Response if requested" do
247
+ headers = {"a" => 2}
248
+ response = Koala::HTTPService::Response.new(200, '', headers)
249
+ allow(Koala).to receive(:make_request).and_return(response)
250
+
251
+ expect(@service.graph_call('anything', {}, 'get', :http_component => :headers)).to eq(headers)
252
+ end
253
+
254
+ it "returns the entire response if http_component => :response" do
255
+ http_component = :response
256
+ response = Koala::HTTPService::Response.new(200, '', {})
257
+ allow(Koala).to receive(:make_request).and_return(response)
258
+ expect(@service.graph_call('anything', {}, 'get', :http_component => http_component)).to eq(response)
259
+ end
260
+
261
+ it "returns the body of the request as JSON if no http_component is given" do
262
+ result = {"a" => 2}
263
+ response = Koala::HTTPService::Response.new(200, result.to_json, {})
264
+ allow(Koala).to receive(:make_request).and_return(response)
265
+
266
+ expect(@service.graph_call('anything')).to eq(result)
267
+ end
268
+
269
+ it "handles rogue true/false as responses" do
270
+ expect(Koala).to receive(:make_request).and_return(Koala::HTTPService::Response.new(200, 'true', {}))
271
+ expect(@service.graph_call('anything')).to be_truthy
272
+
273
+ expect(Koala).to receive(:make_request).and_return(Koala::HTTPService::Response.new(200, 'false', {}))
274
+ expect(@service.graph_call('anything')).to be_falsey
275
+ end
276
+ end
249
277
  end
@@ -473,12 +473,12 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
473
473
 
474
474
  describe "usage tests" do
475
475
  it "gets two results at once" do
476
- me, koppel = @api.batch do |batch_api|
476
+ me, barackobama = @api.batch do |batch_api|
477
477
  batch_api.get_object('me')
478
478
  batch_api.get_object(KoalaTest.user1)
479
479
  end
480
480
  expect(me['id']).not_to be_nil
481
- expect(koppel['id']).not_to be_nil
481
+ expect(barackobama['id']).not_to be_nil
482
482
  end
483
483
 
484
484
  it 'makes mixed calls inside of a batch' do
@@ -502,7 +502,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
502
502
  pictures = @api.batch do |batch_api|
503
503
  batch_api.get_picture('me')
504
504
  end
505
- expect(pictures.first).to match(/http\:\/\//) # works both live & stubbed
505
+ expect(pictures.first).to match(/https\:\/\//) # works both live & stubbed
506
506
  end
507
507
 
508
508
  it 'takes an after processing block for a get_picture call inside of a batch' do
@@ -510,40 +510,40 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
510
510
  @api.batch do |batch_api|
511
511
  batch_api.get_picture('me') { |pic| picture = pic }
512
512
  end
513
- expect(picture).to match(/http\:\/\//) # works both live & stubbed
513
+ expect(picture).to match(/https\:\/\//) # works both live & stubbed
514
514
  end
515
515
 
516
516
  it "handles requests for two different tokens" do
517
- me, insights = @api.batch do |batch_api|
517
+ me, app_event_types = @api.batch do |batch_api|
518
518
  batch_api.get_object('me')
519
- batch_api.get_connections(@app_id, 'insights', {}, {"access_token" => @app_api.access_token})
519
+ batch_api.get_connections(@app_id, 'app_event_types', {}, {"access_token" => @app_api.access_token})
520
520
  end
521
521
  expect(me['id']).not_to be_nil
522
- expect(insights).to be_an(Koala::Facebook::API::GraphCollection)
522
+ expect(app_event_types).to be_an(Koala::Facebook::API::GraphCollection)
523
523
  end
524
524
 
525
525
  it "handles requests passing the access token option as a symbol instead of a string" do
526
- me, insights = @api.batch do |batch_api|
526
+ me, app_event_types = @api.batch do |batch_api|
527
527
  batch_api.get_object('me')
528
- batch_api.get_connections(@app_id, 'insights', {}, {:access_token => @app_api.access_token})
528
+ batch_api.get_connections(@app_id, 'app_event_types', {}, {:access_token => @app_api.access_token})
529
529
  end
530
530
  expect(me['id']).not_to be_nil
531
- expect(insights).to be_an(Koala::Facebook::API::GraphCollection)
531
+ expect(app_event_types).to be_an(Koala::Facebook::API::GraphCollection)
532
532
  end
533
533
 
534
534
  it "preserves batch-op specific access tokens in GraphCollection returned from batch" do
535
535
  # Provide an alternate token for a batch operation
536
536
  @other_access_token_args = { 'access_token' => @app_api.access_token }
537
537
 
538
- # make a batch call for insights using another token
539
- me, insights = @api.batch do |batch_api|
538
+ # make a batch call for app_event_types using another token
539
+ me, app_event_types = @api.batch do |batch_api|
540
540
  batch_api.get_object('me')
541
- batch_api.get_connections(@app_id, 'insights', {}, @other_access_token_args)
541
+ batch_api.get_connections(@app_id, 'app_event_types', {}, @other_access_token_args)
542
542
  end
543
543
 
544
544
  # The alternate token is returned with the next page parameters
545
545
  # The GraphCollection should receive a request for the next_page_params during paging
546
- expect(insights).to receive(:next_page_params).and_return([double("base"), @other_access_token_args.dup])
546
+ expect(app_event_types).to receive(:next_page_params).and_return([double("base"), @other_access_token_args.dup])
547
547
 
548
548
  # The alternate access token should pass through to making the request
549
549
  # Koala should receive a request during paging using the alternate token
@@ -555,23 +555,23 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
555
555
  ).and_return(Koala::HTTPService::Response.new(200, "", ""))
556
556
 
557
557
  # Page the collection
558
- insights.next_page
558
+ app_event_types.next_page
559
559
  end
560
560
 
561
561
  it "inserts errors in the appropriate place, without breaking other results" do
562
- failed_call, koppel = @api.batch do |batch_api|
562
+ failed_call, barackobama = @api.batch do |batch_api|
563
563
  batch_api.get_connection("2", "invalidconnection")
564
564
  batch_api.get_object(KoalaTest.user1, {}, {"access_token" => @app_api.access_token})
565
565
  end
566
566
  expect(failed_call).to be_a(Koala::Facebook::ClientError)
567
- expect(koppel["id"]).not_to be_nil
567
+ expect(barackobama["id"]).not_to be_nil
568
568
  end
569
569
 
570
570
  it "handles different request methods" do
571
571
  result = @api.put_wall_post("Hello, world, from the test suite batch API!")
572
572
  wall_post = result["id"]
573
573
 
574
- wall_post, koppel = @api.batch do |batch_api|
574
+ wall_post, barackobama = @api.batch do |batch_api|
575
575
  batch_api.put_like(wall_post)
576
576
  batch_api.delete_object(wall_post)
577
577
  end
@@ -658,23 +658,23 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
658
658
  end
659
659
 
660
660
  it "allows you to create dependencies" do
661
- me, koppel = @api.batch do |batch_api|
661
+ me, barackobama = @api.batch do |batch_api|
662
662
  batch_api.get_object("me", {}, :batch_args => {:name => "getme"})
663
663
  batch_api.get_object(KoalaTest.user1, {}, :batch_args => {:depends_on => "getme"})
664
664
  end
665
665
 
666
666
  expect(me).to be_nil # gotcha! it's omitted because it's a successfully-executed dependency
667
- expect(koppel["id"]).not_to be_nil
667
+ expect(barackobama["id"]).not_to be_nil
668
668
  end
669
669
 
670
670
  it "properly handles dependencies that fail" do
671
- failed_call, koppel = @api.batch do |batch_api|
671
+ failed_call, barackobama = @api.batch do |batch_api|
672
672
  batch_api.get_connections("2", "invalidconnection", {}, :batch_args => {:name => "getdata"})
673
673
  batch_api.get_object(KoalaTest.user1, {}, :batch_args => {:depends_on => "getdata"})
674
674
  end
675
675
 
676
676
  expect(failed_call).to be_a(Koala::Facebook::ClientError)
677
- expect(koppel).to be_nil
677
+ expect(barackobama).to be_nil
678
678
  end
679
679
 
680
680
  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,28 +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(double("other results"))
21
- expect(@api.get_object('koppel', &post_processing)["result"]).to eq(result)
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(Koala::HTTPService::Response.new(200, "", ""))
27
- expect(@api.get_object('koppel', args, &post_processing)["result"]).to eq(result)
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
- allow(@api).to receive(:api).and_return({"data" => {"is_silhouette" => false, "url" => result}})
34
- expect(@api.get_picture('lukeshepard', &post_processing)["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)
35
38
  end
36
39
  end
37
40
 
38
41
  context '#get_page_access_token' do
39
42
  it 'returns result of block' do
40
43
  token = Koala::MockHTTPService::APP_ACCESS_TOKEN
41
- allow(@api).to receive(:api).and_return("access_token" => token)
44
+ allow(@api).to receive(:api).and_return(
45
+ Koala::HTTPService::Response.new(200, {"access_token" => token}.to_json, {})
46
+ )
42
47
  response = @api.get_page_access_token('facebook', &post_processing)
43
48
  expect(response["args"]).to eq(token)
44
49
  expect(response["result"]).to eq(result)
@@ -52,18 +57,18 @@ describe 'Koala::Facebook::GraphAPIMethods' do
52
57
 
53
58
  it "is enabled by default if an app secret is present" do
54
59
  api = Koala::Facebook::API.new(@token, "mysecret")
55
- 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)
56
61
  api.graph_call(path)
57
62
  end
58
63
 
59
64
  it "can be disabled manually" do
60
65
  api = Koala::Facebook::API.new(@token, "mysecret")
61
- 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)
62
67
  api.graph_call(path, {}, "get", appsecret_proof: false)
63
68
  end
64
69
 
65
70
  it "isn't included if no app secret is present" do
66
- expect(@api).to receive(:api).with(path, {}, 'get', {})
71
+ expect(@api).to receive(:api).with(path, {}, 'get', {}).and_return(dummy_response)
67
72
  @api.graph_call(path)
68
73
  end
69
74
  end
@@ -49,7 +49,7 @@ describe Koala::Facebook::API::GraphCollection do
49
49
  describe "when getting a whole page" do
50
50
  before(:each) do
51
51
  @second_page = {
52
- "data" => [:second, :page, :data],
52
+ "data" => ["second", "page", "data"],
53
53
  "paging" => {}
54
54
  }
55
55
  @base = double("base")
@@ -59,14 +59,14 @@ describe Koala::Facebook::API::GraphCollection do
59
59
 
60
60
  it "should return the previous page of results" do
61
61
  expect(@collection).to receive(:previous_page_params).and_return([@base, @args])
62
- expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(@second_page)
62
+ expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(Koala::HTTPService::Response.new(200, @second_page.to_json, {}))
63
63
  expect(Koala::Facebook::API::GraphCollection).to receive(:new).with(@second_page, @api).and_return(@page_of_results)
64
64
  expect(@collection.previous_page).to eq(@page_of_results)
65
65
  end
66
66
 
67
67
  it "should return the next page of results" do
68
68
  expect(@collection).to receive(:next_page_params).and_return([@base, @args])
69
- expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(@second_page)
69
+ expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(Koala::HTTPService::Response.new(200, @second_page.to_json, {}))
70
70
  expect(Koala::Facebook::API::GraphCollection).to receive(:new).with(@second_page, @api).and_return(@page_of_results)
71
71
 
72
72
  expect(@collection.next_page).to eq(@page_of_results)