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
@@ -14,26 +14,15 @@
14
14
  rest_api:
15
15
 
16
16
  # -- Stubbed Responses --
17
- /method/fql.query:
17
+ /method/admin.setAppProperties:
18
+ 'properties={"desktop":0}':
19
+ post:
20
+ with_token: 'true'
21
+ /method/fql.query: # for testing the beta tier
18
22
  query=select first_name from user where uid = 2901279:
19
23
  get:
20
24
  no_token: '[{"first_name":"Luke"}]'
21
25
  with_token: '[{"first_name":"Luke"}]'
22
- query=select read_stream from permissions where uid = 2901279:
23
- get:
24
- with_token: '[{"read_stream":1}]'
25
- no_token: '{"error_code":104,"error_msg":"Requires valid signature","request_args":[{"key":"method","value":"fql.query"},{"key":"format","value":"json"},{"key":"query","value":"select read_stream from permissions where uid = 2901279"}]}'
26
-
27
- /method/fql.multiquery:
28
- 'queries=<%= MultiJson.encode({"query1" => "select post_id from stream where source_id = me()", "query2" => "select fromid from comment where post_id in (select post_id from #query1)", "query3" => "select uid, name from user where uid in (select fromid from #query2)"}) %>':
29
- get:
30
- with_token: '[{"name":"query1", "fql_result_set":[]},{"name":"query2", "fql_result_set":[]},{"name":"query3", "fql_result_set":[]}]'
31
- no_token: '{"error_code":104,"error_msg":"Requires valid signature","request_args":[{"key":"method","value":"fql.query"},{"key":"format","value":"json"},{"key":"query","value":"select read_stream from permissions where uid = 2901279"}]}'
32
- 'queries=<%= MultiJson.encode({"query1" => "select first_name from user where uid = 2901279", "query2" => "select first_name from user where uid = 2905623"}) %>':
33
- get:
34
- with_token: '[{"name":"query1", "fql_result_set":[{"first_name":"Luke"}]},{"name":"query2", "fql_result_set":[{"first_name":"Alex"}]}]'
35
- no_token: '[{"name":"query1", "fql_result_set":[{"first_name":"Luke"}]},{"name":"query2", "fql_result_set":[{"first_name":"Alex"}]}]'
36
-
37
26
 
38
27
 
39
28
 
@@ -148,6 +137,12 @@ graph_api:
148
137
  message=Hello, world, from the test suite, testing comments!:
149
138
  post:
150
139
  with_token: '{"id": "MOCK_FEED_ITEM"}'
140
+ message=Hello, world, from the test suite, testing comments again!:
141
+ post:
142
+ with_token: '{"id": "MOCK_FEED_ITEM"}'
143
+ message=Hello, world, from the test suite, testing liking!:
144
+ post:
145
+ with_token: '{"id": "MOCK_FEED_ITEM"}'
151
146
  message=the cats are asleep:
152
147
  post:
153
148
  with_token: '{"id": "FEED_ITEM_CATS"}'
@@ -160,6 +155,9 @@ graph_api:
160
155
  link=http://oauth.twoalex.com/&message=Hello, world, from the test suite again!&name=OAuth Playground:
161
156
  post:
162
157
  with_token: '{"id": "FEED_ITEM_CONTEXT"}'
158
+ link=http://oauth.twoalex.com/&message=body&name=It's a big question&picture=http://oauth.twoalex.com//images/logo.png&properties=<%= {"name"=>"Link1'", "text"=>"Left", "href"=>"http://oauth.twoalex.com/"}.to_s %>=<%= {"name"=>"other", "text"=>"Straight ahead"}.to_s %>&type=link:
159
+ post:
160
+ with_token: '{"id": "FEED_ITEM_CONTEXT"}'
163
161
 
164
162
  /me/photos:
165
163
  source=[FILE]:
@@ -214,29 +212,26 @@ graph_api:
214
212
  with_token: '{"data": [{}], "paging": {}}'
215
213
 
216
214
  /lukeshepard/picture:
217
- type=large:
215
+ no_args:
218
216
  get:
219
217
  no_token:
220
218
  code: 302
221
219
  headers:
222
- Location: https://facebook.com/large
220
+ Location: http://facebook.com/
223
221
  with_token:
224
222
  code: 302
225
223
  headers:
226
- Location: https://facebook.com/large
227
-
228
-
229
- /chris.baclig/picture:
230
- no_args:
224
+ Location: http://facebook.com/
225
+ type=large:
231
226
  get:
232
227
  no_token:
233
228
  code: 302
234
229
  headers:
235
- Location: http://facebook.com/
230
+ Location: https://facebook.com/large
236
231
  with_token:
237
232
  code: 302
238
233
  headers:
239
- Location: http://facebook.com/
234
+ Location: https://facebook.com/large
240
235
 
241
236
  /comments:
242
237
  ids=http://developers.facebook.com/blog/post/472:
@@ -266,6 +261,25 @@ graph_api:
266
261
  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
262
  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"}}'
268
263
 
264
+ /fql:
265
+ q=select uid, first_name from user where uid = 2901279:
266
+ get:
267
+ no_token: '[{"uid":2901279,"first_name":"Luke"}]'
268
+ with_token: '[{"uid":2901279,"first_name":"Luke"}]'
269
+ q=select read_stream from permissions where uid = 2901279:
270
+ get:
271
+ <<: *token_required
272
+ with_token: '[{"read_stream":1}]'
273
+ 'q=<%= MultiJson.encode({"query1" => "select post_id from stream where source_id = me()", "query2" => "select fromid from comment where post_id in (select post_id from #query1)", "query3" => "select uid, name from user where uid in (select fromid from #query2)"}) %>':
274
+ get:
275
+ <<: *token_required
276
+ with_token: '[{"name":"query1", "fql_result_set":[]},{"name":"query2", "fql_result_set":[]},{"name":"query3", "fql_result_set":[]}]'
277
+ 'q=<%= MultiJson.encode({"query1" => "select uid, first_name from user where uid = 2901279", "query2" => "select uid, first_name from user where uid = 2905623"}) %>':
278
+ get:
279
+ with_token: '[{"name":"query1", "fql_result_set":[{"uid":2901279,"first_name":"Luke"}]},{"name":"query2", "fql_result_set":[{"uid":"2905623","first_name":"Alex"}]}]'
280
+ no_token: '[{"name":"query1", "fql_result_set":[{"uid":2901279,"first_name":"Luke"}]},{"name":"query2", "fql_result_set":[{"uid":"2905623","first_name":"Alex"}]}]'
281
+
282
+
269
283
  '/115349521819193_113815981982767':
270
284
  no_args:
271
285
  delete:
@@ -277,6 +291,12 @@ graph_api:
277
291
  <<: *token_required
278
292
  with_token: '{"access_token": "<%= APP_ACCESS_TOKEN %>"}'
279
293
 
294
+
295
+ '/<%= APP_ID %>':
296
+ restrictions=<%= MultiJson.encode({"age_distr" => "13+"}) %>:
297
+ post:
298
+ with_token: "true"
299
+
280
300
  # -- OAuth responses --
281
301
  /oauth/access_token:
282
302
  client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&code=<%= OAUTH_CODE %>&redirect_uri=<%= OAUTH_DATA["callback_url"] %>:
@@ -313,6 +333,10 @@ graph_api:
313
333
  post:
314
334
  with_token:
315
335
  code: 200
336
+ callback_url=<%= SUBSCRIPTION_DATA["subscription_path"] %>&fields=name&object=user:
337
+ post:
338
+ with_token:
339
+ code: 200
316
340
  callback_url=<%= SUBSCRIPTION_DATA["subscription_path"] %>foo&fields=name&object=user&verify_token=<%= SUBSCRIPTION_DATA["verify_token"] %>:
317
341
  post:
318
342
  with_token: '{"error":{"type":"Exception","message":"(#2200) subscription validation failed"}}'
@@ -402,7 +426,7 @@ graph_api:
402
426
  with_token: '{"id": "888888888", "access_token":"<%= ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}'
403
427
  no_args:
404
428
  get:
405
- with_token: '{"data":[{"id": "999999999", "access_token":"<%= ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}, {"id": "888888888", "access_token":"119908831367602|o3wswWQ88LYjEC9-ukR_gjRIOMw.", "login_url":"https://www.facebook.com/platform/test_account.."}]}'
429
+ with_token: '{"data":[{"id": "999999999", "access_token":"<%= ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}, {"id": "888888888", "access_token":"119908831367602|o3wswWQ88LYjEC9-ukR_gjRIOMw.", "login_url":"https://www.facebook.com/platform/test_account.."}], "paging":{"next":"https://graph.facebook.com/119908831367602/accounts/test-users?access_token=119908831367602|o3wswWQ88LYjEC9-ukR_gjRIOMw&limit=50&offset=50&__after_id=100003241848740"}}'
406
430
 
407
431
  /999999999:
408
432
  no_args:
data/spec/spec_helper.rb CHANGED
@@ -21,6 +21,9 @@ end
21
21
  # See https://github.com/tenderlove/psych/issues/8 for more details
22
22
  YAML::ENGINE.yamler = 'syck' if RUBY_VERSION == '1.9.2' && RUBY_PATCHLEVEL < 290
23
23
 
24
+ # load custom RSpec matchers
25
+ require 'support/custom_matchers'
26
+
24
27
  # load the library
25
28
  require 'koala'
26
29
 
@@ -0,0 +1,28 @@
1
+ # Verifies that two URLs are equal, ignoring the order of the query string parameters
2
+ RSpec::Matchers.define :match_url do |url|
3
+ match do |original_url|
4
+ base, query_string = url.split("?")
5
+ original_base, original_query_string = original_url.split("?")
6
+ query_hash = query_to_params(query_string)
7
+ original_query_hash = query_to_params(original_query_string)
8
+
9
+ # the base URLs need to match
10
+ base.should == original_base
11
+
12
+ # the number of parameters should match (avoid one being a subset of the other)
13
+ query_hash.values.length.should == original_query_hash.values.length
14
+
15
+ # and ensure all the keys and values match
16
+ query_hash.each_pair do |key, value|
17
+ original_query_hash[key].should == value
18
+ end
19
+ end
20
+
21
+ def query_to_params(query_string)
22
+ query_string.split("&").inject({}) do |hash, segment|
23
+ k, v = segment.split("=")
24
+ hash[k] = v
25
+ hash
26
+ end
27
+ end
28
+ end