koala 2.5.0 → 3.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -2
- data/Gemfile +1 -1
- data/changelog.md +26 -0
- data/lib/koala/api/batch_operation.rb +3 -6
- data/lib/koala/api/graph_api.rb +6 -45
- data/lib/koala/api/graph_batch_api.rb +1 -2
- data/lib/koala/api/graph_collection.rb +1 -5
- data/lib/koala/api/graph_error_checker.rb +1 -1
- data/lib/koala/api.rb +3 -7
- data/lib/koala/errors.rb +1 -1
- data/lib/koala/http_service/multipart_request.rb +6 -10
- data/lib/koala/http_service/request.rb +139 -0
- data/lib/koala/http_service/response.rb +0 -4
- data/lib/koala/http_service/uploadable_io.rb +0 -4
- data/lib/koala/http_service.rb +16 -68
- data/lib/koala/oauth.rb +3 -3
- data/lib/koala/version.rb +1 -1
- data/lib/koala.rb +2 -1
- data/readme.md +5 -26
- data/spec/cases/api_spec.rb +1 -7
- data/spec/cases/graph_api_batch_spec.rb +12 -22
- data/spec/cases/graph_api_spec.rb +0 -19
- data/spec/cases/graph_collection_spec.rb +18 -18
- data/spec/cases/graph_error_checker_spec.rb +6 -1
- data/spec/cases/http_service/request_spec.rb +240 -0
- data/spec/cases/http_service_spec.rb +102 -296
- data/spec/cases/koala_spec.rb +6 -1
- data/spec/cases/oauth_spec.rb +1 -1
- data/spec/cases/test_users_spec.rb +4 -1
- data/spec/cases/uploadable_io_spec.rb +31 -31
- data/spec/fixtures/mock_facebook_responses.yml +0 -37
- data/spec/spec_helper.rb +2 -2
- data/spec/support/graph_api_shared_examples.rb +6 -142
- data/spec/support/koala_test.rb +6 -6
- data/spec/support/mock_http_service.rb +6 -6
- data/spec/support/uploadable_io_shared_examples.rb +4 -4
- metadata +7 -7
- data/lib/koala/api/rest_api.rb +0 -135
- data/spec/support/rest_api_shared_examples.rb +0 -168
data/readme.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Koala [![Version](https://img.shields.io/gem/v/koala.svg)](https://rubygems.org/gems/koala) [![Dependencies](https://img.shields.io/gemnasium/arsduo/koala.svg)](https://gemnasium.com/arsduo/koala) [![Build Status](https://img.shields.io/travis/arsduo/koala.svg)](http://travis-ci.org/arsduo/koala) [![Code Climate](https://img.shields.io/codeclimate/github/arsduo/koala.svg)](https://codeclimate.com/github/arsduo/koala) [![Code Coverage](https://img.shields.io/codeclimate/coverage/github/arsduo/koala.svg)](https://codeclimate.com/github/arsduo/koala)
|
2
2
|
====
|
3
|
-
[Koala](http://github.com/arsduo/koala) is a Facebook library for Ruby, supporting the Graph API (including the batch requests and photo uploads),
|
3
|
+
[Koala](http://github.com/arsduo/koala) is a Facebook library for Ruby, supporting the Graph API (including the batch requests and photo uploads), realtime updates, test users, and OAuth validation. We wrote Koala with four goals:
|
4
4
|
|
5
5
|
* Lightweight: Koala should be as light and simple as Facebook’s own libraries, providing API accessors and returning simple JSON.
|
6
6
|
* Fast: Koala should, out of the box, be quick. Out of the box, we use Facebook's faster read-only servers when possible and if available, the Typhoeus gem to make snappy Facebook requests. Of course, that brings us to our next topic:
|
@@ -39,7 +39,7 @@ Then, go exploring:
|
|
39
39
|
|
40
40
|
```ruby
|
41
41
|
require 'koala'
|
42
|
-
|
42
|
+
|
43
43
|
@graph = Koala::Facebook::API.new(oauth_access_token)
|
44
44
|
|
45
45
|
profile = @graph.get_object("me")
|
@@ -115,27 +115,6 @@ the results apart from a long list of array entries:
|
|
115
115
|
|
116
116
|
Check out the wiki for more details and examples.
|
117
117
|
|
118
|
-
The REST API
|
119
|
-
------------
|
120
|
-
|
121
|
-
Where the Graph API and the old REST API overlap, you should choose the Graph API. Unfortunately, that overlap is far from complete, and there are many important API calls that can't yet be done via the Graph.
|
122
|
-
|
123
|
-
Fortunately, Koala supports the REST API using the very same interface; to use this, instantiate an API:
|
124
|
-
```ruby
|
125
|
-
@rest = Koala::Facebook::API.new(oauth_access_token)
|
126
|
-
|
127
|
-
@rest.fql_query(my_fql_query) # convenience method
|
128
|
-
@rest.fql_multiquery(fql_query_hash) # convenience method
|
129
|
-
@rest.rest_call("stream.publish", arguments_hash) # generic version
|
130
|
-
```
|
131
|
-
|
132
|
-
Of course, you can use the Graph API methods on the same object -- the power of two APIs right in the palm of your hand.
|
133
|
-
```ruby
|
134
|
-
@api = Koala::Facebook::API.new(oauth_access_token)
|
135
|
-
fql = @api.fql_query(my_fql_query)
|
136
|
-
@api.put_wall_post(process_result(fql))
|
137
|
-
```
|
138
|
-
|
139
118
|
Configuration
|
140
119
|
-------------
|
141
120
|
|
@@ -146,7 +125,7 @@ require 'koala'
|
|
146
125
|
|
147
126
|
Koala.configure do |config|
|
148
127
|
config.graph_server = 'my-graph-mock.mysite.com'
|
149
|
-
#
|
128
|
+
# another common option: `dialog_host`
|
150
129
|
# see lib/koala/http_service.rb
|
151
130
|
end
|
152
131
|
```
|
@@ -157,7 +136,7 @@ tier and video upload matching and replacement strings.
|
|
157
136
|
OAuth
|
158
137
|
-----
|
159
138
|
|
160
|
-
You can use the Graph
|
139
|
+
You can use the Graph API without an OAuth access token, but the real magic happens when you provide Facebook an OAuth token to prove you're authenticated. Koala provides an OAuth class to make that process easy:
|
161
140
|
```ruby
|
162
141
|
@oauth = Koala::Facebook::OAuth.new(app_id, app_secret, callback_url)
|
163
142
|
```
|
@@ -225,7 +204,7 @@ For more information about meet_challenge and the RealtimeUpdates class, check o
|
|
225
204
|
Test Users
|
226
205
|
----------
|
227
206
|
|
228
|
-
We also support the test users API, allowing you to conjure up fake users and command them to do your bidding using the Graph
|
207
|
+
We also support the test users API, allowing you to conjure up fake users and command them to do your bidding using the Graph API:
|
229
208
|
```ruby
|
230
209
|
@test_users = Koala::Facebook::TestUsers.new(app_id: id, secret: secret)
|
231
210
|
user = @test_users.create(is_app_installed, desired_permissions)
|
data/spec/cases/api_spec.rb
CHANGED
@@ -128,7 +128,7 @@ describe "Koala::Facebook::API" do
|
|
128
128
|
allow(Koala).to receive(:make_request).and_return(response)
|
129
129
|
|
130
130
|
json_body = double('JSON body')
|
131
|
-
allow(JSON).to receive(:
|
131
|
+
allow(JSON).to receive(:parse).and_return([json_body])
|
132
132
|
|
133
133
|
expect(@service.api('anything')).to eq(json_body)
|
134
134
|
end
|
@@ -181,9 +181,6 @@ describe "Koala::Facebook::API" do
|
|
181
181
|
@api = Koala::Facebook::API.new(@token)
|
182
182
|
end
|
183
183
|
|
184
|
-
it_should_behave_like "Koala RestAPI"
|
185
|
-
it_should_behave_like "Koala RestAPI with an access token"
|
186
|
-
|
187
184
|
it_should_behave_like "Koala GraphAPI"
|
188
185
|
it_should_behave_like "Koala GraphAPI with an access token"
|
189
186
|
it_should_behave_like "Koala GraphAPI with GraphCollection"
|
@@ -194,9 +191,6 @@ describe "Koala::Facebook::API" do
|
|
194
191
|
@api = Koala::Facebook::API.new
|
195
192
|
end
|
196
193
|
|
197
|
-
it_should_behave_like "Koala RestAPI"
|
198
|
-
it_should_behave_like "Koala RestAPI without an access token"
|
199
|
-
|
200
194
|
it_should_behave_like "Koala GraphAPI"
|
201
195
|
it_should_behave_like "Koala GraphAPI without an access token"
|
202
196
|
it_should_behave_like "Koala GraphAPI with GraphCollection"
|
@@ -58,11 +58,11 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
58
58
|
@batch_queue = []
|
59
59
|
allow(Koala::Facebook::API).to receive(:batch_calls).and_return(@batch_queue)
|
60
60
|
|
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)
|
61
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:new).with(@binary).and_return(@uploadable_io)
|
62
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).and_return(false)
|
63
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).with(@binary).and_return(true)
|
64
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).with(@uploadable_io).and_return(true)
|
65
|
+
allow(@uploadable_io).to receive(:is_a?).with(Koala::HTTPService::UploadableIO).and_return(true)
|
66
66
|
|
67
67
|
@args[:method] = "post" # files are always post
|
68
68
|
end
|
@@ -243,11 +243,11 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
243
243
|
describe "with binary files" do
|
244
244
|
before :each do
|
245
245
|
@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)
|
246
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).and_return(false)
|
247
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:binary_content?).with(@binary).and_return(true)
|
248
248
|
@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)
|
249
|
+
allow(Koala::HTTPService::UploadableIO).to receive(:new).with(@binary).and_return(@uploadable_io)
|
250
|
+
allow(@uploadable_io).to receive(:is_a?).with(Koala::HTTPService::UploadableIO).and_return(true)
|
251
251
|
|
252
252
|
@batch_queue = []
|
253
253
|
allow(Koala::Facebook::API).to receive(:batch_calls).and_return(@batch_queue)
|
@@ -486,7 +486,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
486
486
|
batch_api.get_object('me')
|
487
487
|
batch_api.get_connections('me', 'friends')
|
488
488
|
end
|
489
|
-
expect(friends).to be_a(Koala::Facebook::GraphCollection)
|
489
|
+
expect(friends).to be_a(Koala::Facebook::API::GraphCollection)
|
490
490
|
end
|
491
491
|
|
492
492
|
it 'turns pageable results into GraphCollections' do
|
@@ -519,7 +519,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
519
519
|
batch_api.get_connections(@app_id, 'insights', {}, {"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::GraphCollection)
|
522
|
+
expect(insights).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
|
@@ -528,7 +528,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
528
528
|
batch_api.get_connections(@app_id, 'insights', {}, {: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::GraphCollection)
|
531
|
+
expect(insights).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
|
@@ -577,16 +577,6 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
|
|
577
577
|
end
|
578
578
|
end
|
579
579
|
|
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
580
|
describe 'with post-processing callback' do
|
591
581
|
let(:me_result) { double("me result") }
|
592
582
|
let(:friends_result) { [double("friends result")] }
|
@@ -35,25 +35,6 @@ describe 'Koala::Facebook::GraphAPIMethods' do
|
|
35
35
|
end
|
36
36
|
end
|
37
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)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
38
|
context '#get_page_access_token' do
|
58
39
|
it 'returns result of block' do
|
59
40
|
token = Koala::MockHTTPService::APP_ACCESS_TOKEN
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Koala::Facebook::GraphCollection do
|
3
|
+
describe Koala::Facebook::API::GraphCollection do
|
4
4
|
let(:paging){ {:paging => true} }
|
5
5
|
|
6
6
|
before(:each) do
|
@@ -10,15 +10,15 @@ describe Koala::Facebook::GraphCollection do
|
|
10
10
|
"summary" => [3]
|
11
11
|
}
|
12
12
|
@api = Koala::Facebook::API.new("123")
|
13
|
-
@collection = Koala::Facebook::GraphCollection.new(@result, @api)
|
13
|
+
@collection = Koala::Facebook::API::GraphCollection.new(@result, @api)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "subclasses Array" do
|
17
|
-
expect(Koala::Facebook::GraphCollection.ancestors).to include(Array)
|
17
|
+
expect(Koala::Facebook::API::GraphCollection.ancestors).to include(Array)
|
18
18
|
end
|
19
19
|
|
20
20
|
it "creates an array-like object" do
|
21
|
-
expect(Koala::Facebook::GraphCollection.new(@result, @api)).to be_an(Array)
|
21
|
+
expect(Koala::Facebook::API::GraphCollection.new(@result, @api)).to be_an(Array)
|
22
22
|
end
|
23
23
|
|
24
24
|
it "contains the result data" do
|
@@ -60,14 +60,14 @@ describe Koala::Facebook::GraphCollection do
|
|
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
62
|
expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(@second_page)
|
63
|
-
expect(Koala::Facebook::GraphCollection).to receive(:new).with(@second_page, @api).and_return(@page_of_results)
|
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
69
|
expect(@api).to receive(:api).with(@base, @args, anything, anything).and_return(@second_page)
|
70
|
-
expect(Koala::Facebook::GraphCollection).to receive(:new).with(@second_page, @api).and_return(@page_of_results)
|
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)
|
73
73
|
end
|
@@ -84,13 +84,13 @@ describe Koala::Facebook::GraphCollection do
|
|
84
84
|
describe "#parse_page_url" do
|
85
85
|
it "should pass the url to the class method" do
|
86
86
|
url = double("url")
|
87
|
-
expect(Koala::Facebook::GraphCollection).to receive(:parse_page_url).with(url)
|
87
|
+
expect(Koala::Facebook::API::GraphCollection).to receive(:parse_page_url).with(url)
|
88
88
|
@collection.parse_page_url(url)
|
89
89
|
end
|
90
90
|
|
91
91
|
it "should return the result of the class method" do
|
92
92
|
parsed_content = double("parsed_content")
|
93
|
-
allow(Koala::Facebook::GraphCollection).to receive(:parse_page_url).and_return(parsed_content)
|
93
|
+
allow(Koala::Facebook::API::GraphCollection).to receive(:parse_page_url).and_return(parsed_content)
|
94
94
|
expect(@collection.parse_page_url(double("url"))).to eq(parsed_content)
|
95
95
|
end
|
96
96
|
end
|
@@ -98,23 +98,23 @@ describe Koala::Facebook::GraphCollection do
|
|
98
98
|
describe ".parse_page_url" do
|
99
99
|
it "should return the base as the first array entry" do
|
100
100
|
base = "url_path"
|
101
|
-
expect(Koala::Facebook::GraphCollection.parse_page_url("http://facebook.com/#{base}?anything").first).to eq(base)
|
101
|
+
expect(Koala::Facebook::API::GraphCollection.parse_page_url("http://facebook.com/#{base}?anything").first).to eq(base)
|
102
102
|
end
|
103
103
|
|
104
104
|
it "should return the arguments as a hash as the last array entry" do
|
105
105
|
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)
|
106
|
+
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
107
|
end
|
108
108
|
|
109
109
|
it "works with non-.com addresses" do
|
110
110
|
base = "url_path"
|
111
111
|
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])
|
112
|
+
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
113
|
end
|
114
114
|
|
115
115
|
it "works with addresses with irregular characters" do
|
116
116
|
access_token = "appid123a|fdcba"
|
117
|
-
base, args_hash = Koala::Facebook::GraphCollection.parse_page_url("http://facebook.com/foo?token=#{access_token}")
|
117
|
+
base, args_hash = Koala::Facebook::API::GraphCollection.parse_page_url("http://facebook.com/foo?token=#{access_token}")
|
118
118
|
expect(args_hash["token"]).to eq(access_token)
|
119
119
|
end
|
120
120
|
end
|
@@ -123,29 +123,29 @@ describe Koala::Facebook::GraphCollection do
|
|
123
123
|
describe ".evaluate" do
|
124
124
|
it "returns the original result if it's provided a non-hash result" do
|
125
125
|
result = []
|
126
|
-
expect(Koala::Facebook::GraphCollection.evaluate(result, @api)).to eq(result)
|
126
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq(result)
|
127
127
|
end
|
128
128
|
|
129
129
|
it "returns the original result if it's provided a nil result" do
|
130
130
|
result = nil
|
131
|
-
expect(Koala::Facebook::GraphCollection.evaluate(result, @api)).to eq(result)
|
131
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq(result)
|
132
132
|
end
|
133
133
|
|
134
134
|
it "returns the original result if the result doesn't have a data key" do
|
135
135
|
result = {"paging" => {}}
|
136
|
-
expect(Koala::Facebook::GraphCollection.evaluate(result, @api)).to eq(result)
|
136
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq(result)
|
137
137
|
end
|
138
138
|
|
139
139
|
it "returns the original result if the result's data key isn't an array" do
|
140
140
|
result = {"data" => {}, "paging" => {}}
|
141
|
-
expect(Koala::Facebook::GraphCollection.evaluate(result, @api)).to eq(result)
|
141
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq(result)
|
142
142
|
end
|
143
143
|
|
144
144
|
it "returns a new GraphCollection of the result if it has an array data key and a paging key" do
|
145
145
|
result = {"data" => [], "paging" => {}}
|
146
146
|
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)
|
147
|
+
expect(Koala::Facebook::API::GraphCollection).to receive(:new).with(result, @api).and_return(expected)
|
148
|
+
expect(Koala::Facebook::API::GraphCollection.evaluate(result, @api)).to eq(expected)
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
@@ -54,6 +54,12 @@ module Koala
|
|
54
54
|
expect(error.response_body).to eq(body)
|
55
55
|
end
|
56
56
|
|
57
|
+
it "returns a ClientError if the body is empty" do
|
58
|
+
body.replace("")
|
59
|
+
expect(error).to be_a(ClientError)
|
60
|
+
expect(error.response_body).to eq(body)
|
61
|
+
end
|
62
|
+
|
57
63
|
it "adds error data from the body" do
|
58
64
|
error_data = {
|
59
65
|
"type" => "FB error type",
|
@@ -113,4 +119,3 @@ module Koala
|
|
113
119
|
end
|
114
120
|
end
|
115
121
|
end
|
116
|
-
|
@@ -0,0 +1,240 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Koala
|
4
|
+
module HTTPService
|
5
|
+
RSpec.describe Request do
|
6
|
+
let(:path) { "/foo" }
|
7
|
+
let(:args) { {"a" => 2, "b" => 3, "access_token" => "a_token"} }
|
8
|
+
let(:verb) { "get" }
|
9
|
+
let(:options) { {an: :option} }
|
10
|
+
let(:request) { Request.new(path: path, args: args, verb: verb, options: options) }
|
11
|
+
|
12
|
+
shared_context post: true do
|
13
|
+
let(:verb) { "post" }
|
14
|
+
end
|
15
|
+
|
16
|
+
shared_context delete: true do
|
17
|
+
let(:verb) { "delete" }
|
18
|
+
end
|
19
|
+
|
20
|
+
shared_context put: true do
|
21
|
+
let(:verb) { "put" }
|
22
|
+
end
|
23
|
+
|
24
|
+
it "raises an ArgumentError if no verb is supplied" do
|
25
|
+
expect { Request.new(path: path) }.to raise_exception(ArgumentError)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "raises an ArgumentError if no path is supplied" do
|
29
|
+
expect { Request.new(verb: verb) }.to raise_exception(ArgumentError)
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#verb" do
|
33
|
+
it "returns get for get" do
|
34
|
+
expect(Request.new(path: path, verb: "get").verb).to eq("get")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns post for post" do
|
38
|
+
expect(Request.new(path: path, verb: "post").verb).to eq("post")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "returns post for put" do
|
42
|
+
expect(Request.new(path: path, verb: "put").verb).to eq("post")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns post for delete" do
|
46
|
+
expect(Request.new(path: path, verb: "delete").verb).to eq("post")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#path" do
|
51
|
+
context "if there's no API version" do
|
52
|
+
it "returns the path" do
|
53
|
+
expect(request.path).to eq(path)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "if there's an API version" do
|
58
|
+
shared_examples_for :including_the_version do
|
59
|
+
it "prefixes the version appropriately when the path starts with /" do
|
60
|
+
expect(Request.new(path: "/foo", verb: "get", options: options).path).to eq("/#{version}/foo")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "prefixes the version appropriately when the path doesn't start with /" do
|
64
|
+
expect(Request.new(path: "foo", verb: "get", options: options).path).to eq("/#{version}/foo")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "set by Koala.config" do
|
69
|
+
let(:version) { "v2.1" }
|
70
|
+
|
71
|
+
before :each do
|
72
|
+
allow(Koala.config).to receive(:api_version).and_return(version)
|
73
|
+
end
|
74
|
+
|
75
|
+
it_should_behave_like :including_the_version
|
76
|
+
end
|
77
|
+
|
78
|
+
context "set in options" do
|
79
|
+
let(:version) { "v2.1" }
|
80
|
+
|
81
|
+
let(:options) { {api_version: version} }
|
82
|
+
|
83
|
+
it_should_behave_like :including_the_version
|
84
|
+
end
|
85
|
+
|
86
|
+
context "for versions without a ." do
|
87
|
+
let(:version) { "v21" }
|
88
|
+
|
89
|
+
let(:options) { {api_version: version} }
|
90
|
+
|
91
|
+
it_should_behave_like :including_the_version
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#post_args" do
|
97
|
+
it "returns {} for get" do
|
98
|
+
expect(request.post_args).to eq({})
|
99
|
+
end
|
100
|
+
|
101
|
+
it "returns args for post", :post do
|
102
|
+
expect(request.post_args).to eq(args)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns args + method: delete for delete", :delete do
|
106
|
+
expect(request.post_args).to eq(args.merge(method: "delete"))
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns args + method: put for put", :put do
|
110
|
+
expect(request.post_args).to eq(args.merge(method: "put"))
|
111
|
+
end
|
112
|
+
|
113
|
+
it "turns any UploadableIOs to UploadIOs" do
|
114
|
+
# technically this is done for all requests, but you don't send GET requests with files
|
115
|
+
upload_io = double("UploadIO")
|
116
|
+
u = Koala::HTTPService::UploadableIO.new("/path/to/stuff", "img/jpg")
|
117
|
+
allow(u).to receive(:to_upload_io).and_return(upload_io)
|
118
|
+
request = Request.new(path: path, verb: "post", args: {an_upload: u})
|
119
|
+
expect(request.post_args[:an_upload]).to eq(upload_io)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#json?" do
|
124
|
+
it "returns false if the option for JSON isn't set" do
|
125
|
+
expect(request).not_to be_json
|
126
|
+
end
|
127
|
+
|
128
|
+
context "if JSON is set" do
|
129
|
+
let(:options) { {format: :json} }
|
130
|
+
|
131
|
+
it "returns true if it is" do
|
132
|
+
expect(request).to be_json
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#options" do
|
138
|
+
it "returns the options provided" do
|
139
|
+
expect(request.options).to include(options)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "merges in any global options" do
|
143
|
+
global_options = {some: :opts}
|
144
|
+
HTTPService.http_options = global_options
|
145
|
+
results = request.options
|
146
|
+
HTTPService.http_options = {}
|
147
|
+
expect(results).to include(global_options)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "overwrites any global options with equivalent ones" do
|
151
|
+
options = {foo: :bar}
|
152
|
+
HTTPService.http_options = {foo: 2}
|
153
|
+
results = Request.new(path: path, args: args, verb: verb, options: options).options
|
154
|
+
HTTPService.http_options = {}
|
155
|
+
expect(results).to include(options)
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "get parameters" do
|
159
|
+
it "includes the parameters for a get " do
|
160
|
+
expect(request.options[:params]).to eq(args)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "returns {} for post", :post do
|
164
|
+
expect(request.options[:params]).to eq({})
|
165
|
+
end
|
166
|
+
|
167
|
+
it "returns {} for delete", :delete do
|
168
|
+
expect(request.options[:params]).to eq({})
|
169
|
+
end
|
170
|
+
|
171
|
+
it "returns {} for put", :put do
|
172
|
+
expect(request.options[:params]).to eq({})
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "ssl options" do
|
177
|
+
it "does nothing if there's no access token" do
|
178
|
+
request_options = Request.new(path: path, args: args.delete_if {|k, _v| k == "access_token"}, verb: verb, options: options).options
|
179
|
+
expect(request_options).not_to include(:ssl, :use_ssl)
|
180
|
+
end
|
181
|
+
|
182
|
+
context "if there is an access_token" do
|
183
|
+
it "includes the default SSL options" do
|
184
|
+
expect(request.options).to include(use_ssl: true, ssl: {verify: true})
|
185
|
+
end
|
186
|
+
|
187
|
+
it "incorporates any provided SSL options" do
|
188
|
+
new_ssl_options = {an: :option2}
|
189
|
+
request_options = Request.new(path: path, args: args, verb: verb, options: options.merge(ssl: new_ssl_options)).options
|
190
|
+
expect(request_options[:ssl]).to include(new_ssl_options)
|
191
|
+
end
|
192
|
+
|
193
|
+
it "overrides default SSL options with what's provided" do
|
194
|
+
new_ssl_options = {verify: :dunno}
|
195
|
+
request_options = Request.new(path: path, args: args, verb: verb, options: options.merge(ssl: new_ssl_options)).options
|
196
|
+
expect(request_options[:ssl]).to include(new_ssl_options)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "server" do
|
202
|
+
describe "with no options" do
|
203
|
+
it "returns the graph server by default" do
|
204
|
+
expect(request.server).to eq("https://graph.facebook.com")
|
205
|
+
end
|
206
|
+
|
207
|
+
it "uses another base server if specified" do
|
208
|
+
Koala.config.graph_server = "foo"
|
209
|
+
expect(request.server).to eq("https://foo")
|
210
|
+
end
|
211
|
+
|
212
|
+
context "if options[:use_ssl] is false (e.g. no access token)" do
|
213
|
+
let(:args) { {"a" => "b"} }
|
214
|
+
|
215
|
+
it "uses http" do
|
216
|
+
expect(request.server).to eq("http://graph.facebook.com")
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context "if options[:beta]" do
|
221
|
+
let(:options) { {beta: true} }
|
222
|
+
|
223
|
+
it "returns https if options[:beta]" do
|
224
|
+
expect(request.server).to eq("https://graph.beta.facebook.com")
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
context "if options[:video]" do
|
229
|
+
let(:options) { {video: true} }
|
230
|
+
|
231
|
+
it "returns https if options[:video]" do
|
232
|
+
expect(request.server).to eq("https://graph-video.facebook.com")
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|