koala 1.2.1 → 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 (55) 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 +28 -0
  6. data/Gemfile +14 -0
  7. data/Guardfile +6 -0
  8. data/koala.gemspec +3 -3
  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} +34 -13
  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 +69 -20
  20. data/lib/koala/oauth.rb +170 -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 -96
  26. data/readme.md +9 -9
  27. data/spec/cases/api_spec.rb +19 -12
  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 +5 -26
  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 +7 -7
  35. data/spec/cases/oauth_spec.rb +134 -48
  36. data/spec/cases/realtime_updates_spec.rb +154 -47
  37. data/spec/cases/test_users_spec.rb +276 -219
  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 +41 -30
  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 +192 -14
  44. data/spec/support/koala_test.rb +10 -1
  45. data/spec/support/mock_http_service.rb +2 -2
  46. data/spec/support/rest_api_shared_examples.rb +5 -165
  47. metadata +75 -99
  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/multipart_request.rb +0 -35
  52. data/lib/koala/uploadable_io.rb +0 -181
  53. data/spec/cases/graph_and_rest_api_spec.rb +0 -22
  54. data/spec/cases/graph_api_spec.rb +0 -22
  55. data/spec/cases/rest_api_spec.rb +0 -22
@@ -24,33 +24,37 @@ describe "Koala::Facebook::RealtimeUpdates" do
24
24
  end
25
25
  end
26
26
 
27
- describe "when initializing" do
27
+ before :each do
28
+ @updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
29
+ end
30
+
31
+ describe ".new" do
28
32
  # basic initialization
29
- it "should initialize properly with an app_id and an app_access_token" do
33
+ it "initializes properly with an app_id and an app_access_token" do
30
34
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
31
35
  updates.should be_a(Koala::Facebook::RealtimeUpdates)
32
36
  end
33
37
 
34
38
  # attributes
35
- it "should allow read access to app_id" do
39
+ it "allows read access to app_id" do
36
40
  # in Ruby 1.9, .method returns symbols
37
41
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:app_id)
38
42
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:app_id=)
39
43
  end
40
44
 
41
- it "should allow read access to app_access_token" do
45
+ it "allows read access to app_access_token" do
42
46
  # in Ruby 1.9, .method returns symbols
43
47
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:app_access_token)
44
48
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:app_access_token=)
45
49
  end
46
50
 
47
- it "should allow read access to secret" do
51
+ it "allows read access to secret" do
48
52
  # in Ruby 1.9, .method returns symbols
49
53
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:secret)
50
54
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:secret=)
51
55
  end
52
56
 
53
- it "should allow read access to api" do
57
+ it "allows read access to api" do
54
58
  # in Ruby 1.9, .method returns symbols
55
59
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:api)
56
60
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:api=)
@@ -69,72 +73,178 @@ describe "Koala::Facebook::RealtimeUpdates" do
69
73
  end
70
74
 
71
75
  # init with secret / fetching the token
72
- it "should initialize properly with an app_id and a secret" do
76
+ it "initializes properly with an app_id and a secret" do
73
77
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
74
78
  updates.should be_a(Koala::Facebook::RealtimeUpdates)
75
79
  end
76
80
 
77
- it "should fetch an app_token from Facebook when provided an app_id and a secret" do
81
+ it "fetches an app_token from Facebook when provided an app_id and a secret" do
78
82
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
79
83
  updates.app_access_token.should_not be_nil
80
84
  end
81
-
82
- it "should use the OAuth class to fetch a token when provided an app_id and a secret" do
85
+
86
+ it "uses the OAuth class to fetch a token when provided an app_id and a secret" do
83
87
  oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
84
88
  token = oauth.get_app_access_token
85
89
  oauth.should_receive(:get_app_access_token).and_return(token)
86
90
  Koala::Facebook::OAuth.should_receive(:new).with(@app_id, @secret).and_return(oauth)
87
91
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
88
92
  end
93
+
94
+ it "sets up the with the app acces token" do
95
+ updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
96
+ updates.api.should be_a(Koala::Facebook::API)
97
+ updates.api.access_token.should == @app_access_token
98
+ end
99
+
89
100
  end
90
101
 
