koala 1.2.0 → 1.3.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.
Files changed (54) hide show
  1. data/.gitignore +3 -1
  2. data/.rspec +1 -0
  3. data/.travis.yml +4 -0
  4. data/.yardopts +3 -0
  5. data/CHANGELOG +43 -0
  6. data/Gemfile +14 -0
  7. data/Guardfile +6 -0
  8. data/koala.gemspec +4 -4
  9. data/lib/koala/api/batch_operation.rb +83 -0
  10. data/lib/koala/api/graph_api.rb +476 -0
  11. data/lib/koala/{graph_batch_api.rb → api/graph_batch_api.rb} +22 -17
  12. data/lib/koala/api/graph_collection.rb +107 -0
  13. data/lib/koala/api/legacy.rb +26 -0
  14. data/lib/koala/{rest_api.rb → api/rest_api.rb} +36 -10
  15. data/lib/koala/api.rb +93 -0
  16. data/lib/koala/http_service/multipart_request.rb +41 -0
  17. data/lib/koala/http_service/response.rb +18 -0
  18. data/lib/koala/http_service/uploadable_io.rb +187 -0
  19. data/lib/koala/http_service.rb +73 -23
  20. data/lib/koala/oauth.rb +173 -36
  21. data/lib/koala/realtime_updates.rb +89 -51
  22. data/lib/koala/test_users.rb +122 -32
  23. data/lib/koala/utils.rb +11 -4
  24. data/lib/koala/version.rb +1 -1
  25. data/lib/koala.rb +16 -95
  26. data/readme.md +30 -13
  27. data/spec/cases/api_spec.rb +28 -21
  28. data/spec/cases/error_spec.rb +10 -0
  29. data/spec/cases/graph_api_batch_spec.rb +100 -58
  30. data/spec/cases/graph_collection_spec.rb +23 -7
  31. data/spec/cases/http_service_spec.rb +14 -34
  32. data/spec/cases/koala_spec.rb +22 -4
  33. data/spec/cases/legacy_spec.rb +115 -0
  34. data/spec/cases/multipart_request_spec.rb +66 -0
  35. data/spec/cases/oauth_spec.rb +232 -108
  36. data/spec/cases/realtime_updates_spec.rb +154 -47
  37. data/spec/cases/test_users_spec.rb +276 -217
  38. data/spec/cases/uploadable_io_spec.rb +1 -1
  39. data/spec/cases/utils_spec.rb +29 -5
  40. data/spec/fixtures/mock_facebook_responses.yml +50 -26
  41. data/spec/spec_helper.rb +3 -0
  42. data/spec/support/custom_matchers.rb +28 -0
  43. data/spec/support/graph_api_shared_examples.rb +274 -70
  44. data/spec/support/koala_test.rb +27 -16
  45. data/spec/support/mock_http_service.rb +2 -2
  46. data/spec/support/rest_api_shared_examples.rb +46 -162
  47. metadata +33 -25
  48. data/lib/koala/batch_operation.rb +0 -74
  49. data/lib/koala/graph_api.rb +0 -270
  50. data/lib/koala/graph_collection.rb +0 -59
  51. data/lib/koala/uploadable_io.rb +0 -181
  52. data/spec/cases/graph_and_rest_api_spec.rb +0 -22
  53. data/spec/cases/graph_api_spec.rb +0 -22
  54. data/spec/cases/rest_api_spec.rb +0 -41
@@ -2,27 +2,27 @@ shared_examples_for "Koala GraphAPI" do
2
2
  # all Graph API instances should pass these tests, regardless of configuration
3
3
 
4
4
  # API
5
- it "should never use the rest api server" do
5
+ it "never uses the rest api server" do
6
6
  Koala.should_receive(:make_request).with(
7
7
  anything,
8
8
  anything,
9
9
  anything,
10
10
  hash_not_including(:rest_api => true)
11
- ).and_return(Koala::Response.new(200, "", {}))
11
+ ).and_return(Koala::HTTPService::Response.new(200, "", {}))
12
12
 
13
13
  @api.api("anything")
14
14
  end
15
15
 
16
16
  # GRAPH CALL
