koala 1.1.0 → 1.2.0beta1

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 (50) hide show
  1. data/.travis.yml +2 -1
  2. data/CHANGELOG +26 -0
  3. data/Gemfile +6 -2
  4. data/Rakefile +0 -1
  5. data/koala.gemspec +8 -8
  6. data/lib/koala.rb +42 -45
  7. data/lib/koala/batch_operation.rb +15 -15
  8. data/lib/koala/graph_api.rb +81 -58
  9. data/lib/koala/graph_batch_api.rb +10 -10
  10. data/lib/koala/graph_collection.rb +6 -6
  11. data/lib/koala/http_service.rb +177 -0
  12. data/lib/koala/oauth.rb +2 -2
  13. data/lib/koala/realtime_updates.rb +20 -17
  14. data/lib/koala/rest_api.rb +1 -1
  15. data/lib/koala/test_users.rb +33 -16
  16. data/lib/koala/uploadable_io.rb +47 -42
  17. data/lib/koala/utils.rb +11 -0
  18. data/readme.md +38 -38
  19. data/spec/cases/api_base_spec.rb +2 -2
  20. data/spec/cases/error_spec.rb +32 -0
  21. data/spec/cases/graph_and_rest_api_spec.rb +20 -3
  22. data/spec/cases/graph_api_batch_spec.rb +88 -97
  23. data/spec/cases/graph_api_spec.rb +21 -4
  24. data/spec/cases/http_service_spec.rb +446 -0
  25. data/spec/cases/koala_spec.rb +33 -38
  26. data/spec/cases/oauth_spec.rb +219 -200
  27. data/spec/cases/realtime_updates_spec.rb +45 -31
  28. data/spec/cases/rest_api_spec.rb +23 -7
  29. data/spec/cases/test_users_spec.rb +112 -52
  30. data/spec/cases/uploadable_io_spec.rb +49 -36
  31. data/spec/cases/utils_spec.rb +10 -0
  32. data/spec/fixtures/facebook_data.yml +23 -22
  33. data/spec/fixtures/mock_facebook_responses.yml +126 -96
  34. data/spec/spec_helper.rb +29 -5
  35. data/spec/support/graph_api_shared_examples.rb +59 -52
  36. data/spec/support/json_testing_fix.rb +35 -11
  37. data/spec/support/koala_test.rb +163 -0
  38. data/spec/support/mock_http_service.rb +6 -4
  39. data/spec/support/ordered_hash.rb +205 -0
  40. data/spec/support/rest_api_shared_examples.rb +37 -37
  41. data/spec/support/uploadable_io_shared_examples.rb +2 -8
  42. metadata +78 -79
  43. data/lib/koala/http_services.rb +0 -46
  44. data/lib/koala/http_services/net_http_service.rb +0 -92
  45. data/lib/koala/http_services/typhoeus_service.rb +0 -37
  46. data/spec/cases/http_services/http_service_spec.rb +0 -129
  47. data/spec/cases/http_services/net_http_service_spec.rb +0 -532
  48. data/spec/cases/http_services/typhoeus_service_spec.rb +0 -152
  49. data/spec/support/live_testing_data_helper.rb +0 -40
  50. data/spec/support/setup_mocks_or_live.rb +0 -51
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Koala::Utils do
4
+ it "has a deprecate method" do
5
+ Koala::Utils.should respond_to(:deprecate)
6
+ end
7
+
8
+ # AFAIK there's no way to test that (Kernel.)warn receives the text
9
+ # Kernel.should_receive(:warn) doesn't seem to work, even though the text gets printed
10
+ end
@@ -1,23 +1,24 @@
1
- # Check out http://oauth.twoalex.com/ to easily generate tokens, cookies, etc.
2
- # Those values will work with the default settings in this yaml.
1
+ # Testing data
2
+
3
+ # IMPORTANT NOTE: live tests will run against a test users automatically
4
+ # If you want to run them against a real user or test users on a different account, you can
5
+ # by enter an OAuth token, code, and session_key (for real users) or changing the app_id and secret (for test users)
6
+ # (note for real users: this will leave some photos and videos posted to your wall, since they can't be deleted through the API)
7
+
8
+ # These values are configured to work with the OAuth Playground app by default
3
9
  # Of course, you can change this to work with your own app.
