koala 1.2.0beta1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +12 -2
- data/koala.gemspec +7 -8
- data/lib/koala/graph_api.rb +11 -22
- data/lib/koala/graph_batch_api.rb +11 -1
- data/lib/koala/graph_collection.rb +7 -2
- data/lib/koala/http_service.rb +0 -1
- data/lib/koala/oauth.rb +32 -22
- data/lib/koala/realtime_updates.rb +1 -1
- data/lib/koala/test_users.rb +1 -2
- data/lib/koala/uploadable_io.rb +2 -1
- data/lib/koala/version.rb +3 -0
- data/lib/koala.rb +7 -2
- data/readme.md +27 -7
- data/spec/cases/{api_base_spec.rb → api_spec.rb} +25 -0
- data/spec/cases/graph_and_rest_api_spec.rb +0 -26
- data/spec/cases/graph_api_batch_spec.rb +12 -30
- data/spec/cases/graph_api_spec.rb +0 -20
- data/spec/cases/graph_collection_spec.rb +116 -0
- data/spec/cases/koala_spec.rb +7 -3
- data/spec/cases/oauth_spec.rb +130 -43
- data/spec/cases/test_users_spec.rb +11 -23
- data/spec/cases/uploadable_io_spec.rb +28 -0
- data/spec/fixtures/facebook_data.yml +3 -2
- data/spec/fixtures/mock_facebook_responses.yml +5 -5
- data/spec/support/graph_api_shared_examples.rb +23 -70
- data/spec/support/koala_test.rb +30 -6
- data/spec/support/mock_http_service.rb +2 -1
- metadata +19 -29
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Koala::Facebook::GraphCollection do
|
|
4
|
+
before(:each) do
|
|
5
|
+
@result = {
|
|
6
|
+
"data" => [1, 2, :three],
|
|
7
|
+
"paging" => {:paging => true}
|
|
8
|
+
}
|
|
9
|
+
@api = Koala::Facebook::API.new("123")
|
|
10
|
+
@collection = Koala::Facebook::GraphCollection.new(@result, @api)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "subclasses Array" do
|
|
14
|
+
Koala::Facebook::GraphCollection.ancestors.should include(Array)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "creates an array-like object" do
|
|
18
|
+
Koala::Facebook::GraphCollection.new(@result, @api).should be_an(Array)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "contains the result data" do
|
|
22
|
+
@result["data"].each_with_index {|r, i| @collection[i].should == r}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "has a read-only paging attribute" do
|
|
26
|
+
@collection.methods.map(&:to_sym).should include(:paging)
|
|
27
|
+
@collection.methods.map(&:to_sym).should_not include(:paging=)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "sets paging to results['paging']" do
|
|
31
|
+
@collection.paging.should == @result["paging"]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "sets raw_response to the original results" do
|
|
35
|
+
@collection.raw_response.should == @result
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "sets the API to the provided API" do
|
|
39
|
+
@collection.api.should == @api
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "when getting a whole page" do
|
|
43
|
+
before(:each) do
|
|
44
|
+
@second_page = {
|
|
45
|
+
"data" => [:second, :page, :data],
|
|
46
|
+
"paging" => {}
|
|
47
|
+
}
|
|
48
|
+
@base = stub("base")
|
|
49
|
+
@args = stub("args")
|
|
50
|
+
@page_of_results = stub("page of results")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "should return the previous page of results" do
|
|
54
|
+
@collection.should_receive(:previous_page_params).and_return([@base, @args])
|
|
55
|
+
@api.should_receive(:api).with(@base, @args, anything, anything).and_return(@second_page)
|
|
56
|
+
Koala::Facebook::GraphCollection.should_receive(:new).with(@second_page, @api).and_return(@page_of_results)
|
|
57
|
+
@collection.previous_page.should == @page_of_results
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should return the next page of results" do
|
|
61
|
+
@collection.should_receive(:next_page_params).and_return([@base, @args])
|
|
62
|
+
@api.should_receive(:api).with(@base, @args, anything, anything).and_return(@second_page)
|
|
63
|
+
Koala::Facebook::GraphCollection.should_receive(:new).with(@second_page, @api).and_return(@page_of_results)
|
|
64
|
+
|
|
65
|
+
@collection.next_page.should == @page_of_results
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should return nil it there are no other pages" do
|
|
69
|
+
%w{next previous}.each do |this|
|
|
70
|
+
@collection.should_receive("#{this}_page_params".to_sym).and_return(nil)
|
|
71
|
+
@collection.send("#{this}_page").should == nil
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe "when parsing page paramters" do
|
|
77
|
+
it "should return the base as the first array entry" do
|
|
78
|
+
base = "url_path"
|
|
79
|
+
@collection.parse_page_url("anything.com/#{base}?anything").first.should == base
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should return the arguments as a hash as the last array entry" do
|
|
83
|
+
args_hash = {"one" => "val_one", "two" => "val_two"}
|
|
84
|
+
@collection.parse_page_url("anything.com/anything?#{args_hash.map {|k,v| "#{k}=#{v}" }.join("&")}").last.should == args_hash
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe "#evaluate" do
|
|
89
|
+
it "returns the original result if it's provided a non-hash result" do
|
|
90
|
+
result = []
|
|
91
|
+
Koala::Facebook::GraphCollection.evaluate(result, @api).should == result
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "returns the original result if it's provided a nil result" do
|
|
95
|
+
result = nil
|
|
96
|
+
Koala::Facebook::GraphCollection.evaluate(result, @api).should == result
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "returns the original result if the result doesn't have a data key" do
|
|
100
|
+
result = {"paging" => {}}
|
|
101
|
+
Koala::Facebook::GraphCollection.evaluate(result, @api).should == result
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "returns the original result if the result's data key isn't an array" do
|
|
105
|
+
result = {"data" => {}, "paging" => {}}
|
|
106
|
+
Koala::Facebook::GraphCollection.evaluate(result, @api).should == result
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "returns a new GraphCollection of the result if it has an array data key and a paging key" do
|
|
110
|
+
result = {"data" => [], "paging" => {}}
|
|
111
|
+
expected = :foo
|
|
112
|
+
Koala::Facebook::GraphCollection.should_receive(:new).with(result, @api).and_return(expected)
|
|
113
|
+
Koala::Facebook::GraphCollection.evaluate(result, @api).should == expected
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
data/spec/cases/koala_spec.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe "Koala" do
|
|
4
|
+
it "has a version" do
|
|
5
|
+
Koala.const_defined?("VERSION").should be_true
|
|
6
|
+
end
|
|
7
|
+
|
|
4
8
|
it "has an http_service accessor" do
|
|
5
9
|
Koala.should respond_to(:http_service)
|
|
6
10
|
Koala.should respond_to(:http_service=)
|
|
@@ -35,14 +39,14 @@ describe "Koala" do
|
|
|
35
39
|
end
|
|
36
40
|
end
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
describe "make_request" do
|
|
39
43
|
it "passes all its arguments to the http_service" do
|
|
40
|
-
http_service = stub("http_service")
|
|
41
44
|
path = "foo"
|
|
42
45
|
args = {:a => 2}
|
|
43
46
|
verb = "get"
|
|
44
47
|
options = {:c => :d}
|
|
45
|
-
|
|
48
|
+
|
|
49
|
+
Koala.http_service.should_receive(:make_request).with(path, args, verb, options)
|
|
46
50
|
Koala.make_request(path, args, verb, options)
|
|
47
51
|
end
|
|
48
52
|
end
|
data/spec/cases/oauth_spec.rb
CHANGED
|
@@ -53,40 +53,107 @@ describe "Koala::Facebook::OAuth" do
|
|
|
53
53
|
|
|
54
54
|
describe "for cookie parsing" do
|
|
55
55
|
describe "get_user_info_from_cookies" do
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
context "for signed cookies" do
|
|
57
|
+
before :each do
|
|
58
|
+
# we don't actually want to make requests to Facebook to redeem the code
|
|
59
|
+
@cookie = KoalaTest.oauth_test_data["valid_signed_cookies"]
|
|
60
|
+
@token = "my token"
|
|
61
|
+
@oauth.stub(:get_access_token_info).and_return("access_token" => @token)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "parses valid cookies" do
|
|
65
|
+
result = @oauth.get_user_info_from_cookies(@cookie)
|
|
66
|
+
result.should be_a(Hash)
|
|
67
|
+
end
|
|
60
68
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
it "returns all the components in the signed request" do
|
|
70
|
+
result = @oauth.get_user_info_from_cookies(@cookie)
|
|
71
|
+
@oauth.parse_signed_request(@cookie.values.first).each_pair do |k, v|
|
|
72
|
+
result[k].should == v
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "makes a request to Facebook to redeem the code if present" do
|
|
77
|
+
code = "foo"
|
|
78
|
+
@oauth.stub(:parse_signed_request).and_return({"code" => code})
|
|
79
|
+
@oauth.should_receive(:get_access_token_info).with(code, anything)
|
|
80
|
+
@oauth.get_user_info_from_cookies(@cookie)
|
|
81
|
+
end
|
|
67
82
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
83
|
+
it "sets the code redemption redirect_uri to ''" do
|
|
84
|
+
@oauth.should_receive(:get_access_token_info).with(anything, :redirect_uri => '')
|
|
85
|
+
@oauth.get_user_info_from_cookies(@cookie)
|
|
86
|
+
end
|
|
72
87
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
88
|
+
context "if the code is missing" do
|
|
89
|
+
it "doesn't make a request to Facebook" do
|
|
90
|
+
@oauth.stub(:parse_signed_request).and_return({})
|
|
91
|
+
@oauth.should_receive(:get_access_token_info).never
|
|
92
|
+
@oauth.get_user_info_from_cookies(@cookie)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "returns nil" do
|
|
96
|
+
@oauth.stub(:parse_signed_request).and_return({})
|
|
97
|
+
@oauth.get_user_info_from_cookies(@cookie).should be_nil
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context "if the code is present" do
|
|
102
|
+
it "adds the access_token into the hash" do
|
|
103
|
+
@oauth.get_user_info_from_cookies(@cookie)["access_token"].should == @token
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "returns nil if the call to FB fails" do
|
|
107
|
+
@oauth.stub(:get_access_token_info).and_return(nil)
|
|
108
|
+
@oauth.get_user_info_from_cookies(@cookie).should be_nil
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "shouldn't parse invalid cookies" do
|
|
113
|
+
# make an invalid string by replacing some values
|
|
114
|
+
bad_cookie_hash = @cookie.inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
|
|
115
|
+
result = @oauth.get_user_info_from_cookies(bad_cookie_hash)
|
|
116
|
+
result.should be_nil
|
|
117
|
+
end
|
|
78
118
|
end
|
|
119
|
+
|
|
120
|
+
context "for unsigned cookies" do
|
|
121
|
+
it "should properly parse valid cookies" do
|
|
122
|
+
result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["valid_cookies"])
|
|
123
|
+
result.should be_a(Hash)
|
|
124
|
+
end
|
|
79
125
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
126
|
+
it "should return all the cookie components from valid cookie string" do
|
|
127
|
+
cookie_data = KoalaTest.oauth_test_data["valid_cookies"]
|
|
128
|
+
parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
|
|
129
|
+
number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
|
|
130
|
+
parsing_results.length.should == number_of_components
|
|
131
|
+
end
|
|
84
132
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
133
|
+
it "should properly parse valid offline access cookies (e.g. no expiration)" do
|
|
134
|
+
result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["offline_access_cookies"])
|
|
135
|
+
result["uid"].should
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "should return all the cookie components from offline access cookies" do
|
|
139
|
+
cookie_data = KoalaTest.oauth_test_data["offline_access_cookies"]
|
|
140
|
+
parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
|
|
141
|
+
number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
|
|
142
|
+
parsing_results.length.should == number_of_components
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "shouldn't parse expired cookies" do
|
|
146
|
+
new_time = @time.to_i * 2
|
|
147
|
+
@time.stub(:to_i).and_return(new_time)
|
|
148
|
+
@oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["valid_cookies"]).should be_nil
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "shouldn't parse invalid cookies" do
|
|
152
|
+
# make an invalid string by replacing some values
|
|
153
|
+
bad_cookie_hash = KoalaTest.oauth_test_data["valid_cookies"].inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
|
|
154
|
+
result = @oauth.get_user_info_from_cookies(bad_cookie_hash)
|
|
155
|
+
result.should be_nil
|
|
156
|
+
end
|
|
90
157
|
end
|
|
91
158
|
end
|
|
92
159
|
|
|
@@ -179,8 +246,24 @@ describe "Koala::Facebook::OAuth" do
|
|
|
179
246
|
end
|
|
180
247
|
|
|
181
248
|
describe "for fetching access tokens" do
|
|
182
|
-
|
|
183
|
-
|
|
249
|
+
describe ".get_access_token_info" do
|
|
250
|
+
it "uses options[:redirect_uri] if provided" do
|
|
251
|
+
uri = "foo"
|
|
252
|
+
Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => uri), anything, anything).and_return(Koala::Response.new(200, "", {}))
|
|
253
|
+
@oauth.get_access_token_info(@code, :redirect_uri => uri)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it "uses the redirect_uri used to create the @oauth if no :redirect_uri option is provided" do
|
|
257
|
+
Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => @callback_url), anything, anything).and_return(Koala::Response.new(200, "", {}))
|
|
258
|
+
@oauth.get_access_token_info(@code)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it "makes a GET request" do
|
|
262
|
+
Koala.should_receive(:make_request).with(anything, anything, "get", anything).and_return(Koala::Response.new(200, "", {}))
|
|
263
|
+
@oauth.get_access_token_info(@code)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
if KoalaTest.code
|
|
184
267
|
it "should properly get and parse an access token token results into a hash" do
|
|
185
268
|
result = @oauth.get_access_token_info(@code)
|
|
186
269
|
result.should be_a(Hash)
|
|
@@ -190,36 +273,40 @@ describe "Koala::Facebook::OAuth" do
|
|
|
190
273
|
result = @oauth.get_access_token_info(@code)
|
|
191
274
|
result["access_token"].should
|
|
192
275
|
end
|
|
193
|
-
|
|
194
276
|
it "should raise an error when get_access_token is called with a bad code" do
|
|
195
277
|
lambda { @oauth.get_access_token_info("foo") }.should raise_error(Koala::Facebook::APIError)
|
|
196
278
|
end
|
|
197
279
|
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
describe ".get_access_token" do
|
|
283
|
+
# TODO refactor these to be proper tests with stubs and tests against real data
|
|
284
|
+
it "should pass on any options provided to make_request" do
|
|
285
|
+
options = {:a => 2}
|
|
286
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
|
|
287
|
+
@oauth.get_access_token(@code, options)
|
|
288
|
+
end
|
|
198
289
|
|
|
199
|
-
|
|
200
|
-
it "
|
|
290
|
+
if KoalaTest.code
|
|
291
|
+
it "uses get_access_token_info to get and parse an access token token results" do
|
|
201
292
|
result = @oauth.get_access_token(@code)
|
|
202
293
|
result.should be_a(String)
|
|
203
294
|
end
|
|
204
295
|
|
|
205
|
-
it "
|
|
296
|
+
it "returns the access token as a string" do
|
|
206
297
|
result = @oauth.get_access_token(@code)
|
|
207
298
|
original = @oauth.get_access_token_info(@code)
|
|
208
299
|
result.should == original["access_token"]
|
|
209
300
|
end
|
|
210
301
|
|
|
211
|
-
it "
|
|
302
|
+
it "raises an error when get_access_token is called with a bad code" do
|
|
212
303
|
lambda { @oauth.get_access_token("foo") }.should raise_error(Koala::Facebook::APIError)
|
|
213
304
|
end
|
|
214
|
-
|
|
215
|
-
it "should pass on any options provided to make_request" do
|
|
216
|
-
options = {:a => 2}
|
|
217
|
-
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
|
|
218
|
-
@oauth.get_access_token(@code, options)
|
|
219
|
-
end
|
|
220
305
|
end
|
|
221
|
-
|
|
222
|
-
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
unless KoalaTest.code
|
|
309
|
+
it "Some OAuth code tests will not be run since the code field in facebook_data.yml is blank."
|
|
223
310
|
end
|
|
224
311
|
|
|
225
312
|
describe "get_app_access_token_info" do
|
|
@@ -13,6 +13,13 @@ describe "Koala::Facebook::TestUsers" do
|
|
|
13
13
|
raise Exception, "Must supply OAuth app id, secret, app_access_token, and callback to run live subscription tests!"
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
after :each do
|
|
18
|
+
# clean up any test users
|
|
19
|
+
((@network || []) + [@user1, @user2]).each do |u|
|
|
20
|
+
puts "Unable to delete test user #{u.inspect}" if u && (!@test_users.delete(u) rescue false)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
16
23
|
|
|
17
24
|
describe "when initializing" do
|
|
18
25
|
# basic initialization
|
|
@@ -131,11 +138,6 @@ describe "Koala::Facebook::TestUsers" do
|
|
|
131
138
|
@user2 = @test_users.create(true, "read_stream,user_interests")
|
|
132
139
|
end
|
|
133
140
|
|
|
134
|
-
after :each do
|
|
135
|
-
@test_users.delete(@user1) if @user1
|
|
136
|
-
@test_users.delete(@user2) if @user2
|
|
137
|
-
end
|
|
138
|
-
|
|
139
141
|
it "should delete a user by id" do
|
|
140
142
|
@test_users.delete(@user1['id']).should be_true
|
|
141
143
|
@user1 = nil
|
|
@@ -191,11 +193,6 @@ describe "Koala::Facebook::TestUsers" do
|
|
|
191
193
|
@user2 = @test_users.create(true, "read_stream,user_interests")
|
|
192
194
|
end
|
|
193
195
|
|
|
194
|
-
after :each do
|
|
195
|
-
@test_users.delete(@user1)
|
|
196
|
-
@test_users.delete(@user2)
|
|
197
|
-
end
|
|
198
|
-
|
|
199
196
|
it "should list test users" do
|
|
200
197
|
result = @test_users.list
|
|
201
198
|
result.should be_an(Array)
|
|
@@ -243,16 +240,6 @@ describe "Koala::Facebook::TestUsers" do
|
|
|
243
240
|
end
|
|
244
241
|
|
|
245
242
|
describe "tests that create users" do
|
|
246
|
-
before :each do
|
|
247
|
-
test_users = Koala::Facebook::TestUsers.new({:app_access_token => @app_access_token, :app_id => @app_id})
|
|
248
|
-
test_users.delete_all
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
after :each do
|
|
252
|
-
test_users = Koala::Facebook::TestUsers.new({:app_access_token => @app_access_token, :app_id => @app_id})
|
|
253
|
-
test_users.delete_all
|
|
254
|
-
end
|
|
255
|
-
|
|
256
243
|
it "should create a 5 person network" do
|
|
257
244
|
size = 5
|
|
258
245
|
@network = @test_users.create_network(size)
|
|
@@ -261,10 +248,11 @@ describe "Koala::Facebook::TestUsers" do
|
|
|
261
248
|
end
|
|
262
249
|
end
|
|
263
250
|
|
|
264
|
-
it "
|
|
265
|
-
|
|
251
|
+
it "has no built-in network size limit" do
|
|
252
|
+
times = 100
|
|
253
|
+
@test_users.should_receive(:create).exactly(times).times
|
|
266
254
|
@test_users.stub!(:befriend)
|
|
267
|
-
@network = @test_users.create_network(
|
|
255
|
+
@network = @test_users.create_network(times)
|
|
268
256
|
end
|
|
269
257
|
|
|
270
258
|
it "should pass on the installed and permissions parameters to create" do
|
|
@@ -86,6 +86,34 @@ describe "Koala::UploadableIO" do
|
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
+
describe "when given an IO object" do
|
|
90
|
+
before(:each) do
|
|
91
|
+
@io = StringIO.open("abcdefgh")
|
|
92
|
+
@koala_io_params = [@io]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe "and a content type" do
|
|
96
|
+
before :each do
|
|
97
|
+
@koala_io_params.concat(["image/jpg"])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "returns an UploadableIO with the same io" do
|
|
101
|
+
Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == @koala_io_params[0]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "returns an UploadableIO with the same content_type" do
|
|
105
|
+
content_stub = @koala_io_params[1] = stub('Content Type')
|
|
106
|
+
Koala::UploadableIO.new(*@koala_io_params).content_type.should == content_stub
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe "and no content type" do
|
|
111
|
+
it "raises an exception" do
|
|
112
|
+
lambda { Koala::UploadableIO.new(*@koala_io_params) }.should raise_exception(Koala::KoalaError)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
89
117
|
describe "when given a Rails 3 ActionDispatch::Http::UploadedFile" do
|
|
90
118
|
before(:each) do
|
|
91
119
|
@tempfile, @uploaded_file = rails_3_mocks
|
|
@@ -30,11 +30,12 @@ oauth_test_data:
|
|
|
30
30
|
# note: the tests stub the time class so these default cookies are always valid (if you're using the default app)
|
|
31
31
|
# if not you may want to remove the stubbing to test expiration
|
|
32
32
|
fbs_119908831367602: '"access_token=119908831367602|2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623|CMpi0AYbn03Oukzv94AUha2qbO4.&expires=1273363200&secret=lT_9zm5r5IbJ6Aa5O54nFw__&session_key=2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623&sig=9515e93113921f9476a4efbdd4a3c746&uid=2905623"'
|
|
33
|
-
expired_cookies:
|
|
34
|
-
fbs_119908831367602: '"access_token=119908831367602|2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623|yVt5WH_S6J5p3gFa5_5lBzckhws.&expires=1273287600&secret=V_E79ovQnXqxGctFuC_n5A__&session_key=2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623&sig=eeef60838c0c800258d89b7e6ddddddb&uid=2905623"'
|
|
35
33
|
offline_access_cookies:
|
|
36
34
|
# note: I've revoked the offline access for security reasons, so you can't make calls against this :)
|
|
37
35
|
fbs_119908831367602: '"access_token=119908831367602|08170230801eb225068e7a70-2905623|Q3LDCYYF8CX9cstxnZLsxiR0nwg.&expires=0&secret=78abaee300b392e275072a9f2727d436&session_key=08170230801eb225068e7a70-2905623&sig=423b8aa4b6fa1f9a571955f8e929d567&uid=2905623"'
|
|
36
|
+
valid_signed_cookies:
|
|
37
|
+
"fbsr_119908831367602": "f1--LHwjHVCxfs97hRHL-4cF-0jNxZRc6MGzo1qHLb0.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiIyLkFRQm90a0pBWlhVY1l3RkMuMzYwMC4xMzE0ODEzNjAwLjEtMjkwNTYyM3x4V2xya0d0UmJIZlpIclRnVWwxQmxJcVhRbjQiLCJpc3N1ZWRfYXQiOjEzMTQ4MDY2NTUsInVzZXJfaWQiOiIyOTA1NjIzIn0"
|
|
38
|
+
|
|
38
39
|
|
|
39
40
|
# These values from the OAuth Playground (see above) will work out of the box
|
|
40
41
|
# You can update this to live data if desired
|
|
@@ -87,10 +87,10 @@ graph_api:
|
|
|
87
87
|
with_token: '[{"headers":[{"name":"Location","value":"http://google.com"}]}]'
|
|
88
88
|
batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me"},{"method" => "get", "relative_url" => "me/friends"}]) %>:
|
|
89
89
|
post:
|
|
90
|
-
with_token: '[{"body":"{\"id\":\"123\"}"}, {"body":"{\"data\":[]}"}]'
|
|
90
|
+
with_token: '[{"body":"{\"id\":\"123\"}"}, {"body":"{\"data\":[],\"paging\":{}}"}]'
|
|
91
91
|
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"me"}, {"method"=>"get", "relative_url"=>"#{OAUTH_DATA["app_id"]}/insights?access_token=#{CGI.escape APP_ACCESS_TOKEN}"}]) %>:
|
|
92
92
|
post:
|
|
93
|
-
with_token: '[{"body":"{\"id\":\"123\"}"}, {"body":"{\"data\":[]}"}]'
|
|
93
|
+
with_token: '[{"body":"{\"id\":\"123\"}"}, {"body":"{\"data\":[],\"paging\":{}}"}]'
|
|
94
94
|
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"#{OAUTH_DATA["app_id"]}/insights"}, {"method"=>"get", "relative_url"=>"koppel?access_token=#{CGI.escape APP_ACCESS_TOKEN}"}]) %>:
|
|
95
95
|
post:
|
|
96
96
|
with_token: '[{"body": "{\"error\":{\"type\":\"AnError\", \"message\":\"An error occurred!.\"}}"},{"body":"{\"id\":\"123\"}"}]'
|
|
@@ -113,7 +113,7 @@ graph_api:
|
|
|
113
113
|
with_token: '[null,{"body":"{}"}]'
|
|
114
114
|
batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me/friends?limit=5", "name" => "get-friends", "omit_response_on_success" => false}, {"method" => "get", "relative_url" => "?ids=#{CGI.escape "{result=get-friends:$.data.*.id}"}"}]) %>:
|
|
115
115
|
post:
|
|
116
|
-
with_token: '[{"body":"{\"data\":[]}"},{"body":"{}"}]'
|
|
116
|
+
with_token: '[{"body":"{\"data\":[],\"paging\":{}}"},{"body":"{}"}]'
|
|
117
117
|
batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me/friends?limit=5"}, {"method" => "get", "relative_url" => "?ids=#{CGI.escape "{result=i-dont-exist:$.data.*.id}"}"}]) %>:
|
|
118
118
|
post:
|
|
119
119
|
with_token: '{"error":190,"error_description":"Error validating access token."}'
|
|
@@ -211,7 +211,7 @@ graph_api:
|
|
|
211
211
|
no_args:
|
|
212
212
|
get:
|
|
213
213
|
<<: *token_required
|
|
214
|
-
with_token: '{"data": [{}]}'
|
|
214
|
+
with_token: '{"data": [{}], "paging": {}}'
|
|
215
215
|
|
|
216
216
|
/lukeshepard/picture:
|
|
217
217
|
type=large:
|
|
@@ -261,7 +261,7 @@ graph_api:
|
|
|
261
261
|
get:
|
|
262
262
|
with_token: '{"data": [{"id": "507731521_100412693339488"}], "paging": {"previous": "https:\/\/graph.facebook.com\/7204941866\/photos?limit=25&until=2008-09-15T18%3A30%3A25%2B0000", "next": "https:\/\/graph.facebook.com\/7204941866\/photos?limit=25&until=2008-09-15T18%3A30%3A25%2B0000"}}'
|
|
263
263
|
no_token: '{"data": [{"id": "507731521_100412693339488"}], "paging": {"previous": "https:\/\/graph.facebook.com\/7204941866\/photos?limit=25&until=2008-09-15T18%3A30%3A25%2B0000", "next": "https:\/\/graph.facebook.com\/7204941866\/photos?limit=25&until=2008-09-15T18%3A30%3A25%2B0000"}}'
|
|
264
|
-
"limit=25&q=facebook&until
|
|
264
|
+
"limit=25&q=facebook&until=<%= TEST_DATA['search_time'] %>":
|
|
265
265
|
get:
|
|
266
266
|
with_token: '{"data": [{"id": "507731521_100412693339488"}], "paging": {"previous": "https:\/\/graph.facebook.com\/7204941866\/photos?limit=25&until=2008-09-15T18%3A30%3A25%2B0000", "next": "https:\/\/graph.facebook.com\/7204941866\/photos?limit=25&until=2008-09-15T18%3A30%3A25%2B0000"}}'
|
|
267
267
|
no_token: '{"data": [{"id": "507731521_100412693339488"}], "paging": {"previous": "https:\/\/graph.facebook.com\/7204941866\/photos?limit=25&until=2008-09-15T18%3A30%3A25%2B0000", "next": "https:\/\/graph.facebook.com\/7204941866\/photos?limit=25&until=2008-09-15T18%3A30%3A25%2B0000"}}'
|
|
@@ -17,9 +17,7 @@ shared_examples_for "Koala GraphAPI" do
|
|
|
17
17
|
describe "graph_call" do
|
|
18
18
|
it "should pass all arguments to the api method" do
|
|
19
19
|
args = [KoalaTest.user1, {}, "get", {:a => :b}]
|
|
20
|
-
|
|
21
20
|
@api.should_receive(:api).with(*args)
|
|
22
|
-
|
|
23
21
|
@api.graph_call(*args)
|
|
24
22
|
end
|
|
25
23
|
|
|
@@ -27,6 +25,27 @@ shared_examples_for "Koala GraphAPI" do
|
|
|
27
25
|
Koala.stub(:make_request).and_return(Koala::Response.new(500, {"error" => "An error occurred!"}, {}))
|
|
28
26
|
lambda { @api.graph_call(KoalaTest.user1, {}) }.should raise_exception(Koala::Facebook::APIError)
|
|
29
27
|
end
|
|
28
|
+
|
|
29
|
+
it "passes the results through GraphCollection.evaluate" do
|
|
30
|
+
result = {}
|
|
31
|
+
@api.stub(:api).and_return(result)
|
|
32
|
+
Koala::Facebook::GraphCollection.should_receive(:evaluate).with(result, @api)
|
|
33
|
+
@api.graph_call("/me")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "returns the results of GraphCollection.evaluate" do
|
|
37
|
+
expected = {}
|
|
38
|
+
@api.stub(:api).and_return([])
|
|
39
|
+
Koala::Facebook::GraphCollection.should_receive(:evaluate).and_return(expected)
|
|
40
|
+
@api.graph_call("/me").should == expected
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "returns the post_processing block's results if one is supplied" do
|
|
44
|
+
other_result = [:a, 2, :three]
|
|
45
|
+
block = Proc.new {|r| other_result}
|
|
46
|
+
@api.stub(:api).and_return({})
|
|
47
|
+
@api.graph_call("/me", {}, "get", {}, &block).should == other_result
|
|
48
|
+
end
|
|
30
49
|
end
|
|
31
50
|
|
|
32
51
|
# SEARCH
|
|
@@ -349,12 +368,6 @@ end
|
|
|
349
368
|
|
|
350
369
|
# GraphCollection
|
|
351
370
|
shared_examples_for "Koala GraphAPI with GraphCollection" do
|
|
352
|
-
|
|
353
|
-
it "should create an array-like object" do
|
|
354
|
-
call = @api.graph_call("contextoptional/photos")
|
|
355
|
-
Koala::Facebook::GraphCollection.new(call, @api).should be_an(Array)
|
|
356
|
-
end
|
|
357
|
-
|
|
358
371
|
describe "when getting a collection" do
|
|
359
372
|
# GraphCollection methods
|
|
360
373
|
it "should get a GraphCollection when getting connections" do
|
|
@@ -380,74 +393,14 @@ shared_examples_for "Koala GraphAPI with GraphCollection" do
|
|
|
380
393
|
end
|
|
381
394
|
|
|
382
395
|
it "should get a GraphCollection when paging through results" do
|
|
383
|
-
@results = @api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=>
|
|
396
|
+
@results = @api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=> KoalaTest.search_time}])
|
|
384
397
|
@results.should be_a(Koala::Facebook::GraphCollection)
|
|
385
398
|
end
|
|
386
399
|
|
|
387
400
|
it "should return nil if the page call fails with nil" do
|
|
388
401
|
# this happens sometimes
|
|
389
402
|
@api.should_receive(:graph_call).and_return(nil)
|
|
390
|
-
@api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=>
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
# GraphCollection attributes
|
|
394
|
-
describe "the GraphCollection" do
|
|
395
|
-
before(:each) do
|
|
396
|
-
@result = @api.get_connections(KoalaTest.page, "photos")
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
it "should have a read-only paging attribute" do
|
|
400
|
-
@result.methods.map(&:to_sym).should include(:paging)
|
|
401
|
-
@result.methods.map(&:to_sym).should_not include(:paging=)
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
describe "when getting a whole page" do
|
|
405
|
-
before(:each) do
|
|
406
|
-
@second_page = stub("page of Fb graph results")
|
|
407
|
-
@base = stub("base")
|
|
408
|
-
@args = stub("args")
|
|
409
|
-
@page_of_results = stub("page of results")
|
|
410
|
-
end
|
|
411
|
-
|
|
412
|
-
it "should return the previous page of results" do
|
|
413
|
-
@result.should_receive(:previous_page_params).and_return([@base, @args])
|
|
414
|
-
@api.should_receive(:graph_call).with(@base, @args).and_yield(@second_page)
|
|
415
|
-
Koala::Facebook::GraphCollection.should_receive(:new).with(@second_page, @api).and_return(@page_of_results)
|
|
416
|
-
|
|
417
|
-
@result.previous_page#.should == @page_of_results
|
|
418
|
-
end
|
|
419
|
-
|
|
420
|
-
it "should return the next page of results" do
|
|
421
|
-
@result.should_receive(:next_page_params).and_return([@base, @args])
|
|
422
|
-
@api.should_receive(:graph_call).with(@base, @args).and_yield(@second_page)
|
|
423
|
-
Koala::Facebook::GraphCollection.should_receive(:new).with(@second_page, @api).and_return(@page_of_results)
|
|
424
|
-
|
|
425
|
-
@result.next_page#.should == @page_of_results
|
|
426
|
-
end
|
|
427
|
-
|
|
428
|
-
it "should return nil it there are no other pages" do
|
|
429
|
-
%w{next previous}.each do |this|
|
|
430
|
-
@result.should_receive("#{this}_page_params".to_sym).and_return(nil)
|
|
431
|
-
@result.send("#{this}_page").should == nil
|
|
432
|
-
end
|
|
433
|
-
end
|
|
434
|
-
end
|
|
435
|
-
|
|
436
|
-
describe "when parsing page paramters" do
|
|
437
|
-
before(:each) do
|
|
438
|
-
@graph_collection = Koala::Facebook::GraphCollection.new({"data" => []}, Koala::Facebook::API.new)
|
|
439
|
-
end
|
|
440
|
-
|
|
441
|
-
it "should return the base as the first array entry" do
|
|
442
|
-
base = "url_path"
|
|
443
|
-
@graph_collection.parse_page_url("anything.com/#{base}?anything").first.should == base
|
|
444
|
-
end
|
|
445
|
-
|
|
446
|
-
it "should return the arguments as a hash as the last array entry" do
|
|
447
|
-
args_hash = {"one" => "val_one", "two" => "val_two"}
|
|
448
|
-
@graph_collection.parse_page_url("anything.com/anything?#{args_hash.map {|k,v| "#{k}=#{v}" }.join("&")}").last.should == args_hash
|
|
449
|
-
end
|
|
450
|
-
end
|
|
403
|
+
@api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=> KoalaTest.search_time}]).should be_nil
|
|
451
404
|
end
|
|
452
405
|
end
|
|
453
406
|
end
|