17
17
  describe "graph_call" do
18
- it "should pass all arguments to the api method" do
18
+ it "passes all arguments to the api method" do
19
19
  args = [KoalaTest.user1, {}, "get", {:a => :b}]
20
20
  @api.should_receive(:api).with(*args)
21
21
  @api.graph_call(*args)
22
22
  end
23
23
 
24
- it "should throw an APIError if the result hash has an error key" do
25
- Koala.stub(:make_request).and_return(Koala::Response.new(500, {"error" => "An error occurred!"}, {}))
24
+ it "throws an APIError if the result hash has an error key" do
25
+ Koala.stub(:make_request).and_return(Koala::HTTPService::Response.new(500, {"error" => "An error occurred!"}, {}))
26
26
  lambda { @api.graph_call(KoalaTest.user1, {}) }.should raise_exception(Koala::Facebook::APIError)
27
27
  end
28
28
 
@@ -49,7 +49,7 @@ shared_examples_for "Koala GraphAPI" do
49
49
  end
50
50
 
51
51
  # SEARCH
52
- it "should be able to search" do
52
+ it "can search" do
53
53
  result = @api.search("facebook")
54
54
  result.length.should be_an(Integer)
55
55
  end
@@ -58,109 +58,173 @@ shared_examples_for "Koala GraphAPI" do
58
58
  # access public info
59
59
 
60
60
  # get_object
61
- it "should get public data about a user" do
61
+ it "gets public data about a user" do
62
62
  result = @api.get_object(KoalaTest.user1)
63
63
  # the results should have an ID and a name, among other things
64
64
  (result["id"] && result["name"]).should_not be_nil
65
65
  end
66
66
 
67
- it "should get public data about a Page" do
67
+ it "gets public data about a Page" do
68
68
  result = @api.get_object(KoalaTest.page)
69
69
  # the results should have an ID and a name, among other things
70
70
  (result["id"] && result["name"]).should
71
71
  end
72
72
 
73
- it "should return [] from get_objects if passed an empty array" do
73
+ it "returns [] from get_objects if passed an empty array" do
74
74
  results = @api.get_objects([])
75
75
  results.should == []
76
76
  end
77
77
 
78
- it "should be able to get multiple objects" do
78
+ it "gets multiple objects" do
79
79
  results = @api.get_objects([KoalaTest.page, KoalaTest.user1])
80
80
  results.should have(2).items
81
81
  end
82
82
 
83
- it "should be able to get multiple objects if they're a string" do
83
+ it "gets multiple objects if they're a string" do
84
84
  results = @api.get_objects("contextoptional,#{KoalaTest.user1}")
85
85
  results.should have(2).items
86
86
  end
87
87
 
88
- it "should be able to access a user's picture" do
89
- @api.get_picture("chris.baclig").should =~ /http[s]*\:\/\//
88
+ it "can access a user's picture" do
89
+ @api.get_picture(KoalaTest.user2).should =~ /http[s]*\:\/\//
90
90
  end
91
91
 
92
- it "should be able to access a user's picture, given a picture type" do
92
+ it "can access a user's picture, given a picture type" do
93
93
  @api.get_picture(KoalaTest.user2, {:type => 'large'}).should =~ /^http[s]*\:\/\//
94
94
  end
95
95
 
96
- it "should be able to access connections from public Pages" do
96
+ it "can access connections from public Pages" do
97
97
  result = @api.get_connections(KoalaTest.page, "photos")
98
98
  result.should be_a(Array)
99
99
  end
100
100
 
101
- it "should be able to access comments for a URL" do
101
+ it "can access comments for a URL" do
102
102
  result = @api.get_comments_for_urls(["http://developers.facebook.com/blog/post/472"])
103
103
  (result["http://developers.facebook.com/blog/post/472"]).should
104
104
  end
105
105
 
106
- it "should be able to access comments for 2 URLs" do
106
+ it "can access comments for 2 URLs" do
107
107
  result = @api.get_comments_for_urls(["http://developers.facebook.com/blog/post/490", "http://developers.facebook.com/blog/post/472"])