4
- # Just remember to update all fields!
5
-
6
- # You must supply this value yourself to test the GraphAPI class.
7
- # Your OAuth token should have publish_stream, read_stream, and user_photos permissions.
8
- oauth_token:
10
+ # Check out http://oauth.twoalex.com/ to easily generate tokens, cookies, etc.
11
+
12
+ # Your OAuth token should have the read_stream, publish_stream, user_photos, user_videos, and read_insights permissions.
13
+ oauth_token:
9
14
 
10
- # for testing the OAuth class
15
+ # for testing the OAuth class
11
16
  # baseline app
12
- oauth_test_data:
13
- # You must supply this value yourself, since they will expire.
14
- code:
15
- # easiest way to get session keys: use multiple test accounts with the Javascript login at http://oauth.twoalex.com
16
- session_key:
17
- multiple_session_keys:
18
- -
19
- -
20
-
17
+ oauth_test_data:
18
+ # the following two values are not needed for most of the test suite, but the relevant tests will not run if they're not present
19
+ code:
20
+ session_key:
21
+
21
22
  # These values will work out of the box
22
23
  app_id: 119908831367602
23
24
  secret: e45e55a333eec232d4206d2703de1307
@@ -25,13 +26,13 @@ oauth_test_data:
25
26
  app_access_token: 119908831367602|o3wswWQ88LYjEC9-ukR_gjRIOMw.
26
27
  raw_token_string: "access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.&expires=6621"
27
28
  raw_offline_access_token_string: access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.
28
- valid_cookies:
29
+ valid_cookies:
29
30
  # note: the tests stub the time class so these default cookies are always valid (if you're using the default app)
30
31
  # if not you may want to remove the stubbing to test expiration
31
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"'
32
33
  expired_cookies:
33
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"'
34
- offline_access_cookies:
35
+ offline_access_cookies:
35
36
  # note: I've revoked the offline access for security reasons, so you can't make calls against this :)
36
37
  fbs_119908831367602: '"access_token=119908831367602|08170230801eb225068e7a70-2905623|Q3LDCYYF8CX9cstxnZLsxiR0nwg.&expires=0&secret=78abaee300b392e275072a9f2727d436&session_key=08170230801eb225068e7a70-2905623&sig=423b8aa4b6fa1f9a571955f8e929d567&uid=2905623"'
37
38
 
@@ -44,17 +45,17 @@ oauth_test_data:
44
45
  algorithm: HMAC-SHA256
45
46
  user_id: "2905623"
46
47
  oauth_token: 119908831367602|2.zVF_6NrMELHuJa4gIU9tKw__.3600.1301922000-2905623|zgqPsr2BG9LoOK9kekGgRURZx0k
47
- user:
48
+ user:
48
49
  country: de
49
50
  locale: de_DE
50
- age:
51
+ age:
51
52
  min: 21
52
53
  issued_at: 1301917299
53
54
 
54
55
  subscription_test_data:
55
56
  subscription_path: http://oauth.twoalex.com/subscriptions
56
57
  verify_token: "myverificationtoken|1f54545d5f722733e17faae15377928f"
57
- challenge_data:
58
+ challenge_data:
58
59
  "hub.challenge": "1290024882"
59
60
  "hub.verify_token": "myverificationtoken|1f54545d5f722733e17faae15377928f"
60
61
  "hub.mode": "subscribe"
@@ -1,6 +1,6 @@
1
- # Responses by MockHTTPService are taken directly from
1
+ # Responses by MockHTTPService are taken directly from
2
2
  # this file.
3
- #
3
+ #
4
4
  # Structure
5
5
  # ----------
6
6
  #
@@ -10,29 +10,29 @@
10
10
  # with_token:
11
11
  # no_token:
12
12
 
13
- # ====== REST API =====
13
+ # ====== REST API =====
14
14
  rest_api:
15
15
 
16
16
  # -- Stubbed Responses --
17
17
  /method/fql.query:
18
- query=select first_name from user where uid = 216743:
19
- get:
20
- no_token: '[{"first_name":"Chris"}]'
21
- with_token: '[{"first_name":"Chris"}]'
22
- query=select read_stream from permissions where uid = 216743:
18
+ query=select first_name from user where uid = 2901279:
19
+ get:
20
+ no_token: '[{"first_name":"Luke"}]'
21
+ with_token: '[{"first_name":"Luke"}]'
22
+ query=select read_stream from permissions where uid = 2901279:
23
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 = 216743"}]}'
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
26
 
27
27
  /method/fql.multiquery:
28
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:
29
+ get:
30
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 = 216743"}]}'
32
- 'queries=<%= MultiJson.encode({"query1" => "select first_name from user where uid = 216743", "query2" => "select first_name from user where uid = 2905623"}) %>':
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
33
  get:
34
- with_token: '[{"name":"query1", "fql_result_set":[{"first_name":"Chris"}]},{"name":"query2", "fql_result_set":[{"first_name":"Alex"}]}]'
35
- no_token: '[{"name":"query1", "fql_result_set":[{"first_name":"Chris"}]},{"name":"query2", "fql_result_set":[{"first_name":"Alex"}]}]'
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
36
 
37
37
 
38
38
 
@@ -45,7 +45,7 @@ graph_api:
45
45
  # Error responses for when a token is required, but not given
46
46
  token_required_responses: &token_required
47
47
  no_token: '{"error":{"type":"OAuthAccessTokenException", "message":"An access token is required to request this resource."}}'
48
-
48
+
49
49
  # Common mock item responses
50
50
  item_deleted: &item_deleted
51
51
  delete:
@@ -58,22 +58,27 @@ graph_api:
58
58
  # Subscription error response
59
59
  verification_error: &verification_error
60
60
  with_token: '{"error": {"type": "OAuthException", "message": "Error validating verification code."}}'
61
-
62
- test_user_no_perms: &test_user_no_perms
61
+
62
+ test_user_uninstalled: &test_user_uninstalled
63
63
  post:
64
64
  with_token: '{"id": "777777777", "access_token":"<%= APP_ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}'
65
-
65
+
66
+ test_user_installed: &test_user_installed
67
+ post:
68
+ with_token: '{"id": "999999999", "access_token":"<%= ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}'
69
+
66
70
  test_user_befriended: &test_user_befriended
67
71
  post:
68
72
  with_token: 'true'
69
-
73
+
70
74
  # -- Stubbed Responses --
71
75
  root:
72
- ids=contextoptional,naitik:
76
+ ids=contextoptional,koppel:
73
77
  get:
74
- with_token: '{"contextoptional":"{}","naitik":"{}"}'
75
- no_token: '{"contextoptional":"{}","naitik":"{}"}'
76
- # Ruby 1.8.7 and 1.9.2 generate JSON with different key ordering, hence we have to dynamically generate it here
78
+ with_token: '{"contextoptional":"{}","koppel":"{}"}'
79
+ no_token: '{"contextoptional":"{}","koppel":"{}"}'
80
+
81
+ # Ruby 1.8.7 and 1.9.2 generate JSON with different key ordering, hence we have to dynamically generate it here
77
82
  batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me"},{"method" => "get", "relative_url" => "koppel"}]) %>:
78
83
  post:
79
84
  with_token: '[{"body":"{\"id\":\"123\"}"}, {"body":"{\"id\":\"456\"}"}]'
@@ -92,6 +97,17 @@ graph_api:
92
97
  batch=<%= MultiJson.encode([{"method"=>"post", "relative_url"=>"FEED_ITEM_BATCH/likes"}, {"method"=>"delete", "relative_url"=> "FEED_ITEM_BATCH"}]) %>:
93
98
  post:
94
99
  with_token: '[{"body": "{\"id\": \"MOCK_LIKE\"}"},{"body":true}]'
100
+ batch=<%= MultiJson.encode([{"method" => "post", "relative_url" => "method/fql.query", "body" => "query=select+first_name+from+user+where+uid%3D2905623"}]) %>:
101
+ post:
102
+ with_token: '[{"body":"[{\"first_name\":\"Alex\"}]"}]'
103
+
104
+ # dependencies
105
+ batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"me", "name" => "getme"}, {"method"=>"get", "relative_url"=>"koppel", "depends_on" => "getme"}]) %>:
106
+ post:
107
+ with_token: '[null,{"body":"{\"id\":\"123\"}"}]'
108
+ batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"#{OAUTH_DATA["app_id"]}/insights", "name" => "getdata"}, {"method"=>"get", "relative_url"=>"koppel", "depends_on" => "getdata"}]) %>:
109
+ post:
110
+ with_token: '[{"body": "{\"error\":{\"type\":\"AnError\", \"message\":\"An error occurred!.\"}}"},null]'
95
111
  batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me/friends?limit=5", "name" => "get-friends"}, {"method" => "get", "relative_url" => "?ids=#{CGI.escape "{result=get-friends:$.data.*.id}"}"}]) %>:
96
112
  post:
97
113
  with_token: '[null,{"body":"{}"}]'
@@ -101,18 +117,7 @@ graph_api:
101
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}"}"}]) %>:
102
118
  post:
103
119
  with_token: '{"error":190,"error_description":"Error validating access token."}'
104
- batch=<%= MultiJson.encode([{"method" => "post", "relative_url" => "method/fql.query", "body" => "query=select+name+from+user+where+uid%3D4"}]) %>:
105
- post:
106
- with_token: '[{"body":"[{\"name\":\"Mark Zuckerberg\"}]"}]'
107
-
108
- # dependencies
109
- batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"me", "name" => "getme"}, {"method"=>"get", "relative_url"=>"koppel", "depends_on" => "getme"}]) %>:
110
- post: &batch_dependent
111
- with_token: '[null,{"body":"{\"id\":\"123\"}"}]'
112
- batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"#{OAUTH_DATA["app_id"]}/insights", "name" => "getdata"}, {"method"=>"get", "relative_url"=>"koppel", "depends_on" => "getdata"}]) %>:
113
- post:
114
- with_token: '[{"body": "{\"error\":{\"type\":\"AnError\", \"message\":\"An error occurred!.\"}}"},null]'
115
-
120
+
116
121
  # attached files tests
117
122
  batch=<%= MultiJson.encode([{"method"=>"post", "relative_url"=>"me/photos", "attached_files" => "op1_file0"}]) %>&op1_file0=[FILE]:
118
123
  post:
@@ -125,34 +130,37 @@ graph_api:
125
130
  with_token: '[{"body":"{\"id\": \"MOCK_PHOTO\"}"}, {"body":"{\"id\": \"MOCK_PHOTO\"}"}]'
126
131
 
127
132
 
133
+
134
+
128
135
  /me:
129
136
  no_args:
130
137
  get:
131
138
  <<: *token_required
132
139
  with_token: '{"updated_time": 1}'
133
140
  fields=id:
134
- get:
135
- with_token: '{"id": "216743"}'
136
-
141
+ get:
142
+ with_token: '{"id": "2901279"}'
143
+
137
144
  /me/feed:
138
- message=Hello, world, from the test suite!:
139
- post:
145
+ message=Hello, world, from the test suite!:
146
+ post:
140
147
  with_token: '{"id": "MOCK_FEED_ITEM"}'
141
148
  message=Hello, world, from the test suite, testing comments!:
142
149
  post:
143
150
  with_token: '{"id": "MOCK_FEED_ITEM"}'
144
- message=the cats are asleep:
145
- post:
151
+ message=the cats are asleep:
152
+ post:
146
153
  with_token: '{"id": "FEED_ITEM_CATS"}'
