koala 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +12 -0
- data/.gitignore +3 -1
- data/.travis.yml +9 -0
- data/CHANGELOG +62 -2
- data/Gemfile +8 -0
- data/Rakefile +0 -1
- data/autotest/discover.rb +1 -0
- data/koala.gemspec +13 -14
- data/lib/koala/batch_operation.rb +74 -0
- data/lib/koala/graph_api.rb +145 -132
- data/lib/koala/graph_batch_api.rb +97 -0
- data/lib/koala/graph_collection.rb +59 -0
- data/lib/koala/http_service.rb +176 -0
- data/lib/koala/oauth.rb +191 -0
- data/lib/koala/realtime_updates.rb +23 -29
- data/lib/koala/rest_api.rb +13 -8
- data/lib/koala/test_users.rb +33 -17
- data/lib/koala/uploadable_io.rb +153 -87
- data/lib/koala/utils.rb +11 -0
- data/lib/koala/version.rb +3 -0
- data/lib/koala.rb +59 -217
- data/readme.md +92 -53
- data/spec/cases/{api_base_spec.rb → api_spec.rb} +31 -6
- data/spec/cases/error_spec.rb +32 -0
- data/spec/cases/graph_and_rest_api_spec.rb +12 -21
- data/spec/cases/graph_api_batch_spec.rb +582 -0
- data/spec/cases/graph_api_spec.rb +11 -14
- data/spec/cases/graph_collection_spec.rb +116 -0
- data/spec/cases/http_service_spec.rb +446 -0
- data/spec/cases/koala_spec.rb +54 -0
- data/spec/cases/oauth_spec.rb +319 -213
- data/spec/cases/realtime_updates_spec.rb +45 -31
- data/spec/cases/rest_api_spec.rb +23 -7
- data/spec/cases/test_users_spec.rb +123 -75
- data/spec/cases/uploadable_io_spec.rb +120 -37
- data/spec/cases/utils_spec.rb +10 -0
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/facebook_data.yml +26 -24
- data/spec/fixtures/mock_facebook_responses.yml +203 -78
- data/spec/spec_helper.rb +30 -5
- data/spec/support/graph_api_shared_examples.rb +149 -118
- data/spec/support/json_testing_fix.rb +42 -0
- data/spec/support/koala_test.rb +187 -0
- data/spec/support/mock_http_service.rb +62 -58
- data/spec/support/ordered_hash.rb +205 -0
- data/spec/support/rest_api_shared_examples.rb +139 -15
- data/spec/support/uploadable_io_shared_examples.rb +2 -8
- metadata +90 -114
- data/lib/koala/http_services.rb +0 -146
- data/spec/cases/http_services/http_service_spec.rb +0 -54
- data/spec/cases/http_services/net_http_service_spec.rb +0 -350
- data/spec/cases/http_services/typhoeus_service_spec.rb +0 -144
- data/spec/support/live_testing_data_helper.rb +0 -40
- data/spec/support/setup_mocks_or_live.rb +0 -52
|
@@ -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,19 +10,31 @@
|
|
|
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 =
|
|
19
|
-
get:
|
|
20
|
-
no_token: '[{"first_name":"
|
|
21
|
-
with_token: '[{"first_name":"
|
|
22
|
-
query=select read_stream from permissions where uid =
|
|
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
|
+
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)"}) %>':
|
|
23
29
|
get:
|
|
24
|
-
with_token: '[{"
|
|
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 =
|
|
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
40
|
# ====== GRAPH API =====
|
|
@@ -33,7 +45,7 @@ graph_api:
|
|
|
33
45
|
# Error responses for when a token is required, but not given
|
|
34
46
|
token_required_responses: &token_required
|
|
35
47
|
no_token: '{"error":{"type":"OAuthAccessTokenException", "message":"An access token is required to request this resource."}}'
|
|
36
|
-
|
|
48
|
+
|
|
37
49
|
# Common mock item responses
|
|
38
50
|
item_deleted: &item_deleted
|
|
39
51
|
delete:
|
|
@@ -46,46 +58,109 @@ graph_api:
|
|
|
46
58
|
# Subscription error response
|
|
47
59
|
verification_error: &verification_error
|
|
48
60
|
with_token: '{"error": {"type": "OAuthException", "message": "Error validating verification code."}}'
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
|
|
62
|
+
test_user_uninstalled: &test_user_uninstalled
|
|
63
|
+
post:
|
|
64
|
+
with_token: '{"id": "777777777", "access_token":"<%= APP_ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}'
|
|
65
|
+
|
|
66
|
+
test_user_installed: &test_user_installed
|
|
51
67
|
post:
|
|
52
|
-
with_token: '{"id": "
|
|
53
|
-
|
|
68
|
+
with_token: '{"id": "999999999", "access_token":"<%= ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}'
|
|
69
|
+
|
|
54
70
|
test_user_befriended: &test_user_befriended
|
|
55
71
|
post:
|
|
56
72
|
with_token: 'true'
|
|
57
|
-
|
|
73
|
+
|
|
58
74
|
# -- Stubbed Responses --
|
|
59
75
|
root:
|
|
60
|
-
ids=contextoptional,
|
|
76
|
+
ids=contextoptional,koppel:
|
|
61
77
|
get:
|
|
62
|
-
with_token: '
|
|
63
|
-
no_token: '
|
|
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
|
|
82
|
+
batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me"},{"method" => "get", "relative_url" => "koppel"}]) %>:
|
|
83
|
+
post:
|
|
84
|
+
with_token: '[{"body":"{\"id\":\"123\"}"}, {"body":"{\"id\":\"456\"}"}]'
|
|
85
|
+
batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me/picture"}]) %>:
|
|
86
|
+
post:
|
|
87
|
+
with_token: '[{"headers":[{"name":"Location","value":"http://google.com"}]}]'
|
|
88
|
+
batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me"},{"method" => "get", "relative_url" => "me/friends"}]) %>:
|
|
89
|
+
post:
|
|
90
|
+
with_token: '[{"body":"{\"id\":\"123\"}"}, {"body":"{\"data\":[],\"paging\":{}}"}]'
|
|
91
|
+
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"me"}, {"method"=>"get", "relative_url"=>"#{OAUTH_DATA["app_id"]}/insights?access_token=#{CGI.escape APP_ACCESS_TOKEN}"}]) %>:
|
|
92
|
+
post:
|
|
93
|
+
with_token: '[{"body":"{\"id\":\"123\"}"}, {"body":"{\"data\":[],\"paging\":{}}"}]'
|
|
94
|
+
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"#{OAUTH_DATA["app_id"]}/insights"}, {"method"=>"get", "relative_url"=>"koppel?access_token=#{CGI.escape APP_ACCESS_TOKEN}"}]) %>:
|
|
95
|
+
post:
|
|
96
|
+
with_token: '[{"body": "{\"error\":{\"type\":\"AnError\", \"message\":\"An error occurred!.\"}}"},{"body":"{\"id\":\"123\"}"}]'
|
|
97
|
+
batch=<%= MultiJson.encode([{"method"=>"post", "relative_url"=>"FEED_ITEM_BATCH/likes"}, {"method"=>"delete", "relative_url"=> "FEED_ITEM_BATCH"}]) %>:
|
|
98
|
+
post:
|
|
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]'
|
|
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}"}"}]) %>:
|
|
112
|
+
post:
|
|
113
|
+
with_token: '[null,{"body":"{}"}]'
|
|
114
|
+
batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me/friends?limit=5", "name" => "get-friends", "omit_response_on_success" => false}, {"method" => "get", "relative_url" => "?ids=#{CGI.escape "{result=get-friends:$.data.*.id}"}"}]) %>:
|
|
115
|
+
post:
|
|
116
|
+
with_token: '[{"body":"{\"data\":[],\"paging\":{}}"},{"body":"{}"}]'
|
|
117
|
+
batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me/friends?limit=5"}, {"method" => "get", "relative_url" => "?ids=#{CGI.escape "{result=i-dont-exist:$.data.*.id}"}"}]) %>:
|
|
118
|
+
post:
|
|
119
|
+
with_token: '{"error":190,"error_description":"Error validating access token."}'
|
|
120
|
+
|
|
121
|
+
# attached files tests
|
|
122
|
+
batch=<%= MultiJson.encode([{"method"=>"post", "relative_url"=>"me/photos", "attached_files" => "op1_file0"}]) %>&op1_file0=[FILE]:
|
|
123
|
+
post:
|
|
124
|
+
with_token: '[{"body": "{\"error\":{\"type\":\"AnError\", \"message\":\"An error occurred!.\"}}"},null]'
|
|
125
|
+
batch=<%= MultiJson.encode([{"method"=>"post", "relative_url"=>"me/photos", "attached_files" => "op1_file0"}]) %>&op1_file0=[FILE]:
|
|
126
|
+
post:
|
|
127
|
+
with_token: '[{"body":"{\"id\": \"MOCK_PHOTO\"}"}]'
|
|
128
|
+
batch=<%= MultiJson.encode([{"method"=>"post", "relative_url"=>"me/photos", "attached_files" => "op1_file0"}, {"method"=>"post", "relative_url"=>"koppel/photos", "attached_files" => "op2_file0"}]) %>&op1_file0=[FILE]&op2_file0=[FILE]:
|
|
129
|
+
post:
|
|
130
|
+
with_token: '[{"body":"{\"id\": \"MOCK_PHOTO\"}"}, {"body":"{\"id\": \"MOCK_PHOTO\"}"}]'
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
64
135
|
/me:
|
|
65
136
|
no_args:
|
|
66
137
|
get:
|
|
67
138
|
<<: *token_required
|
|
68
139
|
with_token: '{"updated_time": 1}'
|
|
69
140
|
fields=id:
|
|
70
|
-
get:
|
|
71
|
-
with_token: '{"id": "
|
|
72
|
-
|
|
141
|
+
get:
|
|
142
|
+
with_token: '{"id": "2901279"}'
|
|
143
|
+
|
|
73
144
|
/me/feed:
|
|
74
|
-
message=Hello, world, from the test suite!:
|
|
75
|
-
post:
|
|
145
|
+
message=Hello, world, from the test suite!:
|
|
146
|
+
post:
|
|
76
147
|
with_token: '{"id": "MOCK_FEED_ITEM"}'
|
|
77
148
|
message=Hello, world, from the test suite, testing comments!:
|
|
78
149
|
post:
|
|
79
150
|
with_token: '{"id": "MOCK_FEED_ITEM"}'
|
|
80
|
-
message=the cats are asleep:
|
|
81
|
-
post:
|
|
151
|
+
message=the cats are asleep:
|
|
152
|
+
post:
|
|
82
153
|
with_token: '{"id": "FEED_ITEM_CATS"}'
|
|
83
|
-
message=Hello, world, from the test suite delete method!:
|
|
84
|
-
post:
|
|
154
|
+
message=Hello, world, from the test suite delete method!:
|
|
155
|
+
post:
|
|
85
156
|
with_token: '{"id": "FEED_ITEM_DELETE"}'
|
|
157
|
+
message=Hello, world, from the test suite batch API!:
|
|
158
|
+
post:
|
|
159
|
+
with_token: '{"id": "FEED_ITEM_BATCH"}'
|
|
86
160
|
link=http://oauth.twoalex.com/&message=Hello, world, from the test suite again!&name=OAuth Playground:
|
|
87
161
|
post:
|
|
88
162
|
with_token: '{"id": "FEED_ITEM_CONTEXT"}'
|
|
163
|
+
|
|
89
164
|
/me/photos:
|
|
90
165
|
source=[FILE]:
|
|
91
166
|
post:
|
|
@@ -95,30 +170,49 @@ graph_api:
|
|
|
95
170
|
post:
|
|
96
171
|
<<: *token_required
|
|
97
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
|
+
|
|
182
|
+
/me/videos:
|
|
183
|
+
source=[FILE]:
|
|
184
|
+
post:
|
|
185
|
+
<<: *token_required
|
|
186
|
+
with_token: '{"id": "MOCK_PHOTO"}'
|
|
187
|
+
message=This is the test message&source=[FILE]:
|
|
188
|
+
post:
|
|
189
|
+
<<: *token_required
|
|
190
|
+
with_token: '{"id": "MOCK_PHOTO"}'
|
|
191
|
+
|
|
98
192
|
/koppel:
|
|
99
193
|
no_args:
|
|
100
194
|
get:
|
|
101
195
|
with_token: '{"id": 1, "name": 1, "updated_time": 1}'
|
|
102
196
|
no_token: '{"id": 1, "name": 1}'
|
|
103
|
-
|
|
197
|
+
|
|
104
198
|
/contextoptional:
|
|
105
199
|
no_args:
|
|
106
200
|
get:
|
|
107
201
|
with_token: '{"id": 1, "name": 1}'
|
|
108
202
|
no_token: '{"id": 1, "name": 1}'
|
|
109
|
-
|
|
110
|
-
/contextoptional/photos:
|
|
111
|
-
no_args:
|
|
112
|
-
get:
|
|
203
|
+
|
|
204
|
+
/contextoptional/photos:
|
|
205
|
+
no_args:
|
|
206
|
+
get:
|
|
113
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"}}'
|
|
114
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"}}'
|
|
115
|
-
|
|
116
|
-
/lukeshepard/
|
|
117
|
-
no_args:
|
|
118
|
-
get:
|
|
209
|
+
|
|
210
|
+
/lukeshepard/friends:
|
|
211
|
+
no_args:
|
|
212
|
+
get:
|
|
119
213
|
<<: *token_required
|
|
120
|
-
with_token: '{"data": [{}]}'
|
|
121
|
-
|
|
214
|
+
with_token: '{"data": [{}], "paging": {}}'
|
|
215
|
+
|
|
122
216
|
/lukeshepard/picture:
|
|
123
217
|
type=large:
|
|
124
218
|
get:
|
|
@@ -130,8 +224,8 @@ graph_api:
|
|
|
130
224
|
code: 302
|
|
131
225
|
headers:
|
|
132
226
|
Location: https://facebook.com/large
|
|
133
|
-
|
|
134
|
-
|
|
227
|
+
|
|
228
|
+
|
|
135
229
|
/chris.baclig/picture:
|
|
136
230
|
no_args:
|
|
137
231
|
get:
|
|
@@ -144,62 +238,86 @@ graph_api:
|
|
|
144
238
|
headers:
|
|
145
239
|
Location: http://facebook.com/
|
|
146
240
|
|
|
241
|
+
/comments:
|
|
242
|
+
ids=http://developers.facebook.com/blog/post/472:
|
|
243
|
+
get:
|
|
244
|
+
with_token: '{"http://developers.facebook.com/blog/post/472": []}'
|
|
245
|
+
no_token: '{"http://developers.facebook.com/blog/post/472": []}'
|
|
246
|
+
ids=http://developers.facebook.com/blog/post/490,http://developers.facebook.com/blog/post/472:
|
|
247
|
+
get:
|
|
248
|
+
with_token: '{"http://developers.facebook.com/blog/post/490": [], "http://developers.facebook.com/blog/post/472": []}'
|
|
249
|
+
no_token: '{"http://developers.facebook.com/blog/post/490": [], "http://developers.facebook.com/blog/post/472": []}'
|
|
250
|
+
ids=:
|
|
251
|
+
get:
|
|
252
|
+
body: '{"error": {"type": "OAuthException","message": "Cannot specify an empty identifier"}}'
|
|
253
|
+
code: 400
|
|
254
|
+
no_args:
|
|
255
|
+
get:
|
|
256
|
+
body: '{"error": {"type": "Exception","message": "No node specified"}}'
|
|
257
|
+
code: 500
|
|
258
|
+
|
|
147
259
|
/search:
|
|
148
260
|
q=facebook:
|
|
149
|
-
get:
|
|
261
|
+
get:
|
|
150
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"}}'
|
|
151
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"}}'
|
|
152
|
-
"limit=25&q=facebook&until
|
|
153
|
-
get:
|
|
264
|
+
"limit=25&q=facebook&until=<%= TEST_DATA['search_time'] %>":
|
|
265
|
+
get:
|
|
154
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"}}'
|
|
155
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"}}'
|
|
156
|
-
|
|
268
|
+
|
|
157
269
|
'/115349521819193_113815981982767':
|
|
158
270
|
no_args:
|
|
159
271
|
delete:
|
|
160
272
|
<<: *token_required
|
|
161
|
-
|
|
273
|
+
|
|
274
|
+
/my_page:
|
|
275
|
+
fields=access_token:
|
|
276
|
+
get:
|
|
277
|
+
<<: *token_required
|
|
278
|
+
with_token: '{"access_token": "<%= APP_ACCESS_TOKEN %>"}'
|
|
279
|
+
|
|
162
280
|
# -- OAuth responses --
|
|
163
|
-
/oauth/access_token:
|
|
281
|
+
/oauth/access_token:
|
|
164
282
|
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&code=<%= OAUTH_CODE %>&redirect_uri=<%= OAUTH_DATA["callback_url"] %>:
|
|
165
283
|
get:
|
|
166
284
|
no_token: access_token=<%= ACCESS_TOKEN %>
|
|
167
|
-
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&code=foo&redirect_uri=<%= OAUTH_DATA["callback_url"] %>:
|
|
168
|
-
get:
|
|
285
|
+
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&code=foo&redirect_uri=<%= OAUTH_DATA["callback_url"] %>:
|
|
286
|
+
get:
|
|
169
287
|
<<: *oauth_error
|
|
170
288
|
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&type=client_cred:
|
|
171
289
|
post:
|
|
172
|
-
no_token: access_token=<%=
|
|
290
|
+
no_token: access_token=<%= APP_ACCESS_TOKEN %>
|
|
173
291
|
/oauth/exchange_sessions:
|
|
174
|
-
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:
|
|
175
293
|
post:
|
|
176
294
|
no_token: '[{"access_token":"<%= ACCESS_TOKEN %>","expires":4315}]'
|
|
177
|
-
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= OAUTH_DATA["
|
|
295
|
+
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= [OAUTH_DATA["session_key"], OAUTH_DATA["session_key"]].join(",") %>&type=client_cred:
|
|
178
296
|
post:
|
|
179
297
|
no_token: '[{"access_token":"<%= ACCESS_TOKEN %>","expires":4315}, {"access_token":"<%= ACCESS_TOKEN %>","expires":4315}]'
|
|
180
|
-
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= ["foo"].concat(OAUTH_DATA["
|
|
298
|
+
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= ["foo"].concat([OAUTH_DATA["session_key"], OAUTH_DATA["session_key"]]).join(",") %>&type=client_cred:
|
|
181
299
|
post:
|
|
182
300
|
no_token: '[null, {"access_token":"<%= ACCESS_TOKEN %>","expires":4315}, {"access_token":"<%= ACCESS_TOKEN %>","expires":4315}]'
|
|
183
|
-
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:
|
|
184
302
|
post:
|
|
185
303
|
no_token: '[null, null]'
|
|
186
|
-
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:
|
|
187
305
|
post:
|
|
188
306
|
no_token: '[null]'
|
|
189
307
|
|
|
190
308
|
|
|
191
309
|
|
|
192
|
-
# -- Subscription Responses --
|
|
310
|
+
# -- Subscription Responses --
|
|
193
311
|
/<%= APP_ID %>/subscriptions:
|
|
194
312
|
callback_url=<%= SUBSCRIPTION_DATA["subscription_path"] %>&fields=name&object=user&verify_token=<%= SUBSCRIPTION_DATA["verify_token"] %>:
|
|
195
|
-
post:
|
|
313
|
+
post:
|
|
196
314
|
with_token:
|
|
197
315
|
code: 200
|
|
198
316
|
callback_url=<%= SUBSCRIPTION_DATA["subscription_path"] %>foo&fields=name&object=user&verify_token=<%= SUBSCRIPTION_DATA["verify_token"] %>:
|
|
199
|
-
post:
|
|
317
|
+
post:
|
|
200
318
|
with_token: '{"error":{"type":"Exception","message":"(#2200) subscription validation failed"}}'
|
|
201
319
|
callback_url=foo&fields=name&object=user&verify_token=<%= SUBSCRIPTION_DATA["verify_token"] %>:
|
|
202
|
-
post:
|
|
320
|
+
post:
|
|
203
321
|
with_token: '{"error":{"type":"Exception","message":"(#100) callback_url URL is not properly formatted"}}'
|
|
204
322
|
object=user:
|
|
205
323
|
delete:
|
|
@@ -209,7 +327,7 @@ graph_api:
|
|
|
209
327
|
delete:
|
|
210
328
|
with_token: '{"error":{"type":"Exception","message":"(#100) Invalid parameter"}}'
|
|
211
329
|
no_args:
|
|
212
|
-
delete:
|
|
330
|
+
delete:
|
|
213
331
|
with_token:
|
|
214
332
|
code: 200
|
|
215
333
|
get:
|
|
@@ -226,28 +344,28 @@ graph_api:
|
|
|
226
344
|
no_args:
|
|
227
345
|
post:
|
|
228
346
|
with_token: '{"id": "MOCK_LIKE"}'
|
|
229
|
-
|
|
347
|
+
|
|
230
348
|
/MOCK_FEED_ITEM/comments:
|
|
231
349
|
message=it's my comment!:
|
|
232
350
|
post:
|
|
233
351
|
with_token: '{"id": "MOCK_COMMENT"}'
|
|
234
|
-
|
|
352
|
+
|
|
235
353
|
/MOCK_FEED_ITEM:
|
|
236
354
|
no_args:
|
|
237
355
|
<<: *item_deleted
|
|
238
|
-
|
|
356
|
+
|
|
239
357
|
/FEED_ITEM_CONTEXT:
|
|
240
|
-
no_args:
|
|
358
|
+
no_args:
|
|
241
359
|
<<: *item_deleted
|
|
242
360
|
get:
|
|
243
361
|
with_token: '{"link":"http://oauth.twoalex.com/", "name": "OAuth Playground"}'
|
|
244
|
-
|
|
362
|
+
|
|
245
363
|
/FEED_ITEM_CATS:
|
|
246
364
|
no_args:
|
|
247
365
|
<<: *item_deleted
|
|
248
|
-
get:
|
|
366
|
+
get:
|
|
249
367
|
with_token: '{"message": "the cats are asleep"}'
|
|
250
|
-
|
|
368
|
+
|
|
251
369
|
/FEED_ITEM_DELETE:
|
|
252
370
|
no_args:
|
|
253
371
|
<<: *item_deleted
|
|
@@ -255,9 +373,9 @@ graph_api:
|
|
|
255
373
|
/FEED_ITEM_DELETE/likes:
|
|
256
374
|
no_args:
|
|
257
375
|
<<: *item_deleted
|
|
258
|
-
post:
|
|
376
|
+
post:
|
|
259
377
|
with_token: 'true'
|
|
260
|
-
|
|
378
|
+
|
|
261
379
|
/MOCK_COMMENT:
|
|
262
380
|
no_args:
|
|
263
381
|
<<: *item_deleted
|
|
@@ -268,26 +386,33 @@ graph_api:
|
|
|
268
386
|
<<: *item_deleted
|
|
269
387
|
get:
|
|
270
388
|
with_token: "{\"name\": \"This is the test message\"}"
|
|
271
|
-
|
|
389
|
+
|
|
272
390
|
# -- Mock Test User Responses --
|
|
273
391
|
/<%= APP_ID %>/accounts/test-users:
|
|
274
392
|
installed=false:
|
|
275
|
-
<<: *
|
|
393
|
+
<<: *test_user_uninstalled
|
|
276
394
|
installed=false&permissions=read_stream:
|
|
277
|
-
<<: *
|
|
395
|
+
<<: *test_user_uninstalled
|
|
396
|
+
installed=true&permissions=:
|
|
397
|
+
<<: *test_user_installed
|
|
278
398
|
installed=true&permissions=read_stream:
|
|
279
|
-
|
|
280
|
-
with_token: '{"id": "999999999", "access_token":"<%= ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}'
|
|
399
|
+
<<: *test_user_installed
|
|
281
400
|
installed=true&permissions=read_stream,user_interests:
|
|
282
401
|
post:
|
|
283
402
|
with_token: '{"id": "888888888", "access_token":"<%= ACCESS_TOKEN %>", "login_url":"https://www.facebook.com/platform/test_account.."}'
|
|
284
403
|
no_args:
|
|
285
404
|
get:
|
|
286
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.."}]}'
|
|
287
|
-
|
|
406
|
+
|
|
288
407
|
/999999999:
|
|
289
408
|
no_args:
|
|
290
409
|
<<: *item_deleted
|
|
410
|
+
get:
|
|
411
|
+
with_token: '{"name":"Foo Baz"}'
|
|
412
|
+
name=Foo Baz:
|
|
413
|
+
post:
|
|
414
|
+
with_token: 'true'
|
|
415
|
+
|
|
291
416
|
|
|
292
417
|
/999999999/friends/888888888:
|
|
293
418
|
no_args:
|
|
@@ -299,10 +424,10 @@ graph_api:
|
|
|
299
424
|
no_args:
|
|
300
425
|
delete:
|
|
301
426
|
with_token: '{"error": {"type": "OAuthException", "message": "Error validating verification code."}}'
|
|
302
|
-
|
|
427
|
+
|
|
303
428
|
/888888888:
|
|
304
429
|
no_args:
|
|
305
|
-
<<: *item_deleted
|
|
430
|
+
<<: *item_deleted
|
|
306
431
|
|
|
307
432
|
/888888888/friends/999999999:
|
|
308
433
|
no_args:
|
|
@@ -311,4 +436,4 @@ graph_api:
|
|
|
311
436
|
|
|
312
437
|
/777777777:
|
|
313
438
|
no_args:
|
|
314
|
-
<<: *item_deleted
|
|
439
|
+
<<: *item_deleted
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,18 +1,43 @@
|
|
|
1
1
|
begin
|
|
2
2
|
require 'bundler/setup'
|
|
3
3
|
rescue LoadError
|
|
4
|
-
puts '
|
|
4
|
+
puts 'Although not required, bundler is recommended for running the tests.'
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
#
|
|
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
|
|
8
25
|
require 'koala'
|
|
9
26
|
|
|
10
|
-
#
|
|
11
|
-
|
|
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
|
|
12
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
|
|
13
39
|
require 'support/rest_api_shared_examples'
|
|
14
40
|
require 'support/graph_api_shared_examples'
|
|
15
41
|
require 'support/uploadable_io_shared_examples'
|
|
16
|
-
require 'support/setup_mocks_or_live'
|
|
17
42
|
|
|
18
43
|
BEACH_BALL_PATH = File.join(File.dirname(__FILE__), "fixtures", "beach.jpg")
|