108
108
  (result["http://developers.facebook.com/blog/post/490"] && result["http://developers.facebook.com/blog/post/472"]).should
109
109
  end
110
110
 
111
111
  # SEARCH
112
- it "should be able to search" do
112
+ it "can search" do
113
113
  result = @api.search("facebook")
114
114
  result.length.should be_an(Integer)
115
115
  end
116
116
 
117
117
  # PAGING THROUGH COLLECTIONS
118
118
  # see also graph_collection_tests
119
- it "should make a request for a page when provided a specific set of page params" do
119
+ it "makes a request for a page when provided a specific set of page params" do
120
120
  query = [1, 2]
121
121
  @api.should_receive(:graph_call).with(*query)
122
122
  @api.get_page(query)
123
123
  end
124
+
125
+ # Beta tier
126
+ it "can use the beta tier" do
127
+ result = @api.get_object(KoalaTest.user1, {}, :beta => true)
128
+ # the results should have an ID and a name, among other things
129
+ (result["id"] && result["name"]).should_not be_nil
130
+ end
131
+
132
+ # FQL
133
+ describe "#fql_query" do
134
+ it "makes a request to /fql" do
135
+ @api.should_receive(:get_object).with("fql", anything, anything)
136
+ @api.fql_query stub('query string')
137
+ end
138
+
139
+ it "passes a query argument" do
140
+ query = stub('query string')
141
+ @api.should_receive(:get_object).with(anything, hash_including(:q => query), anything)
142
+ @api.fql_query(query)
143
+ end
144
+
145
+ it "passes on any other arguments provided" do
146
+ args = {:a => 2}
147
+ @api.should_receive(:get_object).with(anything, hash_including(args), anything)
148
+ @api.fql_query("a query", args)
149
+ end
150
+ end
151
+
152
+ describe "#fql_multiquery" do
153
+ it "makes a request to /fql" do
154
+ @api.should_receive(:get_object).with("fql", anything, anything)
155
+ @api.fql_multiquery 'query string'
156
+ end
157
+
158
+ it "passes a queries argument" do
159
+ queries = stub('query string')
160
+ queries_json = "some JSON"
161
+ MultiJson.stub(:encode).with(queries).and_return(queries_json)
162
+
163
+ @api.should_receive(:get_object).with(anything, hash_including(:q => queries_json), anything)
164
+ @api.fql_multiquery(queries)
165
+ end
166
+
167
+ it "simplifies the response format" do
168
+ raw_results = [
169
+ {"name" => "query1", "fql_result_set" => [1, 2, 3]},
170
+ {"name" => "query2", "fql_result_set" => [:a, :b, :c]}
171
+ ]
172
+ expected_results = {
173
+ "query1" => [1, 2, 3],
174
+ "query2" => [:a, :b, :c]
175
+ }
176
+
177
+ @api.stub(:get_object).and_return(raw_results)
178
+ results = @api.fql_multiquery({:query => true})
179
+ results.should == expected_results
180
+ end
181
+
182
+ it "passes on any other arguments provided" do
183
+ args = {:a => 2}
184
+ @api.should_receive(:get_object).with(anything, hash_including(args), anything)
185
+ @api.fql_multiquery("a query", args)
186
+ end
187
+ end
124
188
  end
125
189
 
126
190
 
127
191
  shared_examples_for "Koala GraphAPI with an access token" do
128
- it "should get private data about a user" do
192
+ it "gets private data about a user" do
129
193
  result = @api.get_object(KoalaTest.user1)
130
194
  # updated_time should be a pretty fixed test case
131
195
  result["updated_time"].should_not be_nil
132
196
  end
133
197
 
134
- it "should get data about 'me'" do
198
+ it "gets data about 'me'" do
135
199
  result = @api.get_object("me")
136
200
  result["updated_time"].should
137
201
  end
138
202
 
139
- it "should be able to get multiple objects" do
203
+ it "gets multiple objects" do
140
204
  result = @api.get_objects([KoalaTest.page, KoalaTest.user1])
141
205
  result.length.should == 2
142
206
  end