147
- message=Hello, world, from the test suite delete method!:
148
- post:
154
+ message=Hello, world, from the test suite delete method!:
155
+ post:
149
156
  with_token: '{"id": "FEED_ITEM_DELETE"}'
150
- message=Hello, world, from the test suite batch API!:
151
- post:
157
+ message=Hello, world, from the test suite batch API!:
158
+ post:
152
159
  with_token: '{"id": "FEED_ITEM_BATCH"}'
153
160
  link=http://oauth.twoalex.com/&message=Hello, world, from the test suite again!&name=OAuth Playground:
154
161
  post:
155
162
  with_token: '{"id": "FEED_ITEM_CONTEXT"}'
163
+
156
164
  /me/photos:
157
165
  source=[FILE]:
158
166
  post:
@@ -162,6 +170,15 @@ graph_api:
162
170
  post:
163
171
  <<: *token_required
164
172
  with_token: '{"id": "MOCK_PHOTO"}'
173
+ url=http://img.slate.com/images/redesign2008/slate_logo.gif:
174
+ post:
175
+ <<: *token_required
176
+ with_token: '{"id": "MOCK_PHOTO_FROM_URL"}'
177
+ message=my message&url=http://img.slate.com/images/redesign2008/slate_logo.gif:
178
+ post:
179
+ <<: *token_required
180
+ with_token: '{"id": "MOCK_PHOTO_FROM_URL"}'
181
+
165
182
  /me/videos:
166
183
  source=[FILE]:
167
184
  post:
@@ -177,25 +194,25 @@ graph_api:
177
194
  get:
178
195
  with_token: '{"id": 1, "name": 1, "updated_time": 1}'
179
196
  no_token: '{"id": 1, "name": 1}'
180
-
197
+
181
198
  /contextoptional:
182
199
  no_args:
183
200
  get:
184
201
  with_token: '{"id": 1, "name": 1}'
185
202
  no_token: '{"id": 1, "name": 1}'
186
-
187
- /contextoptional/photos:
188
- no_args:
189
- get:
203
+
204
+ /contextoptional/photos:
205
+ no_args:
206
+ get:
190
207
  with_token: '{"data": [{}], "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"}}'
191
208
  no_token: '{"data": [{}], "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"}}'
192
-
193
- /lukeshepard/likes:
194
- no_args:
195
- get:
209
+
210
+ /lukeshepard/friends:
211
+ no_args:
212
+ get:
196
213
  <<: *token_required
197
214
  with_token: '{"data": [{}]}'
198
-
215
+
199
216
  /lukeshepard/picture:
200
217
  type=large:
201
218
  get:
@@ -207,8 +224,8 @@ graph_api:
207
224
  code: 302
208
225
  headers:
209
226
  Location: https://facebook.com/large
210
-
211
-
227
+
228
+
212
229
  /chris.baclig/picture:
213
230
  no_args:
214
231
  get:
@@ -223,11 +240,11 @@ graph_api:
223
240
 
224
241
  /comments:
225
242
  ids=http://developers.facebook.com/blog/post/472:
226
- get:
243
+ get:
227
244
  with_token: '{"http://developers.facebook.com/blog/post/472": []}'
228
245
  no_token: '{"http://developers.facebook.com/blog/post/472": []}'
229
246
  ids=http://developers.facebook.com/blog/post/490,http://developers.facebook.com/blog/post/472:
230
- get:
247
+ get:
231
248
  with_token: '{"http://developers.facebook.com/blog/post/490": [], "http://developers.facebook.com/blog/post/472": []}'
232
249
  no_token: '{"http://developers.facebook.com/blog/post/490": [], "http://developers.facebook.com/blog/post/472": []}'
233
250
  ids=:
@@ -237,64 +254,70 @@ graph_api:
237
254
  no_args:
238
255
  get:
239
256
  body: '{"error": {"type": "Exception","message": "No node specified"}}'