91
- describe "when used" do
92
- before :each do
93
- @updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
102
+ describe "#subscribe" do
103
+ it "makes a POST to the subscription path" do
104
+ @updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "post", anything)
105
+ @updates.subscribe("user", "name", @subscription_path, @verify_token)
106
+ end
107
+
108
+ it "properly formats the subscription request" do
109
+ obj = "user"
110
+ fields = "name"
111
+ @updates.api.should_receive(:graph_call).with(anything, hash_including(
112
+ :object => obj,
113
+ :fields => fields,
114
+ :callback_url => @subscription_path,
115
+ :verify_token => @verify_token
116
+ ), anything, anything)
117
+ @updates.subscribe("user", "name", @subscription_path, @verify_token)
118
+ end
119
+
120
+ pending "doesn't require a verify_token" do
121
+ # see https://github.com/arsduo/koala/issues/150
122
+ obj = "user"
123
+ fields = "name"
124
+ @updates.api.should_not_receive(:graph_call).with(anything, hash_including(:verify_token => anything), anything, anything)
125
+ @updates.subscribe("user", "name", @subscription_path)
126
+ end
127
+
128
+ it "requires verify_token" do
129
+ expect { @updates.subscribe("user", "name", @subscription_path) }.to raise_exception
94
130
  end
95
131
 
96
- it "should send a subscription request to a valid server" do
97
- result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
98
- result.should be_true
132
+ it "requests the status component" do
133
+ @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
134
+ @updates.subscribe("user", "name", @subscription_path, @verify_token)
99
135
  end
100
136
 
101
- it "should send a subscription request to a valid server" do
102
- result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
103
- result.should be_true
137
+ it "accepts an options hash" do
138
+ options = {:a => 2, :b => "c"}
139
+ @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
140
+ @updates.subscribe("user", "name", @subscription_path, @verify_token, options)
104
141
  end
105
142
 
106
- it "should send a subscription request to an invalid path on a valid server" do
107
- lambda { result = @updates.subscribe("user", "name", @subscription_path + "foo", @verify_token) }.should raise_exception(Koala::Facebook::APIError)
143
+ it "overrides any provided http_component" do
144
+ # since we test against status, we need to ensure that we get that
145
+ options = {:http_component => :body}
146
+ @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
147
+ @updates.subscribe("user", "name", @subscription_path, @verify_token, options)
108
148
  end
149
+
150
+ describe "in practice" do
151
+ it "sends a subscription request" do
152
+ result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
153
+ result.should be_true
154
+ end
109
155
 
110
- it "should fail to send a subscription request to an invalid server" do
111
- lambda { @updates.subscribe("user", "name", "foo", @verify_token) }.should raise_exception(Koala::Facebook::APIError)
156
+ pending "sends a subscription request without a verify token" do
157
+ result = @updates.subscribe("user", "name", @subscription_path)
158
+ result.should be_true
159
+ end
160
+
161
+ it "fails if you try to hit an invalid path on your valid server" do
162
+ expect { result = @updates.subscribe("user", "name", @subscription_path + "foo", @verify_token) }.to raise_exception(Koala::Facebook::APIError)
163
+ end
164
+
165
+ it "fails to send a subscription request to an invalid server" do
166
+ expect { @updates.subscribe("user", "name", "foo", @verify_token) }.to raise_exception(Koala::Facebook::APIError)
167
+ end
112
168
  end
169
+ end
113
170
 
114
- it "should unsubscribe a valid individual object successfully" do
115
- @updates.unsubscribe("user").should be_true
171
+ describe "#unsubscribe" do
172
+ it "makes a DELETE to the subscription path" do
173
+ @updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "delete", anything)
174
+ @updates.unsubscribe("user")
116
175
  end
117
176
 
118
- it "should unsubscribe all subscriptions successfully" do
119
- @updates.unsubscribe.should be_true
177
+ it "includes the object if provided" do
178
+ obj = "user"
179
+ @updates.api.should_receive(:graph_call).with(anything, hash_including(:object => obj), anything, anything)
180
+ @updates.unsubscribe(obj)
120
181
  end
182
+
183
+ it "requests the status component" do
184
+ @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
185
+ @updates.unsubscribe("user")
186
+ end
187
+
188
+ it "accepts an options hash" do
189
+ options = {:a => 2, :b => "C"}
190
+ @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
191
+ @updates.unsubscribe("user", options)
192
+ end
193
+
194
+ it "overrides any provided http_component" do
195
+ # since we test against status, we need to ensure that we get that
196
+ options = {:http_component => :body}
197
+ @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
198
+ @updates.unsubscribe("user", options)
199
+ end
200
+
201
+ describe "in practice" do
202
+ it "unsubscribes a valid individual object successfully" do
203
+ @updates.unsubscribe("user").should be_true
204
+ end
205
+
206
+ it "unsubscribes all subscriptions successfully" do
207
+ @updates.unsubscribe.should be_true
208
+ end
121
209
 
122
- it "should fail when an invalid object is provided to unsubscribe" do
123
- lambda { @updates.unsubscribe("kittens") }.should raise_error(Koala::Facebook::APIError)
210
+ it "fails when an invalid object is provided to unsubscribe" do
211
+ expect { @updates.unsubscribe("kittens") }.to raise_error(Koala::Facebook::APIError)
212
+ end
213
+ end
214
+ end
215
+
216
+ describe "#list_subscriptions" do
217
+ it "GETs the subscription path" do
218
+ @updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "get", anything)
219
+ @updates.list_subscriptions
124
220
  end
125
221
 
126
- it "should is subscriptions properly" do
127
- @updates.list_subscriptions.should be_a(Array)
222
+ it "accepts options" do
223
+ options = {:a => 3, :b => "D"}
224
+ @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
225
+ @updates.list_subscriptions(options)
128
226
  end
129
- end # describe "when used"
227
+
228
+ describe "in practice" do
229
+ it "lists subscriptions properly" do
230
+ @updates.list_subscriptions.should be_a(Array)
231
+ end
232
+ end
233
+ end
234
+
235
+ describe "#subscription_path" do
236
+ it "returns the app_id/subscriptions" do
237
+ @updates.subscription_path.should == "#{@app_id}/subscriptions"
238
+ end
239
+ end
130
240
 
131
- describe "when meeting challenge" do
132
- it "should return false if hub.mode isn't subscribe" do
241
+ describe ".meet_challenge" do
242
+ it "returns false if hub.mode isn't subscribe" do
133
243
  params = {'hub.mode' => 'not subscribe'}
134
244
  Koala::Facebook::RealtimeUpdates.meet_challenge(params).should be_false
135
245
  end
136
246
 
137
- it "should return false if not given a verify_token or block" do
247
+ it "returns false if not given a verify_token or block" do
138
248
  params = {'hub.mode' => 'subscribe'}
139
249
  Koala::Facebook::RealtimeUpdates.meet_challenge(params).should be_false
140
250
  end
@@ -150,11 +260,11 @@ describe "Koala::Facebook::RealtimeUpdates" do
150
260
  @params['hub.verify_token'] = @token
151
261
  end
152
262
 
153
- it "should return false if the given verify token doesn't match" do
263
+ it "returns false if the given verify token doesn't match" do
154
264
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token + '1').should be_false
155
265
  end
156
266
 
157
- it "should return the challenge if the given verify token matches" do
267
+ it "returns the challenge if the given verify token matches" do
158
268
  @params['hub.challenge'] = 'challenge val'
159
269
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token).should == @params['hub.challenge']
160
270
  end
@@ -165,34 +275,31 @@ describe "Koala::Facebook::RealtimeUpdates" do
165
275
  @params['hub.verify_token'] = @token
166
276
  end
167
277
 
168
- it "should give the block the token as a parameter" do
278
+ it "gives the block the token as a parameter" do
169
279
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
170
280
  token.should == @token
171
281
  end
172
282
  end
173
283
 
174
- it "should return false if the given block return false" do
284
+ it "returns false if the given block return false" do
175
285
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
176
286
  false
177
287
  end.should be_false
178
288
  end
179
289
 
180
- it "should return false if the given block returns nil" do
290
+ it "returns false if the given block returns nil" do
181
291
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
182
292
  nil
183
293
  end.should be_false
184
294
  end
185
295
 
186
- it "should return the challenge if the given block returns true" do
296
+ it "returns the challenge if the given block returns true" do
187
297
  @params['hub.challenge'] = 'challenge val'
188
298
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
189
299
  true
190
300
  end.should be_true
191
301
  end
192
302
  end
193
-
194
- end # describe "and mode is subscribe"
195
-
196
- end # describe "when meeting challenge"
197
-
198
- end # describe
303
+ end
304
+ end
305
+ end