143
- it "should be able to access connections from users" do
207
+ it "can access connections from users" do
144
208
  result = @api.get_connections(KoalaTest.user2, "friends")
145
209
  result.length.should > 0
146
210
  end
147
211
 
148
212
  # PUT
149
- it "should be able to write an object to the graph" do
213
+ it "can write an object to the graph" do
150
214
  result = @api.put_wall_post("Hello, world, from the test suite!")
151
215
  @temporary_object_id = result["id"]
152
216
  @temporary_object_id.should_not be_nil
153
217
  end
154
218
 
155
219
  # DELETE
156
- it "should be able to delete posts" do
220
+ it "can delete posts" do
157
221
  result = @api.put_wall_post("Hello, world, from the test suite delete method!")
158
222
  object_id_to_delete = result["id"]
159
223
  delete_result = @api.delete_object(object_id_to_delete)
160
224
  delete_result.should == true
161
225
  end
162
226
 
163
- it "should be able to delete likes" do
227
+ it "can delete likes" do
164
228
  result = @api.put_wall_post("Hello, world, from the test suite delete method!")
165
229
  @temporary_object_id = result["id"]
166
230
  @api.put_like(@temporary_object_id)
@@ -169,7 +233,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
169
233
  end
170
234
 
171
235
  # additional put tests
172
- it "should be able to verify messages posted to a wall" do
236
+ it "can verify messages posted to a wall" do
173
237
  message = "the cats are asleep"
174
238
  put_result = @api.put_wall_post(message)
175
239
  @temporary_object_id = put_result["id"]
@@ -179,14 +243,33 @@ shared_examples_for "Koala GraphAPI with an access token" do
179
243
  get_result["message"].should == message
180
244
  end
181
245
 
182
- it "should be able to post a message with an attachment to a feed" do
246
+ it "can post a message with an attachment to a feed" do
183
247
  result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "OAuth Playground", :link => "http://oauth.twoalex.com/"})
184
248
  @temporary_object_id = result["id"]
185
249
  @temporary_object_id.should_not be_nil
186
250
  end
251
+
252
+ it "can post a message whose attachment has a properties dictionary" do
253
+ url = KoalaTest.oauth_test_data["callback_url"]
254
+ options = {
255
+ "picture" => "#{KoalaTest.oauth_test_data["callback_url"]}/images/logo.png",
256
+ "name" => "It's a big question",
257
+ "type" => "link",
258
+ "link" => KoalaTest.oauth_test_data["callback_url"],
259
+ "properties" => [
260
+ {"name" => "Link1'", "text" => "Left", "href" => url},
261
+ {"name" => "other", "text" => "Straight ahead"}
262
+ ]
263
+ }
264
+
265
+ result = @api.put_wall_post("body", options)
266
+ @temporary_object_id = result["id"]
267
+ @temporary_object_id.should_not be_nil
268
+ end
269
+
187
270
 
188
- describe ".put_picture" do
189
- it "should be able to post photos to the user's wall with an open file object" do
271
+ describe "#put_picture" do
272
+ it "can post photos to the user's wall with an open file object" do
190
273
  content_type = "image/jpg"
191
274
  file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))
192
275
 
@@ -195,7 +278,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
195
278
  @temporary_object_id.should_not be_nil
196
279
  end
197
280
 
198
- it "should be able to post photos to the user's wall without an open file object" do
281
+ it "can post photos to the user's wall without an open file object" do
199
282
  content_type = "image/jpg",
200
283
  file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
201
284
 
@@ -204,7 +287,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
204
287
  @temporary_object_id.should_not be_nil
205
288
  end
206
289
 
207
- it "should be able to verify a photo posted to a user's wall" do
290
+ it "can verify a photo posted to a user's wall" do
208
291
  content_type = "image/jpg",
209
292
  file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
210
293
 
@@ -224,13 +307,13 @@ shared_examples_for "Koala GraphAPI with an access token" do
224
307
  @url = "http://img.slate.com/images/redesign2008/slate_logo.gif"
225
308
  end
226
309
 
227
- it "should be able to post photo to the user's wall using a URL" do
310
+ it "can post photo to the user's wall using a URL" do
228
311
  result = @api.put_picture(@url)