240
- code: 500
257
+ code: 500
241
258
 
242
259
  /search:
243
260
  q=facebook:
244
- get:
261
+ get:
245
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"}}'
246
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"}}'
247
264
  "limit=25&q=facebook&until=2010-09-23T21:17:33+0000":
248
- get:
265
+ get:
249
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"}}'
250
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"}}'
251
-
268
+
252
269
  '/115349521819193_113815981982767':
253
270
  no_args:
254
271
  delete:
255
272
  <<: *token_required
256
-
273
+
274
+ /my_page:
275
+ fields=access_token:
276
+ get:
277
+ <<: *token_required
278
+ with_token: '{"access_token": "<%= APP_ACCESS_TOKEN %>"}'
279
+
257
280
  # -- OAuth responses --
258
- /oauth/access_token:
281
+ /oauth/access_token:
259
282
  client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&code=<%= OAUTH_CODE %>&redirect_uri=<%= OAUTH_DATA["callback_url"] %>:
260
283
  get:
261
284
  no_token: access_token=<%= ACCESS_TOKEN %>
262
- client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&code=foo&redirect_uri=<%= OAUTH_DATA["callback_url"] %>:
263
- get:
285
+ client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&code=foo&redirect_uri=<%= OAUTH_DATA["callback_url"] %>:
286
+ get:
264
287
  <<: *oauth_error
265
288
  client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&type=client_cred:
266
289
  post:
267
290
  no_token: access_token=<%= APP_ACCESS_TOKEN %>
268
291
  /oauth/exchange_sessions:
269
- client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= OAUTH_DATA["session_key"] %>&type=client_cred:
292
+ client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= OAUTH_DATA["session_key"] %>&type=client_cred:
270
293
  post:
271
294
  no_token: '[{"access_token":"<%= ACCESS_TOKEN %>","expires":4315}]'
272
- client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= OAUTH_DATA["multiple_session_keys"].join(",") %>&type=client_cred:
295
+ client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= [OAUTH_DATA["session_key"], OAUTH_DATA["session_key"]].join(",") %>&type=client_cred:
273
296
  post:
274
297
  no_token: '[{"access_token":"<%= ACCESS_TOKEN %>","expires":4315}, {"access_token":"<%= ACCESS_TOKEN %>","expires":4315}]'
275
- client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= ["foo"].concat(OAUTH_DATA["multiple_session_keys"]).join(",") %>&type=client_cred:
298
+ client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= ["foo"].concat([OAUTH_DATA["session_key"], OAUTH_DATA["session_key"]]).join(",") %>&type=client_cred:
276
299
  post:
277
300
  no_token: '[null, {"access_token":"<%= ACCESS_TOKEN %>","expires":4315}, {"access_token":"<%= ACCESS_TOKEN %>","expires":4315}]'
278
- client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=foo,bar&type=client_cred:
301
+ client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=foo,bar&type=client_cred:
279
302
  post:
280
303
  no_token: '[null, null]'
281
- client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=foo&type=client_cred:
304
+ client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=foo&type=client_cred:
282
305
  post:
283
306
  no_token: '[null]'
284
307
 
285
308
 
286
309
 
287
- # -- Subscription Responses --
310
+ # -- Subscription Responses --
288
311
  /<%= APP_ID %>/subscriptions:
289
312
  callback_url=<%= SUBSCRIPTION_DATA["subscription_path"] %>&fields=name&object=user&verify_token=<%= SUBSCRIPTION_DATA["verify_token"] %>:
290
- post:
313
+ post:
291
314
  with_token:
292
315
  code: 200
293
316
  callback_url=<%= SUBSCRIPTION_DATA["subscription_path"] %>foo&fields=name&object=user&verify_token=<%= SUBSCRIPTION_DATA["verify_token"] %>:
294
- post:
317
+ post:
295
318
  with_token: '{"error":{"type":"Exception","message":"(#2200) subscription validation failed"}}'
296
319
  callback_url=foo&fields=name&object=user&verify_token=<%= SUBSCRIPTION_DATA["verify_token"] %>:
297
- post:
320
+ post:
298
321
  with_token: '{"error":{"type":"Exception","message":"(#100) callback_url URL is not properly formatted"}}'
299
322
  object=user:
300
323
  delete:
@@ -304,7 +327,7 @@ graph_api:
304
327
  delete:
305
328
  with_token: '{"error":{"type":"Exception","message":"(#100) Invalid parameter"}}'
306
329
  no_args:
307
- delete:
330
+ delete:
308
331
  with_token:
309
332
  code: 200
310
333
  get:
@@ -321,28 +344,28 @@ graph_api:
321
344
  no_args:
322
345
  post:
323
346
  with_token: '{"id": "MOCK_LIKE"}'
324
-
347
+
325
348
  /MOCK_FEED_ITEM/comments:
326
349
  message=it's my comment!:
327
350
  post:
328
351
  with_token: '{"id": "MOCK_COMMENT"}'
329
-
352
+
330
353
  /MOCK_FEED_ITEM:
331
354
  no_args:
332
355
  <<: *item_deleted
333
-
356
+
334
357
  /FEED_ITEM_CONTEXT:
335
- no_args:
358
+ no_args:
336
359
  <<: *item_deleted
337
360
  get:
338
361
  with_token: '{"link":"http://oauth.twoalex.com/", "name": "OAuth Playground"}'
339
-
362
+
340
363
  /FEED_ITEM_CATS:
341
364
  no_args:
342
365
  <<: *item_deleted
343
- get:
366
+ get:
344
367
  with_token: '{"message": "the cats are asleep"}'
345
-
368
+
346
369
  /FEED_ITEM_DELETE:
347
370
  no_args:
348
371
  <<: *item_deleted
@@ -350,9 +373,9 @@ graph_api:
350
373
  /FEED_ITEM_DELETE/likes:
351
374
  no_args:
352
375
  <<: *item_deleted
353
- post:
376
+ post:
354
377
  with_token: 'true'
355
-
378
+
356
379
  /MOCK_COMMENT:
357
380
  no_args:
358
381
  <<: *item_deleted
@@ -363,26 +386,33 @@ graph_api:
363
386
  <<: *item_deleted
364
387
  get:
365
388
  with_token: "{\"name\": \"This is the test message\"}"
366
-
389
+
367
390
  # -- Mock Test User Responses --
368
391
  /<%= APP_ID %>/accounts/test-users:
369
392
  installed=false:
370
- <<: *test_user_no_perms
393
+ <<: *test_user_uninstalled
371
394
  installed=false&permissions=read_stream:
372
- <<: *test_user_no_perms
395
+ <<: *test_user_uninstalled
396
+ installed=true&permissions=:
397
+ <<: *test_user_installed
373
398
  installed=true&permissions=read_stream:
374
- post:
375
- with_token: '{"id": "999999999", "access_token":"<%= ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}'
399
+ <<: *test_user_installed
376
400
  installed=true&permissions=read_stream,user_interests:
377
401
  post:
378
402
  with_token: '{"id": "888888888", "access_token":"<%= ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}'
379
403
  no_args:
380
404
  get:
381
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.."}]}'
382
-
406
+
383
407
  /999999999:
384
408
  no_args:
385
409
  <<: *item_deleted
410
+ get:
411
+ with_token: '{"name":"Foo Baz"}'
412
+ name=Foo Baz:
413
+ post:
414
+ with_token: 'true'
415
+
386
416
 
387
417
  /999999999/friends/888888888:
388
418
  no_args:
@@ -394,10 +424,10 @@ graph_api:
394
424
  no_args:
395
425
  delete:
396
426
  with_token: '{"error": {"type": "OAuthException", "message": "Error validating verification code."}}'
397
-
427
+
398
428
  /888888888:
399
429
  no_args:
400
- <<: *item_deleted
430
+ <<: *item_deleted
401
431
 
402
432
  /888888888/friends/999999999:
403
433
  no_args: