tyler_koala 1.2.0beta
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +12 -0
- data/.gitignore +5 -0
- data/.travis.yml +9 -0
- data/CHANGELOG +185 -0
- data/Gemfile +11 -0
- data/LICENSE +22 -0
- data/Manifest +39 -0
- data/Rakefile +16 -0
- data/autotest/discover.rb +1 -0
- data/koala.gemspec +50 -0
- data/lib/koala.rb +119 -0
- data/lib/koala/batch_operation.rb +74 -0
- data/lib/koala/graph_api.rb +281 -0
- data/lib/koala/graph_batch_api.rb +87 -0
- data/lib/koala/graph_collection.rb +54 -0
- data/lib/koala/http_service.rb +161 -0
- data/lib/koala/oauth.rb +181 -0
- data/lib/koala/realtime_updates.rb +89 -0
- data/lib/koala/rest_api.rb +95 -0
- data/lib/koala/test_users.rb +102 -0
- data/lib/koala/uploadable_io.rb +180 -0
- data/lib/koala/utils.rb +7 -0
- data/readme.md +160 -0
- data/spec/cases/api_base_spec.rb +101 -0
- data/spec/cases/error_spec.rb +30 -0
- data/spec/cases/graph_and_rest_api_spec.rb +48 -0
- data/spec/cases/graph_api_batch_spec.rb +600 -0
- data/spec/cases/graph_api_spec.rb +42 -0
- data/spec/cases/http_service_spec.rb +420 -0
- data/spec/cases/koala_spec.rb +21 -0
- data/spec/cases/oauth_spec.rb +428 -0
- data/spec/cases/realtime_updates_spec.rb +198 -0
- data/spec/cases/rest_api_spec.rb +41 -0
- data/spec/cases/test_users_spec.rb +281 -0
- data/spec/cases/uploadable_io_spec.rb +206 -0
- data/spec/cases/utils_spec.rb +8 -0
- data/spec/fixtures/beach.jpg +0 -0
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/facebook_data.yml +61 -0
- data/spec/fixtures/mock_facebook_responses.yml +439 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/support/graph_api_shared_examples.rb +502 -0
- data/spec/support/json_testing_fix.rb +42 -0
- data/spec/support/koala_test.rb +163 -0
- data/spec/support/mock_http_service.rb +98 -0
- data/spec/support/ordered_hash.rb +205 -0
- data/spec/support/rest_api_shared_examples.rb +285 -0
- data/spec/support/uploadable_io_shared_examples.rb +70 -0
- metadata +221 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'Although not required, bundler is recommended for running the tests.'
|
5
|
+
end
|
6
|
+
|
7
|
+
# In Ruby 1.9.2 versions before patchlevel 290, the default Psych
|
8
|
+
# parser has an issue with YAML merge keys, which
|
9
|
+
# fixtures/mock_facebook_responses.yml relies heavily on.
|
10
|
+
#
|
11
|
+
# Anyone using an earlier version will see missing mock response
|
12
|
+
# errors when running the test suite similar to this:
|
13
|
+
#
|
14
|
+
# RuntimeError:
|
15
|
+
# Missing a mock response for graph_api: /me/videos: source=[FILE]: post: with_token
|
16
|
+
# API PATH: /me/videos?source=[FILE]&format=json&access_token=*
|
17
|
+
#
|
18
|
+
# For now, it seems the best fix is to just downgrade to the old syck YAML parser
|
19
|
+
# for these troubled versions.
|
20
|
+
#
|
21
|
+
# See https://github.com/tenderlove/psych/issues/8 for more details
|
22
|
+
YAML::ENGINE.yamler = 'syck' if RUBY_VERSION == '1.9.2' && RUBY_PATCHLEVEL < 290
|
23
|
+
|
24
|
+
# load the library
|
25
|
+
require 'koala'
|
26
|
+
|
27
|
+
# ensure consistent to_json behavior
|
28
|
+
# this must be required first so mock_http_service loads the YAML as expected
|
29
|
+
require 'support/ordered_hash'
|
30
|
+
require 'support/json_testing_fix'
|
31
|
+
|
32
|
+
# set up our testing environment
|
33
|
+
require 'support/mock_http_service'
|
34
|
+
require 'support/koala_test'
|
35
|
+
# load testing data and (if needed) create test users or validate real users
|
36
|
+
KoalaTest.setup_test_environment!
|
37
|
+
|
38
|
+
# load supporting files for our tests
|
39
|
+
require 'support/rest_api_shared_examples'
|
40
|
+
require 'support/graph_api_shared_examples'
|
41
|
+
require 'support/uploadable_io_shared_examples'
|
42
|
+
|
43
|
+
BEACH_BALL_PATH = File.join(File.dirname(__FILE__), "fixtures", "beach.jpg")
|
@@ -0,0 +1,502 @@
|
|
1
|
+
shared_examples_for "Koala GraphAPI" do
|
2
|
+
# all Graph API instances should pass these tests, regardless of configuration
|
3
|
+
|
4
|
+
# API
|
5
|
+
it "should never use the rest api server" do
|
6
|
+
Koala.should_receive(:make_request).with(
|
7
|
+
anything,
|
8
|
+
anything,
|
9
|
+
anything,
|
10
|
+
hash_not_including(:rest_api => true)
|
11
|
+
).and_return(Koala::Response.new(200, "", {}))
|
12
|
+
|
13
|
+
@api.api("anything")
|
14
|
+
end
|
15
|
+
|
16
|
+
# GRAPH CALL
|
17
|
+
describe "graph_call" do
|
18
|
+
it "should pass all arguments to the api method" do
|
19
|
+
args = [KoalaTest.user1, {}, "get", {:a => :b}]
|
20
|
+
|
21
|
+
@api.should_receive(:api).with(*args)
|
22
|
+
|
23
|
+
@api.graph_call(*args)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should throw an APIError if the result hash has an error key" do
|
27
|
+
Koala.stub(:make_request).and_return(Koala::Response.new(500, {"error" => "An error occurred!"}, {}))
|
28
|
+
lambda { @api.graph_call(KoalaTest.user1, {}) }.should raise_exception(Koala::Facebook::APIError)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# SEARCH
|
33
|
+
it "should be able to search" do
|
34
|
+
result = @api.search("facebook")
|
35
|
+
result.length.should be_an(Integer)
|
36
|
+
end
|
37
|
+
|
38
|
+
# DATA
|
39
|
+
# access public info
|
40
|
+
|
41
|
+
# get_object
|
42
|
+
it "should get public data about a user" do
|
43
|
+
result = @api.get_object(KoalaTest.user1)
|
44
|
+
# the results should have an ID and a name, among other things
|
45
|
+
(result["id"] && result["name"]).should_not be_nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should get public data about a Page" do
|
49
|
+
result = @api.get_object(KoalaTest.page)
|
50
|
+
# the results should have an ID and a name, among other things
|
51
|
+
(result["id"] && result["name"]).should
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return [] from get_objects if passed an empty array" do
|
55
|
+
results = @api.get_objects([])
|
56
|
+
results.should == []
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should be able to get multiple objects" do
|
60
|
+
results = @api.get_objects([KoalaTest.page, KoalaTest.user1])
|
61
|
+
results.should have(2).items
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be able to get multiple objects if they're a string" do
|
65
|
+
results = @api.get_objects("contextoptional,#{KoalaTest.user1}")
|
66
|
+
results.should have(2).items
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should be able to access a user's picture" do
|
70
|
+
@api.get_picture("chris.baclig").should =~ /http[s]*\:\/\//
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should be able to access a user's picture, given a picture type" do
|
74
|
+
@api.get_picture(KoalaTest.user2, {:type => 'large'}).should =~ /^http[s]*\:\/\//
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should be able to access connections from public Pages" do
|
78
|
+
result = @api.get_connections(KoalaTest.page, "photos")
|
79
|
+
result.should be_a(Array)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should be able to access comments for a URL" do
|
83
|
+
result = @api.get_comments_for_urls(["http://developers.facebook.com/blog/post/472"])
|
84
|
+
(result["http://developers.facebook.com/blog/post/472"]).should
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should be able to access comments for 2 URLs" do
|
88
|
+
result = @api.get_comments_for_urls(["http://developers.facebook.com/blog/post/490", "http://developers.facebook.com/blog/post/472"])
|
89
|
+
(result["http://developers.facebook.com/blog/post/490"] && result["http://developers.facebook.com/blog/post/472"]).should
|
90
|
+
end
|
91
|
+
|
92
|
+
# SEARCH
|
93
|
+
it "should be able to search" do
|
94
|
+
result = @api.search("facebook")
|
95
|
+
result.length.should be_an(Integer)
|
96
|
+
end
|
97
|
+
|
98
|
+
# PAGING THROUGH COLLECTIONS
|
99
|
+
# see also graph_collection_tests
|
100
|
+
it "should make a request for a page when provided a specific set of page params" do
|
101
|
+
query = [1, 2]
|
102
|
+
@api.should_receive(:graph_call).with(*query)
|
103
|
+
@api.get_page(query)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
shared_examples_for "Koala GraphAPI with an access token" do
|
109
|
+
it "should get private data about a user" do
|
110
|
+
result = @api.get_object(KoalaTest.user1)
|
111
|
+
# updated_time should be a pretty fixed test case
|
112
|
+
result["updated_time"].should_not be_nil
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should get data about 'me'" do
|
116
|
+
result = @api.get_object("me")
|
117
|
+
result["updated_time"].should
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be able to get multiple objects" do
|
121
|
+
result = @api.get_objects([KoalaTest.page, KoalaTest.user1])
|
122
|
+
result.length.should == 2
|
123
|
+
end
|
124
|
+
it "should be able to access connections from users" do
|
125
|
+
result = @api.get_connections(KoalaTest.user2, "friends")
|
126
|
+
result.length.should > 0
|
127
|
+
end
|
128
|
+
|
129
|
+
# PUT
|
130
|
+
it "should be able to write an object to the graph" do
|
131
|
+
result = @api.put_wall_post("Hello, world, from the test suite!")
|
132
|
+
@temporary_object_id = result["id"]
|
133
|
+
@temporary_object_id.should_not be_nil
|
134
|
+
end
|
135
|
+
|
136
|
+
# DELETE
|
137
|
+
it "should be able to delete posts" do
|
138
|
+
result = @api.put_wall_post("Hello, world, from the test suite delete method!")
|
139
|
+
object_id_to_delete = result["id"]
|
140
|
+
delete_result = @api.delete_object(object_id_to_delete)
|
141
|
+
delete_result.should == true
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should be able to delete likes" do
|
145
|
+
result = @api.put_wall_post("Hello, world, from the test suite delete method!")
|
146
|
+
@temporary_object_id = result["id"]
|
147
|
+
@api.put_like(@temporary_object_id)
|
148
|
+
delete_like_result = @api.delete_like(@temporary_object_id)
|
149
|
+
delete_like_result.should == true
|
150
|
+
end
|
151
|
+
|
152
|
+
# additional put tests
|
153
|
+
it "should be able to verify messages posted to a wall" do
|
154
|
+
message = "the cats are asleep"
|
155
|
+
put_result = @api.put_wall_post(message)
|
156
|
+
@temporary_object_id = put_result["id"]
|
157
|
+
get_result = @api.get_object(@temporary_object_id)
|
158
|
+
|
159
|
+
# make sure the message we sent is the message that got posted
|
160
|
+
get_result["message"].should == message
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should be able to post a message with an attachment to a feed" do
|
164
|
+
result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "OAuth Playground", :link => "http://oauth.twoalex.com/"})
|
165
|
+
@temporary_object_id = result["id"]
|
166
|
+
@temporary_object_id.should_not be_nil
|
167
|
+
end
|
168
|
+
|
169
|
+
describe ".put_picture" do
|
170
|
+
it "should be able to post photos to the user's wall with an open file object" do
|
171
|
+
content_type = "image/jpg"
|
172
|
+
file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))
|
173
|
+
|
174
|
+
result = @api.put_picture(file, content_type)
|
175
|
+
@temporary_object_id = result["id"]
|
176
|
+
@temporary_object_id.should_not be_nil
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should be able to post photos to the user's wall without an open file object" do
|
180
|
+
content_type = "image/jpg",
|
181
|
+
file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
|
182
|
+
|
183
|
+
result = @api.put_picture(file_path, content_type)
|
184
|
+
@temporary_object_id = result["id"]
|
185
|
+
@temporary_object_id.should_not be_nil
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should be able to verify a photo posted to a user's wall" do
|
189
|
+
content_type = "image/jpg",
|
190
|
+
file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
|
191
|
+
|
192
|
+
expected_message = "This is the test message"
|
193
|
+
|
194
|
+
result = @api.put_picture(file_path, content_type, :message => expected_message)
|
195
|
+
@temporary_object_id = result["id"]
|
196
|
+
@temporary_object_id.should_not be_nil
|
197
|
+
|
198
|
+
get_result = @api.get_object(@temporary_object_id)
|
199
|
+
get_result["name"].should == expected_message
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
describe "using a URL instead of a file" do
|
204
|
+
before :each do
|
205
|
+
@url = "http://img.slate.com/images/redesign2008/slate_logo.gif"
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should be able to post photo to the user's wall using a URL" do
|
209
|
+
result = @api.put_picture(@url)
|
210
|
+
@temporary_object_id = result["id"]
|
211
|
+
@temporary_object_id.should_not be_nil
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should be able to post photo to the user's wall using a URL and an additional param" do
|
215
|
+
result = @api.put_picture(@url, :message => "my message")
|
216
|
+
@temporary_object_id = result["id"]
|
217
|
+
@temporary_object_id.should_not be_nil
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe ".put_video" do
|
223
|
+
before :each do
|
224
|
+
@cat_movie = File.join(File.dirname(__FILE__), "..", "fixtures", "cat.m4v")
|
225
|
+
@content_type = "video/mpeg4"
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should set options[:video] to true" do
|
229
|
+
source = stub("UploadIO")
|
230
|
+
Koala::UploadableIO.stub(:new).and_return(source)
|
231
|
+
source.stub(:requires_base_http_service).and_return(false)
|
232
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(:video => true)).and_return(Koala::Response.new(200, "[]", {}))
|
233
|
+
@api.put_video("foo")
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should be able to post videos to the user's wall with an open file object" do
|
237
|
+
file = File.open(@cat_movie)
|
238
|
+
|
239
|
+
result = @api.put_video(file, @content_type)
|
240
|
+
@temporary_object_id = result["id"]
|
241
|
+
@temporary_object_id.should_not be_nil
|
242
|
+
end
|
243
|
+
|
244
|
+
|
245
|
+
it "should be able to post videos to the user's wall without an open file object" do
|
246
|
+
result = @api.put_video(@cat_movie, @content_type)
|
247
|
+
@temporary_object_id = result["id"]
|
248
|
+
@temporary_object_id.should_not be_nil
|
249
|
+
end
|
250
|
+
|
251
|
+
# note: Facebook doesn't post videos immediately to the wall, due to processing time
|
252
|
+
# during which get_object(video_id) will return false
|
253
|
+
# hence we can't do the same verify test we do for photos
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should be able to verify a message with an attachment posted to a feed" do
|
257
|
+
attachment = {"name" => "OAuth Playground", "link" => "http://oauth.twoalex.com/"}
|
258
|
+
result = @api.put_wall_post("Hello, world, from the test suite again!", attachment)
|
259
|
+
@temporary_object_id = result["id"]
|
260
|
+
get_result = @api.get_object(@temporary_object_id)
|
261
|
+
|
262
|
+
# make sure the result we fetch includes all the parameters we sent
|
263
|
+
it_matches = attachment.inject(true) {|valid, param| valid && (get_result[param[0]] == attachment[param[0]])}
|
264
|
+
it_matches.should == true
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should be able to comment on an object" do
|
268
|
+
result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
|
269
|
+
@temporary_object_id = result["id"]
|
270
|
+
|
271
|
+
# this will be deleted when the post gets deleted
|
272
|
+
comment_result = @api.put_comment(@temporary_object_id, "it's my comment!")
|
273
|
+
comment_result.should_not be_nil
|
274
|
+
end
|
275
|
+
|
276
|
+
it "should be able to verify a comment posted about an object" do
|
277
|
+
message_text = "Hello, world, from the test suite, testing comments!"
|
278
|
+
result = @api.put_wall_post(message_text)
|
279
|
+
@temporary_object_id = result["id"]
|
280
|
+
|
281
|
+
# this will be deleted when the post gets deleted
|
282
|
+
comment_text = "it's my comment!"
|
283
|
+
comment_result = @api.put_comment(@temporary_object_id, comment_text)
|
284
|
+
get_result = @api.get_object(comment_result["id"])
|
285
|
+
|
286
|
+
# make sure the text of the comment matches what we sent
|
287
|
+
get_result["message"].should == comment_text
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should be able to like an object" do
|
291
|
+
result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
|
292
|
+
@temporary_object_id = result["id"]
|
293
|
+
like_result = @api.put_like(@temporary_object_id)
|
294
|
+
like_result.should be_true
|
295
|
+
end
|
296
|
+
|
297
|
+
# Page Access Token Support
|
298
|
+
it "gets a page's access token" do
|
299
|
+
# we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
|
300
|
+
@api.should_receive(:api).with("my_page", {:fields => "access_token"}, "get", anything)
|
301
|
+
@api.get_page_access_token("my_page")
|
302
|
+
end
|
303
|
+
|
304
|
+
# test all methods to make sure they pass data through to the API
|
305
|
+
# we run the tests here (rather than in the common shared example group)
|
306
|
+
# since some require access tokens
|
307
|
+
describe "HTTP options" do
|
308
|
+
# Each of the below methods should take an options hash as their last argument
|
309
|
+
# ideally we'd use introspection to determine how many arguments a method has
|
310
|
+
# but some methods require specially formatted arguments for processing
|
311
|
+
# (and anyway, Ruby 1.8's arity method fails (for this) for methods w/ 2+ optional arguments)
|
312
|
+
# (Ruby 1.9's parameters method is perfect, but only in 1.9)
|
313
|
+
# so we have to double-document
|
314
|
+
{
|
315
|
+
:get_object => 3, :put_object => 4, :delete_object => 2,
|
316
|
+
:get_connections => 4, :put_connections => 4, :delete_connections => 4,
|
317
|
+
:put_wall_post => 4,
|
318
|
+
:put_comment => 3,
|
319
|
+
:put_like => 2, :delete_like => 2,
|
320
|
+
:search => 3,
|
321
|
+
# methods that have special arguments
|
322
|
+
:put_picture => ["x.jpg", "image/jpg", {}, "me"],
|
323
|
+
:put_video => ["x.mp4", "video/mpeg4", {}, "me"],
|
324
|
+
:get_objects => [["x"], {}]
|
325
|
+
}.each_pair do |method_name, params|
|
326
|
+
it "should pass http options through for #{method_name}" do
|
327
|
+
options = {:a => 2}
|
328
|
+
# graph call should ultimately receive options as the fourth argument
|
329
|
+
@api.should_receive(:graph_call).with(anything, anything, anything, options)
|
330
|
+
|
331
|
+
# if we supply args, use them (since some methods process params)
|
332
|
+
# the method should receive as args n-1 anythings and then options
|
333
|
+
args = (params.is_a?(Integer) ? ([{}] * (params - 1)) : params) + [options]
|
334
|
+
|
335
|
+
@api.send(method_name, *args)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
# also test get_picture, which merges a parameter into options
|
340
|
+
it "should pass http options through for get_picture" do
|
341
|
+
options = {:a => 2}
|
342
|
+
# graph call should ultimately receive options as the fourth argument
|
343
|
+
@api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options)).and_return({})
|
344
|
+
@api.send(:get_picture, "x", {}, options)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
|
350
|
+
# GraphCollection
|
351
|
+
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
|
+
describe "when getting a collection" do
|
359
|
+
# GraphCollection methods
|
360
|
+
it "should get a GraphCollection when getting connections" do
|
361
|
+
@result = @api.get_connections(KoalaTest.page, "photos")
|
362
|
+
@result.should be_a(Koala::Facebook::GraphCollection)
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should return nil if the get_collections call fails with nil" do
|
366
|
+
# this happens sometimes
|
367
|
+
@api.should_receive(:graph_call).and_return(nil)
|
368
|
+
@api.get_connections(KoalaTest.page, "photos").should be_nil
|
369
|
+
end
|
370
|
+
|
371
|
+
it "should get a GraphCollection when searching" do
|
372
|
+
result = @api.search("facebook")
|
373
|
+
result.should be_a(Koala::Facebook::GraphCollection)
|
374
|
+
end
|
375
|
+
|
376
|
+
it "should return nil if the search call fails with nil" do
|
377
|
+
# this happens sometimes
|
378
|
+
@api.should_receive(:graph_call).and_return(nil)
|
379
|
+
@api.search("facebook").should be_nil
|
380
|
+
end
|
381
|
+
|
382
|
+
it "should get a GraphCollection when paging through results" do
|
383
|
+
@results = @api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=>"2010-09-23T21:17:33+0000"}])
|
384
|
+
@results.should be_a(Koala::Facebook::GraphCollection)
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should return nil if the page call fails with nil" do
|
388
|
+
# this happens sometimes
|
389
|
+
@api.should_receive(:graph_call).and_return(nil)
|
390
|
+
@api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=>"2010-09-23T21:17:33+0000"}]).should be_nil
|
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
|
451
|
+
end
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
|
456
|
+
shared_examples_for "Koala GraphAPI without an access token" do
|
457
|
+
|
458
|
+
it "should not get private data about a user" do
|
459
|
+
result = @api.get_object("koppel")
|
460
|
+
# updated_time should be a pretty fixed test case
|
461
|
+
result["updated_time"].should be_nil
|
462
|
+
end
|
463
|
+
|
464
|
+
it "should not be able to get data about 'me'" do
|
465
|
+
lambda { @api.get_object("me") }.should raise_error(Koala::Facebook::APIError)
|
466
|
+
end
|
467
|
+
|
468
|
+
it "shouldn't be able to access connections from users" do
|
469
|
+
lambda { @api.get_connections("lukeshepard", "friends") }.should raise_error(Koala::Facebook::APIError)
|
470
|
+
end
|
471
|
+
|
472
|
+
it "should not be able to put an object" do
|
473
|
+
lambda { @result = @api.put_object("lukeshepard", "feed", :message => "Hello, world") }.should raise_error(Koala::Facebook::APIError)
|
474
|
+
end
|
475
|
+
|
476
|
+
# these are not strictly necessary as the other put methods resolve to put_object, but are here for completeness
|
477
|
+
it "should not be able to post to a feed" do
|
478
|
+
(lambda do
|
479
|
+
attachment = {:name => "OAuth Playground", :link => "http://oauth.twoalex.com/"}
|
480
|
+
@result = @api.put_wall_post("Hello, world", attachment, "contextoptional")
|
481
|
+
end).should raise_error(Koala::Facebook::APIError)
|
482
|
+
end
|
483
|
+
|
484
|
+
it "should not be able to comment on an object" do
|
485
|
+
# random public post on the ContextOptional wall
|
486
|
+
lambda { @result = @api.put_comment("7204941866_119776748033392", "The hackathon was great!") }.should raise_error(Koala::Facebook::APIError)
|
487
|
+
end
|
488
|
+
|
489
|
+
it "should not be able to like an object" do
|
490
|
+
lambda { @api.put_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
|
491
|
+
end
|
492
|
+
|
493
|
+
# DELETE
|
494
|
+
it "should not be able to delete posts" do
|
495
|
+
# test post on the Ruby SDK Test application
|
496
|
+
lambda { @result = @api.delete_object("115349521819193_113815981982767") }.should raise_error(Koala::Facebook::APIError)
|
497
|
+
end
|
498
|
+
|
499
|
+
it "should not be able to delete a like" do
|
500
|
+
lambda { @api.delete_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
|
501
|
+
end
|
502
|
+
end
|