229
312
  @temporary_object_id = result["id"]
230
313
  @temporary_object_id.should_not be_nil
231
314
  end
232
315
 
233
- it "should be able to post photo to the user's wall using a URL and an additional param" do
316
+ it "can post photo to the user's wall using a URL and an additional param" do
234
317
  result = @api.put_picture(@url, :message => "my message")
235
318
  @temporary_object_id = result["id"]
236
319
  @temporary_object_id.should_not be_nil
@@ -238,21 +321,21 @@ shared_examples_for "Koala GraphAPI with an access token" do
238
321
  end
239
322
  end
240
323
 
241
- describe ".put_video" do
324
+ describe "#put_video" do
242
325
  before :each do
243
326
  @cat_movie = File.join(File.dirname(__FILE__), "..", "fixtures", "cat.m4v")
244
327
  @content_type = "video/mpeg4"
245
328
  end
246
329
 
247
- it "should set options[:video] to true" do
330
+ it "sets options[:video] to true" do
248
331
  source = stub("UploadIO")
249
332
  Koala::UploadableIO.stub(:new).and_return(source)
250
333
  source.stub(:requires_base_http_service).and_return(false)
251
- Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(:video => true)).and_return(Koala::Response.new(200, "[]", {}))
334
+ Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(:video => true)).and_return(Koala::HTTPService::Response.new(200, "[]", {}))
252
335
  @api.put_video("foo")
253
336
  end
254
337
 
255
- it "should be able to post videos to the user's wall with an open file object" do
338
+ it "can post videos to the user's wall with an open file object" do
256
339
  file = File.open(@cat_movie)
257
340
 
258
341
  result = @api.put_video(file, @content_type)
@@ -261,7 +344,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
261
344
  end
262
345
 
263
346
 
264
- it "should be able to post videos to the user's wall without an open file object" do
347
+ it "can post videos to the user's wall without an open file object" do
265
348
  result = @api.put_video(@cat_movie, @content_type)
266
349
  @temporary_object_id = result["id"]
267
350
  @temporary_object_id.should_not be_nil
@@ -272,7 +355,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
272
355
  # hence we can't do the same verify test we do for photos
273
356
  end
274
357
 
275
- it "should be able to verify a message with an attachment posted to a feed" do
358
+ it "can verify a message with an attachment posted to a feed" do
276
359
  attachment = {"name" => "OAuth Playground", "link" => "http://oauth.twoalex.com/"}
277
360
  result = @api.put_wall_post("Hello, world, from the test suite again!", attachment)
278
361
  @temporary_object_id = result["id"]
@@ -283,7 +366,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
283
366
  it_matches.should == true
284
367
  end
285
368
 
286
- it "should be able to comment on an object" do
369
+ it "can comment on an object" do
287
370
  result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
288
371
  @temporary_object_id = result["id"]
289
372
 
@@ -292,8 +375,8 @@ shared_examples_for "Koala GraphAPI with an access token" do
292
375
  comment_result.should_not be_nil
293
376
  end
294
377
 
295
- it "should be able to verify a comment posted about an object" do
296
- message_text = "Hello, world, from the test suite, testing comments!"
378
+ it "can verify a comment posted about an object" do
379
+ message_text = "Hello, world, from the test suite, testing comments again!"
297
380
  result = @api.put_wall_post(message_text)
298
381
  @temporary_object_id = result["id"]
299
382
 
@@ -306,18 +389,103 @@ shared_examples_for "Koala GraphAPI with an access token" do
306
389
  get_result["message"].should == comment_text
307
390
  end
308
391
 
309
- it "should be able to like an object" do
310
- result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
392
+ it "can like an object" do
393
+ result = @api.put_wall_post("Hello, world, from the test suite, testing liking!")
311
394
  @temporary_object_id = result["id"]
312
395
  like_result = @api.put_like(@temporary_object_id)
313
396
  like_result.should be_true
314
397
  end
315
398
 
316
399
  # Page Access Token Support
317
- it "gets a page's access token" do
318
- # we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
319
- @api.should_receive(:api).with("my_page", {:fields => "access_token"}, "get", anything)
320
- @api.get_page_access_token("my_page")
400
+ describe "#get_page_access_token" do
401
+ it "gets the page object with the access_token field" do
402
+ # we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
403
+ @api.should_receive(:api).with("my_page", hash_including({:fields => "access_token"}), "get", anything)
404
+ @api.get_page_access_token("my_page")
405
+ end
406
+
407
+ it "merges in any other arguments" do
408
+ # we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
409
+ args = {:a => 3}
410
+ @api.should_receive(:api).with("my_page", hash_including(args), "get", anything)
411
+ @api.get_page_access_token("my_page", args)
412
+ end
413
+ end
414
+
415
+ describe "#set_app_restrictions" do
416
+ before :all do
417
+ oauth = Koala::Facebook::OAuth.new(KoalaTest.app_id, KoalaTest.secret)
418
+ app_token = oauth.get_app_access_token
419
+ @app_api = Koala::Facebook::API.new(app_token)
420
+ @restrictions = {"age_distr" => "13+"}
421
+ end
422
+
423
+ it "makes a POST to /app_id" do
424
+ @app_api.should_receive(:graph_call).with(KoalaTest.app_id, anything, "post", anything)
425
+ @app_api.set_app_restrictions(KoalaTest.app_id, @restrictions)
426
+ end
427
+
428
+ it "JSON-encodes the restrictions" do
429
+ @app_api.should_receive(:graph_call).with(anything, hash_including(:restrictions => MultiJson.encode(@restrictions)), anything, anything)
430
+ @app_api.set_app_restrictions(KoalaTest.app_id, @restrictions)
431
+ end
432
+
433
+ it "includes the other arguments" do
434
+ args = {:a => 2}
435
+ @app_api.should_receive(:graph_call).with(anything, hash_including(args), anything, anything)
436
+ @app_api.set_app_restrictions(KoalaTest.app_id, @restrictions, args)
437
+ end
438
+
439
+ it "works" do
440
+ @app_api.set_app_restrictions(KoalaTest.app_id, @restrictions).should be_true
441
+ end
442
+ end
443
+
444
+ it "changes tests to first_name when FB repairs its bug"
445
+
446
+ it "can access public information via FQL" do
447
+ result = @api.fql_query("select uid, first_name from user where uid = #{KoalaTest.user2_id}")
448
+ result.size.should == 1
449
+ # result.first['first_name'].should == KoalaTest.user2_name
450
+ result.first['uid'].should == KoalaTest.user2_id.to_i
451
+ end
452
+
453
+ it "can access public information via FQL.multiquery" do
454
+ result = @api.fql_multiquery(
455
+ :query1 => "select uid, first_name from user where uid = #{KoalaTest.user2_id}",
456
+ :query2 => "select uid, first_name from user where uid = #{KoalaTest.user1_id}"
457
+ )
458
+ result.size.should == 2
459
+ # this should check for first_name, but there's an FB bug currently
460
+ result["query1"].first['uid'].should == KoalaTest.user2_id.to_i
461
+ # result["query1"].first['first_name'].should == KoalaTest.user2_name
462
+ result["query2"].first['first_name'].should == KoalaTest.user1_name
463
+ end
464
+
465
+ it "can access protected information via FQL" do
466
+ # Tests agains the permissions fql table
467
+
468
+ # get the current user's ID
469
+ # we're sneakily using the Graph API, which should be okay since it has its own tests
470
+ g = Koala::Facebook::API.new(@token)
471
+ id = g.get_object("me", :fields => "id")["id"]
472
+
473
+ # now send a query about your permissions
474
+ result = @api.fql_query("select read_stream from permissions where uid = #{id}")
475
+
476
+ result.size.should == 1
477
+ # we've verified that you have read_stream permissions, so we can test against that
478
+ result.first["read_stream"].should == 1
479
+ end
480
+
481
+ it "can access protected information via FQL.multiquery" do
482
+ result = @api.fql_multiquery(
483
+ :query1 => "select post_id from stream where source_id = me()",
484
+ :query2 => "select fromid from comment where post_id in (select post_id from #query1)",
485
+ :query3 => "select uid, name from user where uid in (select fromid from #query2)"
486
+ )
487
+ result.size.should == 3
488
+ result.keys.should include("query1", "query2", "query3")
321
489
  end
322
490
 
323
491
  # test all methods to make sure they pass data through to the API
@@ -337,12 +505,16 @@ shared_examples_for "Koala GraphAPI with an access token" do
337
505
  :put_comment => 3,
338
506
  :put_like => 2, :delete_like => 2,
339
507
  :search => 3,
508
+ :set_app_restrictions => 4,
509
+ :get_page_access_token => 3,
510
+ :fql_query => 3, :fql_multiquery => 3,
340
511
  # methods that have special arguments
512
+ :get_comments_for_urls => [["url1", "url2"], {}],
341
513
  :put_picture => ["x.jpg", "image/jpg", {}, "me"],
342
514
  :put_video => ["x.mp4", "video/mpeg4", {}, "me"],
343
515
  :get_objects => [["x"], {}]
344
516
  }.each_pair do |method_name, params|
345
- it "should pass http options through for #{method_name}" do
517
+ it "passes http options through for #{method_name}" do
346
518
  options = {:a => 2}
347
519
  # graph call should ultimately receive options as the fourth argument
348
520
  @api.should_receive(:graph_call).with(anything, anything, anything, options)
@@ -356,7 +528,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
356
528
  end
357
529
 
358
530
  # also test get_picture, which merges a parameter into options
359
- it "should pass http options through for get_picture" do
531
+ it "passes http options through for get_picture" do
360
532
  options = {:a => 2}
361
533
  # graph call should ultimately receive options as the fourth argument
362
534
  @api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options)).and_return({})
@@ -370,34 +542,34 @@ end
370
542
  shared_examples_for "Koala GraphAPI with GraphCollection" do
371
543
  describe "when getting a collection" do
372
544
  # GraphCollection methods
373
- it "should get a GraphCollection when getting connections" do
545
+ it "gets a GraphCollection when getting connections" do
374
546
  @result = @api.get_connections(KoalaTest.page, "photos")
375
547
  @result.should be_a(Koala::Facebook::GraphCollection)
376
548
  end
377
549
 
378
- it "should return nil if the get_collections call fails with nil" do
550
+ it "returns nil if the get_collections call fails with nil" do
379
551
  # this happens sometimes
380
552
  @api.should_receive(:graph_call).and_return(nil)
381
553
  @api.get_connections(KoalaTest.page, "photos").should be_nil
382
554
  end
383
555
 
384
- it "should get a GraphCollection when searching" do
556
+ it "gets a GraphCollection when searching" do
385
557
  result = @api.search("facebook")
386
558
  result.should be_a(Koala::Facebook::GraphCollection)
387
559
  end
388
560
 
389
- it "should return nil if the search call fails with nil" do
561
+ it "returns nil if the search call fails with nil" do
390
562
  # this happens sometimes
391
563
  @api.should_receive(:graph_call).and_return(nil)
392
564
  @api.search("facebook").should be_nil
393
565
  end
394
566
 
395
- it "should get a GraphCollection when paging through results" do
567
+ it "gets a GraphCollection when paging through results" do
396
568
  @results = @api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=> KoalaTest.search_time}])
397
569
  @results.should be_a(Koala::Facebook::GraphCollection)
398
570
  end
399
571
 
400
- it "should return nil if the page call fails with nil" do
572
+ it "returns nil if the page call fails with nil" do
401
573
  # this happens sometimes
402
574
  @api.should_receive(:graph_call).and_return(nil)
403
575
  @api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=> KoalaTest.search_time}]).should be_nil
@@ -407,49 +579,81 @@ end
407
579
 
408
580
 
409
581
  shared_examples_for "Koala GraphAPI without an access token" do
410
-
411
- it "should not get private data about a user" do
412
- result = @api.get_object("koppel")
582
+ it "can't get private data about a user" do
583
+ result = @api.get_object(KoalaTest.user1)
413
584
  # updated_time should be a pretty fixed test case
414
585
  result["updated_time"].should be_nil
415
586
  end
