koala 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +15 -0
- data/koala.gemspec +1 -1
- data/lib/koala/http_service.rb +3 -2
- data/lib/koala/multipart_request.rb +35 -0
- data/lib/koala/oauth.rb +5 -2
- data/lib/koala/rest_api.rb +5 -0
- data/lib/koala/test_users.rb +1 -1
- data/lib/koala/version.rb +1 -1
- data/lib/koala.rb +1 -0
- data/readme.md +22 -5
- data/spec/cases/api_spec.rb +10 -10
- data/spec/cases/http_service_spec.rb +13 -12
- data/spec/cases/multipart_request_spec.rb +66 -0
- data/spec/cases/oauth_spec.rb +105 -67
- data/spec/cases/rest_api_spec.rb +0 -19
- data/spec/cases/test_users_spec.rb +15 -13
- data/spec/fixtures/mock_facebook_responses.yml +13 -0
- data/spec/support/graph_api_shared_examples.rb +82 -56
- data/spec/support/koala_test.rb +17 -15
- data/spec/support/rest_api_shared_examples.rb +69 -25
- metadata +89 -57
data/CHANGELOG
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
v1.2.1
|
2
|
+
New methods:
|
3
|
+
-- RestAPI.set_app_properties handles JSON-encoding application properties
|
4
|
+
Updated methods:
|
5
|
+
-- OAuth.get_user_from_cookie works with the new signed cookie format (thanks, gmccreight!)
|
6
|
+
-- Beta server URLs are now correct
|
7
|
+
-- OAuth.parse_signed_request now raises an informative error if the signed_request is malformed
|
8
|
+
Internal improvements:
|
9
|
+
-- Koala::Multipart middleware properly encoding nested parameters (hashes) in POSTs
|
10
|
+
-- Updated readme, changelog, etc.
|
11
|
+
Testing improvements:
|
12
|
+
-- Live tests with test users now clean up all fake users they create
|
13
|
+
-- Removed duplicate test cases
|
14
|
+
-- Live tests with test users no longer delete each object they create, speeding things up
|
15
|
+
|
1
16
|
v1.2
|
2
17
|
New methods:
|
3
18
|
-- API is now the main API class, contains both Graph and REST methods
|
data/koala.gemspec
CHANGED
@@ -5,7 +5,7 @@ require 'koala/version'
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = %q{koala}
|
7
7
|
s.version = Koala::VERSION
|
8
|
-
s.date = %q{2011-
|
8
|
+
s.date = %q{2011-10-04}
|
9
9
|
|
10
10
|
s.summary = %q{A lightweight, flexible library for Facebook with support for the Graph API, the REST API, realtime updates, and OAuth authentication.}
|
11
11
|
s.description = %q{Koala is a lightweight, flexible Ruby SDK for Facebook. It allows read/write access to the social graph via the Graph and REST APIs, as well as support for realtime updates and OAuth and Facebook Connect authentication. Koala is fully tested and supports Net::HTTP and Typhoeus connections out of the box and can accept custom modules for other services.}
|
data/lib/koala/http_service.rb
CHANGED
@@ -20,7 +20,7 @@ module Koala
|
|
20
20
|
@http_options ||= {}
|
21
21
|
|
22
22
|
DEFAULT_MIDDLEWARE = Proc.new do |builder|
|
23
|
-
builder.
|
23
|
+
builder.use Koala::MultipartRequest
|
24
24
|
builder.request :url_encoded
|
25
25
|
builder.adapter Faraday.default_adapter
|
26
26
|
end
|
@@ -28,7 +28,8 @@ module Koala
|
|
28
28
|
def self.server(options = {})
|
29
29
|
server = "#{options[:rest_api] ? Facebook::REST_SERVER : Facebook::GRAPH_SERVER}"
|
30
30
|
server.gsub!(/\.facebook/, "-video.facebook") if options[:video]
|
31
|
-
|
31
|
+
server.gsub!(/\.facebook/, ".beta.facebook") if options[:beta]
|
32
|
+
"#{options[:use_ssl] ? "https" : "http"}://#{server}"
|
32
33
|
end
|
33
34
|
|
34
35
|
def self.make_request(path, args, verb, options = {})
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Koala
|
4
|
+
class MultipartRequest < Faraday::Request::Multipart
|
5
|
+
# Facebook expects nested parameters to be passed in a certain way
|
6
|
+
# Based on our testing (https://github.com/arsduo/koala/issues/125),
|
7
|
+
# Faraday needs two changes to make that work:
|
8
|
+
# 1) [] need to be escaped (e.g. params[foo]=bar ==> params%5Bfoo%5D=bar)
|
9
|
+
# 2) such messages need to be multipart-encoded
|
10
|
+
|
11
|
+
self.mime_type = 'multipart/form-data'.freeze
|
12
|
+
|
13
|
+
def process_request?(env)
|
14
|
+
# if the request values contain any hashes or arrays, multipart it
|
15
|
+
super || !!(env[:body].respond_to?(:values) && env[:body].values.find {|v| v.is_a?(Hash) || v.is_a?(Array)})
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def process_params(params, prefix = nil, pieces = nil, &block)
|
20
|
+
params.inject(pieces || []) do |all, (key, value)|
|
21
|
+
key = "#{prefix}%5B#{key}%5D" if prefix
|
22
|
+
|
23
|
+
case value
|
24
|
+
when Array
|
25
|
+
values = value.inject([]) { |a,v| a << [nil, v] }
|
26
|
+
process_params(values, key, all, &block)
|
27
|
+
when Hash
|
28
|
+
process_params(value, key, all, &block)
|
29
|
+
else
|
30
|
+
all << block.call(key, value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/koala/oauth.rb
CHANGED
@@ -27,7 +27,8 @@ module Koala
|
|
27
27
|
|
28
28
|
def get_user_from_cookie(cookies)
|
29
29
|
if info = get_user_info_from_cookies(cookies)
|
30
|
-
|
30
|
+
# signed cookie has user_id, unsigned cookie has uid
|
31
|
+
string = info["user_id"] || info["uid"]
|
31
32
|
end
|
32
33
|
end
|
33
34
|
alias_method :get_user_from_cookies, :get_user_from_cookie
|
@@ -85,6 +86,8 @@ module Koala
|
|
85
86
|
# for a more accurate reference implementation strategy.
|
86
87
|
def parse_signed_request(input)
|
87
88
|
encoded_sig, encoded_envelope = input.split('.', 2)
|
89
|
+
raise 'SignedRequest: Invalid (incomplete) signature data' unless encoded_sig && encoded_envelope
|
90
|
+
|
88
91
|
signature = base64_url_decode(encoded_sig).unpack("H*").first
|
89
92
|
envelope = MultiJson.decode(base64_url_decode(encoded_envelope))
|
90
93
|
|
@@ -94,7 +97,7 @@ module Koala
|
|
94
97
|
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, @app_secret, encoded_envelope)
|
95
98
|
raise 'SignedRequest: Invalid signature' if (signature != hmac)
|
96
99
|
|
97
|
-
|
100
|
+
envelope
|
98
101
|
end
|
99
102
|
|
100
103
|
# from session keys
|
data/lib/koala/rest_api.rb
CHANGED
@@ -13,6 +13,11 @@ module Koala
|
|
13
13
|
results.inject({}) {|outcome, data| outcome[data["name"]] = data["fql_result_set"]; outcome}
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
17
|
+
def set_app_properties(properties, args = {}, options = {})
|
18
|
+
raise APIError.new({"type" => "KoalaMissingAccessToken", "message" => "setAppProperties requires an access token"}) unless @access_token
|
19
|
+
rest_call("admin.setAppProperties", args.merge(:properties => MultiJson.encode(properties)), options, "post")
|
20
|
+
end
|
16
21
|
|
17
22
|
def rest_call(fb_method, args = {}, options = {}, method = "get")
|
18
23
|
options = options.merge!(:rest_api => true, :read_only => READ_ONLY_METHODS.include?(fb_method.to_s))
|
data/lib/koala/test_users.rb
CHANGED
@@ -31,7 +31,7 @@ module Koala
|
|
31
31
|
# Creates and returns a test user
|
32
32
|
args['installed'] = installed
|
33
33
|
args['permissions'] = (permissions.is_a?(Array) ? permissions.join(",") : permissions) if installed
|
34
|
-
|
34
|
+
@api.graph_call(accounts_path, args, "post", options)
|
35
35
|
end
|
36
36
|
|
37
37
|
def list
|
data/lib/koala/version.rb
CHANGED
data/lib/koala.rb
CHANGED
data/readme.md
CHANGED
@@ -12,11 +12,7 @@ Koala
|
|
12
12
|
Facebook Changes on October 1, 2011
|
13
13
|
---
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
To test your application, upgrade to the latest version of Koala (see below) and configure your application according to Facebook's [OAuth 2.0 and HTTPS Migration](https://developers.facebook.com/docs/oauth2-https-migration/) guide. If you have the appropriate calls to get_user_info_from_cookies (apps using the Javascript SDK) and/or parse_signed_params (for Canvas and tab apps), your application should work without a hitch.
|
18
|
-
|
19
|
-
_Note_: in their new secure cookie format, Facebook provides an OAuth code, which Koala automatically exchanges for an access token. Because this involves a call to Facebook's servers, you should consider storing the user's access token in their session and only calling get_user_info_from_cookies when necessary (access_token not present, you discover it's expired, etc.). Otherwise, you'll be calling out to Facebook each time the user loads a page, slowing down your site. (As we figure out best practices for this, we'll update the wiki.)
|
15
|
+
Koala 1.2 supports all of Facebook's new authentication schemes, which were introduced on October 1, 2011. If you have the appropriate calls to get_user_info_from_cookies (apps using the Javascript SDK) and/or parse_signed_params (for Canvas and tab apps), your application should work without a hitch. For more information, see Facebook's [OAuth 2.0 and HTTPS Migration](https://developers.facebook.com/docs/oauth2-https-migration/) guide.
|
20
16
|
|
21
17
|
Installation
|
22
18
|
---
|
@@ -94,25 +90,31 @@ Of course, you can use the Graph API methods on the same object -- the power of
|
|
94
90
|
OAuth
|
95
91
|
-----
|
96
92
|
You can use the Graph and REST APIs 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:
|
93
|
+
|
97
94
|
@oauth = Koala::Facebook::OAuth.new(app_id, app_secret, callback_url)
|
98
95
|
|
99
96
|
If your application uses Koala and the Facebook [JavaScript SDK](http://github.com/facebook/connect-js) (formerly Facebook Connect), you can use the OAuth class to parse the cookies:
|
97
|
+
|
100
98
|
@oauth.get_user_from_cookies(cookies) # gets the user's ID
|
101
99
|
@oauth.get_user_info_from_cookies(cookies) # parses and returns the entire hash
|
102
100
|
|
103
101
|
And if you have to use the more complicated [redirect-based OAuth process](http://developers.facebook.com/docs/authentication/), Koala helps out there, too:
|
102
|
+
|
104
103
|
# generate authenticating URL
|
105
104
|
@oauth.url_for_oauth_code
|
106
105
|
# fetch the access token once you have the code
|
107
106
|
@oauth.get_access_token(code)
|
108
107
|
|
109
108
|
You can also get your application's own access token, which can be used without a user session for subscriptions and certain other requests:
|
109
|
+
|
110
110
|
@oauth.get_app_access_token
|
111
111
|
|
112
112
|
For those building apps on Facebook, parsing signed requests is simple:
|
113
|
+
|
113
114
|
@oauth.parse_signed_request(signed_request_string)
|
114
115
|
|
115
116
|
Or, if for some horrible reason, you're still using session keys, despair not! It's easy to turn them into shiny, modern OAuth tokens:
|
117
|
+
|
116
118
|
@oauth.get_token_from_session_key(session_key)
|
117
119
|
@oauth.get_tokens_from_session_keys(array_of_session_keys)
|
118
120
|
|
@@ -155,12 +157,27 @@ We also support the test users API, allowing you to conjure up fake users and co
|
|
155
157
|
# or, if you want to make a whole community:
|
156
158
|
@test_users.create_network(network_size, is_app_installed, common_permissions)
|
157
159
|
|
160
|
+
Talking to Facebook
|
161
|
+
-----
|
162
|
+
|
163
|
+
Koala uses Faraday to make HTTP requests, which means you have complete control over how your app makes HTTP requests to Facebook. You can set Faraday options globally or pass them in on a per-request (or both):
|
164
|
+
|
165
|
+
# Set an SSL certificate to avoid Net::HTTP errors
|
166
|
+
Koala.http_service.http_options = {
|
167
|
+
:ssl => { :ca_path => "/etc/ssl/certs" }
|
168
|
+
}
|
169
|
+
# or on a per-request basis
|
170
|
+
@api.get_object(id, args_hash, { :timeout => 10 })
|
171
|
+
|
172
|
+
The <a href="https://github.com/arsduo/koala/wiki/HTTP-Services">HTTP Services wiki page</a> has more information on what options are available, as well as on how to configure your own Faraday middleware stack (for instance, to implement request logging).
|
173
|
+
|
158
174
|
See examples, ask questions
|
159
175
|
-----
|
160
176
|
Some resources to help you as you play with Koala and the Graph API:
|
161
177
|
|
162
178
|
* Complete Koala documentation <a href="http://wiki.github.com/arsduo/koala/">on the wiki</a>
|
163
179
|
* The <a href="http://groups.google.com/group/koala-users">Koala users group</a> on Google Groups, the place for your Koala and API questions
|
180
|
+
* Facebook's <a href="http://developers.facebook.com/tools/explorer/">Graph API Explorer</a>, where you can play with the Graph API in your browser
|
164
181
|
* The Koala-powered <a href="http://oauth.twoalex.com" target="_blank">OAuth Playground</a>, where you can easily generate OAuth access tokens and any other data needed to test out the APIs or OAuth
|
165
182
|
|
166
183
|
Testing
|
data/spec/cases/api_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe "Koala::Facebook::API" do
|
|
5
5
|
@service = Koala::Facebook::API.new
|
6
6
|
end
|
7
7
|
|
8
|
-
it "
|
8
|
+
it "doesn't include an access token if none was given" do
|
9
9
|
Koala.should_receive(:make_request).with(
|
10
10
|
anything,
|
11
11
|
hash_not_including('access_token' => 1),
|
@@ -16,7 +16,7 @@ describe "Koala::Facebook::API" do
|
|
16
16
|
@service.api('anything')
|
17
17
|
end
|
18
18
|
|
19
|
-
it "
|
19
|
+
it "includes an access token if given" do
|
20
20
|
token = 'adfadf'
|
21
21
|
service = Koala::Facebook::API.new token
|
22
22
|
|
@@ -30,13 +30,13 @@ describe "Koala::Facebook::API" do
|
|
30
30
|
service.api('anything')
|
31
31
|
end
|
32
32
|
|
33
|
-
it "
|
33
|
+
it "has an attr_reader for access token" do
|
34
34
|
token = 'adfadf'
|
35
35
|
service = Koala::Facebook::API.new token
|
36
36
|
service.access_token.should == token
|
37
37
|
end
|
38
38
|
|
39
|
-
it "
|
39
|
+
it "gets the attribute of a Koala::Response given by the http_component parameter" do
|
40
40
|
http_component = :method_name
|
41
41
|
|
42
42
|
response = mock('Mock KoalaResponse', :body => '', :status => 200)
|
@@ -47,7 +47,7 @@ describe "Koala::Facebook::API" do
|
|
47
47
|
@service.api('anything', {}, 'get', :http_component => http_component)
|
48
48
|
end
|
49
49
|
|
50
|
-
it "
|
50
|
+
it "returns the body of the request as JSON if no http_component is given" do
|
51
51
|
response = stub('response', :body => 'body', :status => 200)
|
52
52
|
Koala.stub(:make_request).and_return(response)
|
53
53
|
|
@@ -57,7 +57,7 @@ describe "Koala::Facebook::API" do
|
|
57
57
|
@service.api('anything').should == json_body
|
58
58
|
end
|
59
59
|
|
60
|
-
it "
|
60
|
+
it "executes an error checking block if provided" do
|
61
61
|
body = '{}'
|
62
62
|
Koala.stub(:make_request).and_return(Koala::Response.new(200, body, {}))
|
63
63
|
|
@@ -70,13 +70,13 @@ describe "Koala::Facebook::API" do
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
it "
|
73
|
+
it "raises an API error if the HTTP response code is greater than or equal to 500" do
|
74
74
|
Koala.stub(:make_request).and_return(Koala::Response.new(500, 'response body', {}))
|
75
75
|
|
76
76
|
lambda { @service.api('anything') }.should raise_exception(Koala::Facebook::APIError)
|
77
77
|
end
|
78
78
|
|
79
|
-
it "
|
79
|
+
it "handles rogue true/false as responses" do
|
80
80
|
Koala.should_receive(:make_request).and_return(Koala::Response.new(200, 'true', {}))
|
81
81
|
@service.api('anything').should be_true
|
82
82
|
|
@@ -85,13 +85,13 @@ describe "Koala::Facebook::API" do
|
|
85
85
|
end
|
86
86
|
|
87
87
|
describe "with regard to leading slashes" do
|
88
|
-
it "
|
88
|
+
it "adds a leading / to the path if not present" do
|
89
89
|
path = "anything"
|
90
90
|
Koala.should_receive(:make_request).with("/#{path}", anything, anything, anything).and_return(Koala::Response.new(200, 'true', {}))
|
91
91
|
@service.api(path)
|
92
92
|
end
|
93
93
|
|
94
|
-
it "
|
94
|
+
it "doesn't change the path if a leading / is present" do
|
95
95
|
path = "/anything"
|
96
96
|
Koala.should_receive(:make_request).with(path, anything, anything, anything).and_return(Koala::Response.new(200, 'true', {}))
|
97
97
|
@service.api(path)
|
@@ -20,6 +20,7 @@ describe "Koala::HTTPService" do
|
|
20
20
|
@builder = stub("Faraday connection builder")
|
21
21
|
@builder.stub(:request)
|
22
22
|
@builder.stub(:adapter)
|
23
|
+
@builder.stub(:use)
|
23
24
|
end
|
24
25
|
|
25
26
|
it "is defined" do
|
@@ -27,7 +28,7 @@ describe "Koala::HTTPService" do
|
|
27
28
|
end
|
28
29
|
|
29
30
|
it "adds multipart" do
|
30
|
-
@builder.should_receive(:
|
31
|
+
@builder.should_receive(:use).with(Koala::MultipartRequest)
|
31
32
|
Koala::HTTPService::DEFAULT_MIDDLEWARE.call(@builder)
|
32
33
|
end
|
33
34
|
|
@@ -63,12 +64,12 @@ describe "Koala::HTTPService" do
|
|
63
64
|
|
64
65
|
it "returns the beta REST server if options[:rest_api]" do
|
65
66
|
server = Koala::HTTPService.server(@options.merge(:rest_api => true))
|
66
|
-
server.should =~ Regexp.new(
|
67
|
+
server.should =~ Regexp.new(Koala::Facebook::REST_SERVER.gsub(/\.facebook/, ".beta.facebook"))
|
67
68
|
end
|
68
69
|
|
69
70
|
it "returns the beta rest server if !options[:rest_api]" do
|
70
71
|
server = Koala::HTTPService.server(@options)
|
71
|
-
server.should =~ Regexp.new(
|
72
|
+
server.should =~ Regexp.new(Koala::Facebook::GRAPH_SERVER.gsub(/\.facebook/, ".beta.facebook"))
|
72
73
|
end
|
73
74
|
end
|
74
75
|
|
@@ -77,12 +78,12 @@ describe "Koala::HTTPService" do
|
|
77
78
|
@options = {:video => true}
|
78
79
|
end
|
79
80
|
|
80
|
-
it "
|
81
|
+
it "returns the REST video server if options[:rest_api]" do
|
81
82
|
server = Koala::HTTPService.server(@options.merge(:rest_api => true))
|
82
83
|
server.should =~ Regexp.new(Koala::Facebook::REST_SERVER.gsub(/\.facebook/, "-video.facebook"))
|
83
84
|
end
|
84
85
|
|
85
|
-
it "
|
86
|
+
it "returns the graph video server if !options[:rest_api]" do
|
86
87
|
server = Koala::HTTPService.server(@options)
|
87
88
|
server.should =~ Regexp.new(Koala::Facebook::GRAPH_SERVER.gsub(/\.facebook/, "-video.facebook"))
|
88
89
|
end
|
@@ -90,11 +91,11 @@ describe "Koala::HTTPService" do
|
|
90
91
|
end
|
91
92
|
|
92
93
|
describe "#encode_params" do
|
93
|
-
it "
|
94
|
+
it "returns an empty string if param_hash evaluates to false" do
|
94
95
|
Koala::HTTPService.encode_params(nil).should == ''
|
95
96
|
end
|
96
97
|
|
97
|
-
it "
|
98
|
+
it "converts values to JSON if the value is not a String" do
|
98
99
|
val = 'json_value'
|
99
100
|
not_a_string = 'not_a_string'
|
100
101
|
not_a_string.stub(:is_a?).and_return(false)
|
@@ -113,7 +114,7 @@ describe "Koala::HTTPService" do
|
|
113
114
|
end.should be_true
|
114
115
|
end
|
115
116
|
|
116
|
-
it "
|
117
|
+
it "escapes all values" do
|
117
118
|
args = Hash[*(1..4).map {|i| [i.to_s, "Value #{i}($"]}.flatten]
|
118
119
|
|
119
120
|
result = Koala::HTTPService.encode_params(args)
|
@@ -123,7 +124,7 @@ describe "Koala::HTTPService" do
|
|
123
124
|
end
|
124
125
|
end
|
125
126
|
|
126
|
-
it "
|
127
|
+
it "converts all keys to Strings" do
|
127
128
|
args = Hash[*(1..4).map {|i| [i, "val#{i}"]}.flatten]
|
128
129
|
|
129
130
|
result = Koala::HTTPService.encode_params(args)
|
@@ -427,16 +428,16 @@ describe "Koala::HTTPService" do
|
|
427
428
|
:net_http => Koala::NetHTTPService
|
428
429
|
}.each_pair do |adapter, module_class|
|
429
430
|
describe module_class.to_s do
|
430
|
-
it "
|
431
|
+
it "responds to deprecated_interface" do
|
431
432
|
module_class.should respond_to(:deprecated_interface)
|
432
433
|
end
|
433
434
|
|
434
|
-
it "
|
435
|
+
it "issues a deprecation warning" do
|
435
436
|
Koala::Utils.should_receive(:deprecate)
|
436
437
|
module_class.deprecated_interface
|
437
438
|
end
|
438
439
|
|
439
|
-
it "
|
440
|
+
it "sets the default adapter to #{adapter}" do
|
440
441
|
module_class.deprecated_interface
|
441
442
|
Faraday.default_adapter.should == adapter
|
442
443
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Koala::MultipartRequest do
|
4
|
+
it "is a subclass of Faraday::Request::Multipart" do
|
5
|
+
Koala::MultipartRequest.superclass.should == Faraday::Request::Multipart
|
6
|
+
end
|
7
|
+
|
8
|
+
it "defines mime_type as multipart/form-data" do
|
9
|
+
Koala::MultipartRequest.mime_type.should == 'multipart/form-data'
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ".process_request?" do
|
13
|
+
before :each do
|
14
|
+
@env = {}
|
15
|
+
@multipart = Koala::MultipartRequest.new
|
16
|
+
@multipart.stub(:request_type).and_return("")
|
17
|
+
end
|
18
|
+
|
19
|
+
# no way to test the call to super, unfortunately
|
20
|
+
it "returns true if env[:body] is a hash with at least one hash in its values" do
|
21
|
+
@env[:body] = {:a => {:c => 2}}
|
22
|
+
@multipart.process_request?(@env).should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns true if env[:body] is a hash with at least one array in its values" do
|
26
|
+
@env[:body] = {:a => [:c, 2]}
|
27
|
+
@multipart.process_request?(@env).should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns true if env[:body] is a hash with mixed objects in its values" do
|
31
|
+
@env[:body] = {:a => [:c, 2], :b => {:e => :f}}
|
32
|
+
@multipart.process_request?(@env).should be_true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns false if env[:body] is a string" do
|
36
|
+
@env[:body] = "my body"
|
37
|
+
@multipart.process_request?(@env).should be_false
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns false if env[:body] is a hash without an array or hash value" do
|
41
|
+
@env[:body] = {:a => 3}
|
42
|
+
@multipart.process_request?(@env).should be_false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe ".process_params" do
|
47
|
+
before :each do
|
48
|
+
@parent = Faraday::Request::Multipart.new
|
49
|
+
@multipart = Koala::MultipartRequest.new
|
50
|
+
@block = lambda {|k, v| "#{k}=#{v}"}
|
51
|
+
end
|
52
|
+
|
53
|
+
it "is identical to the parent for requests without a prefix" do
|
54
|
+
hash = {:a => 2, :c => "3"}
|
55
|
+
@multipart.process_params(hash, &@block).should == @parent.process_params(hash, &@block)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "replaces encodes [ and ] if the request has a prefix" do
|
59
|
+
hash = {:a => 2, :c => "3"}
|
60
|
+
prefix = "foo"
|
61
|
+
# process_params returns an array
|
62
|
+
@multipart.process_params(hash, prefix, &@block).join("&").should == @parent.process_params(hash, prefix, &@block).join("&").gsub(/\[/, "%5B").gsub(/\]/, "%5D")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|