416
587
 
417
- it "should not be able to get data about 'me'" do
588
+ it "can't get data about 'me'" do
418
589
  lambda { @api.get_object("me") }.should raise_error(Koala::Facebook::APIError)
419
590
  end
420
591
 
421
- it "shouldn't be able to access connections from users" do
422
- lambda { @api.get_connections("lukeshepard", "friends") }.should raise_error(Koala::Facebook::APIError)
592
+ it "can't access connections from users" do
593
+ lambda { @api.get_connections(KoalaTest.user2, "friends") }.should raise_error(Koala::Facebook::APIError)
423
594
  end
424
595
 
425
- it "should not be able to put an object" do
426
- lambda { @result = @api.put_object("lukeshepard", "feed", :message => "Hello, world") }.should raise_error(Koala::Facebook::APIError)
596
+ it "can't put an object" do
597
+ lambda { @result = @api.put_object(KoalaTest.user2, "feed", :message => "Hello, world") }.should raise_error(Koala::Facebook::APIError)
427
598
  end
428
599
 
429
600
  # these are not strictly necessary as the other put methods resolve to put_object, but are here for completeness
430
- it "should not be able to post to a feed" do
601
+ it "can't post to a feed" do
431
602
  (lambda do
432
603
  attachment = {:name => "OAuth Playground", :link => "http://oauth.twoalex.com/"}
433
604
  @result = @api.put_wall_post("Hello, world", attachment, "contextoptional")
434
605
  end).should raise_error(Koala::Facebook::APIError)
435
606
  end
436
607
 
437
- it "should not be able to comment on an object" do
608
+ it "can't comment on an object" do
438
609
  # random public post on the ContextOptional wall
439
610
  lambda { @result = @api.put_comment("7204941866_119776748033392", "The hackathon was great!") }.should raise_error(Koala::Facebook::APIError)
440
611
  end
441
612
 
442
- it "should not be able to like an object" do
613
+ it "can't like an object" do
443
614
  lambda { @api.put_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
444
615
  end
445
616
 
446
617
  # DELETE
447
- it "should not be able to delete posts" do
618
+ it "can't delete posts" do
448
619
  # test post on the Ruby SDK Test application
449
620
  lambda { @result = @api.delete_object("115349521819193_113815981982767") }.should raise_error(Koala::Facebook::APIError)
450
621
  end
451
622
 
452
- it "should not be able to delete a like" do
623
+ it "can't delete a like" do
453
624
  lambda { @api.delete_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
454
625
  end
626
+
627
+ # FQL_QUERY
628
+ describe "when making a FQL request" do
629
+ it "can access public information via FQL" do
630
+ result = @api.fql_query("select uid, first_name from user where uid = #{KoalaTest.user2_id}")
631
+ result.size.should == 1
632
+ result.first['first_name'].should == KoalaTest.user2_name
633
+ end
634
+
635
+ it "can access public information via FQL.multiquery" do
636
+ result = @api.fql_multiquery(
637
+ :query1 => "select uid, first_name from user where uid = #{KoalaTest.user2_id}",
638
+ :query2 => "select uid, first_name from user where uid = #{KoalaTest.user1_id}"
639
+ )
640
+ result.size.should == 2
641
+ result["query1"].first['first_name'].should == KoalaTest.user2_name
642
+ result["query2"].first['first_name'].should == KoalaTest.user1_name
643
+ end
644
+
645
+ it "can't access protected information via FQL" do
646
+ lambda { @api.fql_query("select read_stream from permissions where uid = #{KoalaTest.user2_id}") }.should raise_error(Koala::Facebook::APIError)
647
+ end
648
+
649
+ it "can't access protected information via FQL.multiquery" do
650
+ lambda {
651
+ @api.fql_multiquery(
652
+ :query1 => "select post_id from stream where source_id = me()",
653
+ :query2 => "select fromid from comment where post_id in (select post_id from #query1)",
654
+ :query3 => "select uid, name from user where uid in (select fromid from #query2)"
655
+ )
656
+ }.should raise_error(Koala::Facebook::APIError)
657
+ end
658
+ end
455
659
  end