koala 0.10.0 → 1.0.0.beta2.1

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 (34) hide show
  1. data/CHANGELOG +34 -7
  2. data/Manifest +8 -1
  3. data/Rakefile +4 -4
  4. data/koala.gemspec +10 -8
  5. data/lib/koala/graph_api.rb +188 -123
  6. data/lib/koala/http_services.rb +92 -22
  7. data/lib/koala/rest_api.rb +73 -6
  8. data/lib/koala/test_users.rb +18 -5
  9. data/lib/koala/uploadable_io.rb +115 -0
  10. data/lib/koala.rb +81 -72
  11. data/readme.md +18 -12
  12. data/spec/facebook_data.yml +18 -14
  13. data/spec/koala/assets/beach.jpg +0 -0
  14. data/spec/koala/graph_and_rest_api/graph_and_rest_api_no_token_tests.rb +5 -1
  15. data/spec/koala/graph_and_rest_api/graph_and_rest_api_with_token_tests.rb +8 -3
  16. data/spec/koala/graph_api/graph_api_no_access_token_tests.rb +13 -62
  17. data/spec/koala/graph_api/graph_api_tests.rb +85 -0
  18. data/spec/koala/graph_api/graph_api_with_access_token_tests.rb +167 -123
  19. data/spec/koala/http_services/http_service_tests.rb +51 -0
  20. data/spec/koala/http_services/net_http_service_tests.rb +339 -0
  21. data/spec/koala/http_services/typhoeus_service_tests.rb +162 -0
  22. data/spec/koala/live_testing_data_helper.rb +1 -1
  23. data/spec/koala/oauth/oauth_tests.rb +19 -85
  24. data/spec/koala/rest_api/rest_api_no_access_token_tests.rb +5 -74
  25. data/spec/koala/rest_api/rest_api_tests.rb +118 -0
  26. data/spec/koala/rest_api/rest_api_with_access_token_tests.rb +5 -3
  27. data/spec/koala/test_users/test_users_tests.rb +49 -48
  28. data/spec/koala/uploadable_io/uploadable_io_tests.rb +246 -0
  29. data/spec/koala_spec_helper.rb +32 -6
  30. data/spec/koala_spec_without_mocks.rb +3 -3
  31. data/spec/mock_facebook_responses.yml +43 -20
  32. data/spec/mock_http_service.rb +16 -3
  33. metadata +39 -8
  34. data/spec/koala/net_http_service_tests.rb +0 -186
@@ -0,0 +1,339 @@
1
+ require 'koala/http_services'
2
+ class NetHTTPServiceTests < Test::Unit::TestCase
3
+ module Bear
4
+ include Koala::NetHTTPService
5
+ end
6
+
7
+ describe "NetHTTPService module holder class Bear" do
8
+ before :each do
9
+ # reset the always_use_ssl parameter
10
+ Bear.always_use_ssl = nil
11
+ end
12
+
13
+ it "should define a make_request static module method" do
14
+ Bear.respond_to?(:make_request).should be_true
15
+ end
16
+
17
+ it "should include the Koala::HTTPService module defining common features" do
18
+ Bear.included_modules.include?(Koala::HTTPService).should be_true
19
+ end
20
+
21
+ describe "when making a request" do
22
+ before(:each) do
23
+ # Setup stubs for make_request to execute without exceptions
24
+ @mock_http_response = stub('Net::HTTPResponse', :code => 1)
25
+ @mock_body = stub('Net::HTTPResponse body')
26
+ @http_request_result = [@mock_http_response, @mock_body]
27
+
28
+ # to_ary is called in Ruby 1.9 to provide backwards compatibility
29
+ # with the response, body = http.get() syntax we use
30
+ @mock_http_response.stub!(:to_ary).and_return(@http_request_result)
31
+
32
+ @http_yield_mock = mock('Net::HTTP start yielded object')
33
+
34
+ @http_yield_mock.stub(:post).and_return(@http_request_result)
35
+ @http_yield_mock.stub(:get).and_return(@http_request_result)
36
+
37
+ @http_mock = stub('Net::HTTP object', 'use_ssl=' => true, 'verify_mode=' => true)
38
+ @http_mock.stub(:start).and_yield(@http_yield_mock)
39
+
40
+ Net::HTTP.stub(:new).and_return(@http_mock)
41
+ end
42
+
43
+ describe "the connection" do
44
+ it "should use POST if verb is not GET" do
45
+ @http_yield_mock.should_receive(:post).and_return(@mock_http_response)
46
+ @http_mock.should_receive(:start).and_yield(@http_yield_mock)
47
+
48
+ Bear.make_request('anything', {}, 'anything')
49
+ end
50
+
51
+ it "should use GET if that verb is specified" do
52
+ @http_yield_mock.should_receive(:get).and_return(@mock_http_response)
53
+ @http_mock.should_receive(:start).and_yield(@http_yield_mock)
54
+
55
+ Bear.make_request('anything', {}, 'get')
56
+ end
57
+
58
+ it "should add the method to the arguments if it's not get or post" do
59
+ args = {}
60
+ method = "telekenesis"
61
+ # since the arguments get encoded later, we'll test for merge!
62
+ # even though that's somewhat testing internal implementation
63
+ args.should_receive(:merge!).with(:method => method)
64
+
65
+ Bear.make_request('anything', args, method)
66
+ end
67
+ end
68
+
69
+ describe "if the request has an access token" do
70
+ before :each do
71
+ @args = {"access_token" => "123"}
72
+ end
73
+
74
+ it "should use SSL" do
75
+ @http_mock.should_receive('use_ssl=').with(true)
76
+
77
+ Bear.make_request('anything', @args, 'anything')
78
+ end
79
+
80
+ it "should set the port to 443" do
81
+ Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
82
+
83
+ Bear.make_request('anything', @args, 'anything')
84
+ end
85
+ end
86
+
87
+ describe "if always_use_ssl is true" do
88
+ before :each do
89
+ Bear.always_use_ssl = true
90
+ end
91
+
92
+ it "should use SSL" do
93
+ @http_mock.should_receive('use_ssl=').with(true)
94
+
95
+ Bear.make_request('anything', {}, 'anything')
96
+ end
97
+
98
+ it "should set the port to 443" do
99
+ Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
100
+
101
+ Bear.make_request('anything', {}, 'anything')
102
+ end
103
+ end
104
+
105
+ describe "if the use_ssl option is provided" do
106
+ it "should use SSL" do
107
+ @http_mock.should_receive('use_ssl=').with(true)
108
+
109
+ Bear.make_request('anything', {}, 'anything', :use_ssl => true)
110
+ end
111
+
112
+ it "should set the port to 443" do
113
+ Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
114
+
115
+ Bear.make_request('anything', {}, 'anything', :use_ssl => true)
116
+ end
117
+ end
118
+
119
+ describe "if there's no token and always_use_ssl isn't true" do
120
+ it "should not use SSL" do
121
+ @http_mock.should_not_receive('use_ssl=')
122
+ Bear.make_request('anything', {}, 'anything')
123
+ end
124
+
125
+ it "should not set the port" do
126
+ Net::HTTP.should_receive(:new).with(anything, nil).and_return(@http_mock)
127
+ Bear.make_request('anything', {}, 'anything')
128
+ end
129
+ end
130
+
131
+ it "should use the graph server by default" do
132
+ Net::HTTP.should_receive(:new).with(Koala::Facebook::GRAPH_SERVER, anything).and_return(@http_mock)
133
+ Bear.make_request('anything', {}, 'anything')
134
+ end
135
+
136
+ it "should use the REST server if the :rest_api option is true" do
137
+ Net::HTTP.should_receive(:new).with(Koala::Facebook::REST_SERVER, anything).and_return(@http_mock)
138
+ Bear.make_request('anything', {}, 'anything', :rest_api => true)
139
+ end
140
+
141
+ it "no longer turns off vertificate validaiton warnings" do
142
+ @http_mock.should_not_receive('verify_mode=')
143
+
144
+ Bear.make_request('anything', {}, 'anything')
145
+ end
146
+
147
+ it "should start an HTTP connection" do
148
+ @http_mock.should_receive(:start).and_yield(@http_yield_mock)
149
+ Bear.make_request('anything', {}, 'anything')
150
+ end
151
+
152
+ describe "via POST" do
153
+ it "should use Net::HTTP to make a POST request" do
154
+ @http_yield_mock.should_receive(:post).and_return(@http_request_result)
155
+
156
+ Bear.make_request('anything', {}, 'post')
157
+ end
158
+
159
+ it "should go to the specified path adding a / if it doesn't exist" do
160
+ path = mock('Path')
161
+ @http_yield_mock.should_receive(:post).with(path, anything).and_return(@http_request_result)
162
+
163
+ Bear.make_request(path, {}, 'post')
164
+ end
165
+
166
+ it "should use encoded parameters" do
167
+ args = {}
168
+ params = mock('Encoded parameters')
169
+ Bear.should_receive(:encode_params).with(args).and_return(params)
170
+
171
+ @http_yield_mock.should_receive(:post).with(anything, params).and_return(@http_request_result)
172
+
173
+ Bear.make_request('anything', args, 'post')
174
+ end
175
+
176
+ describe "with multipart/form-data" do
177
+ before(:each) do
178
+ Bear.stub(:encode_multipart_params)
179
+ Bear.stub("params_require_multipart?").and_return(true)
180
+
181
+ @multipart_request_stub = stub('Stub Multipart Request')
182
+ Net::HTTP::Post::Multipart.stub(:new).and_return(@multipart_request_stub)
183
+
184
+ @file_stub = stub('fake File', "kind_of?" => true, "path" => 'anypath.jpg')
185
+
186
+ @http_yield_mock.stub(:request).with(@multipart_request_stub).and_return(@http_request_result)
187
+ end
188
+
189
+ it "should use multipart/form-data if any parameter is a valid file hash" do
190
+ @http_yield_mock.should_receive(:request).with(@multipart_request_stub).and_return(@http_request_result)
191
+
192
+ Bear.make_request('anything', {}, 'post')
193
+ end
194
+
195
+ it "should use the given request path for the request" do
196
+ args = {"file" => @file_stub}
197
+ expected_path = 'expected/path'
198
+
199
+ Net::HTTP::Post::Multipart.should_receive(:new).with(expected_path, anything).and_return(@multipart_request_stub)
200
+
201
+ Bear.make_request(expected_path, {}, 'post')
202
+ end
203
+
204
+ it "should use multipart encoded arguments for the request" do
205
+ args = {"file" => @file_stub}
206
+ expected_params = stub('Stub Multipart Params')
207
+
208
+ Bear.should_receive(:encode_multipart_params).with(args).and_return(expected_params)
209
+ Net::HTTP::Post::Multipart.should_receive(:new).with(anything, expected_params).and_return(@multipart_request_stub)
210
+
211
+ Bear.make_request('anything', args, 'post')
212
+ end
213
+ end
214
+ end
215
+
216
+ describe "via GET" do
217
+ it "should use Net::HTTP to make a GET request" do
218
+ @http_yield_mock.should_receive(:get).and_return(@http_request_result)
219
+
220
+ Bear.make_request('anything', {}, 'get')
221
+ end
222
+
223
+ it "should use the correct path, including arguments" do
224
+ path = mock('Path')
225
+ params = mock('Encoded parameters')
226
+ args = {}
227
+
228
+ Bear.should_receive(:encode_params).with(args).and_return(params)
229
+ @http_yield_mock.should_receive(:get).with("#{path}?#{params}").and_return(@http_request_result)
230
+
231
+ Bear.make_request(path, args, 'get')
232
+ end
233
+ end
234
+
235
+ describe "the returned value" do
236
+ before(:each) do
237
+ @response = Bear.make_request('anything', {}, 'anything')
238
+ end
239
+
240
+ it "should return a Koala::Response object" do
241
+ @response.class.should == Koala::Response
242
+ end
243
+
244
+ it "should return a Koala::Response with the right status" do
245
+ @response.status.should == @mock_http_response.code
246
+ end
247
+
248
+ it "should reutrn a Koala::Response with the right body" do
249
+ @response.body.should == @mock_body
250
+ end
251
+
252
+ it "should return a Koala::Response with the Net::HTTPResponse object as headers" do
253
+ @response.headers.should == @mock_http_response
254
+ end
255
+ end # describe return value
256
+ end # describe when making a request
257
+
258
+ describe "when encoding parameters" do
259
+ it "should return an empty string if param_hash evaluates to false" do
260
+ Bear.encode_params(nil).should == ''
261
+ end
262
+
263
+ it "should convert values to JSON if the value is not a String" do
264
+ val = 'json_value'
265
+ not_a_string = 'not_a_string'
266
+ not_a_string.stub(:class).and_return('NotAString')
267
+ not_a_string.should_receive(:to_json).and_return(val)
268
+
269
+ string = "hi"
270
+
271
+ args = {
272
+ not_a_string => not_a_string,
273
+ string => string
274
+ }
275
+
276
+ result = Bear.encode_params(args)
277
+ result.split('&').find do |key_and_val|
278
+ key_and_val.match("#{not_a_string}=#{val}")
279
+ end.should be_true
280
+ end
281
+
282
+ it "should escape all values" do
283
+ args = Hash[*(1..4).map {|i| [i.to_s, "Value #{i}($"]}.flatten]
284
+
285
+ result = Bear.encode_params(args)
286
+ result.split('&').each do |key_val|
287
+ key, val = key_val.split('=')
288
+ val.should == CGI.escape(args[key])
289
+ end
290
+ end
291
+
292
+ it "should convert all keys to Strings" do
293
+ args = Hash[*(1..4).map {|i| [i, "val#{i}"]}.flatten]
294
+
295
+ result = Bear.encode_params(args)
296
+ result.split('&').each do |key_val|
297
+ key, val = key_val.split('=')
298
+ key.should == args.find{|key_val_arr| key_val_arr.last == val}.first.to_s
299
+ end
300
+ end
301
+ end
302
+
303
+ describe "when detecting if multipart posting is needed" do
304
+ it "should be true if any parameter value requires multipart post" do
305
+ koala_io = mock("Koala::IO")
306
+ koala_io.should_receive(:kind_of?).with(Koala::UploadableIO).and_return(true)
307
+
308
+ args = {
309
+ "key1" => "val",
310
+ "key2" => "val",
311
+ "key3" => koala_io,
312
+ "key4" => "val"
313
+ }
314
+
315
+ Bear.params_require_multipart?(args).should be_true
316
+ end
317
+
318
+ describe "when encoding multipart/form-data params" do
319
+ it "should replace Koala::UploadableIO values with UploadIO values" do
320
+ upload_io = UploadIO.new(__FILE__, "fake type")
321
+
322
+ uploadable_io = stub('Koala::UploadableIO')
323
+ uploadable_io.should_receive(:kind_of?).with(Koala::UploadableIO).and_return(true)
324
+ uploadable_io.should_receive(:to_upload_io).and_return(upload_io)
325
+ args = {
326
+ "not_a_file" => "not a file",
327
+ "file" => uploadable_io
328
+ }
329
+
330
+ result = Bear.encode_multipart_params(args)
331
+
332
+ result["not_a_file"] == args["not_a_file"]
333
+ result["file"] == upload_io
334
+ end
335
+ end
336
+
337
+ end
338
+ end
339
+ end
@@ -0,0 +1,162 @@
1
+ require 'koala/http_services'
2
+ class TyphoeusServiceTests < Test::Unit::TestCase
3
+ module Bear
4
+ include Koala::TyphoeusService
5
+ end
6
+
7
+ describe "TyphoeusService module holder class Bear" do
8
+ before :each do
9
+ # reset the always_use_ssl parameter
10
+ Bear.always_use_ssl = nil
11
+ end
12
+
13
+ it "should define a make_request static module method" do
14
+ Bear.respond_to?(:make_request).should be_true
15
+ end
16
+
17
+ it "should include the Koala::HTTPService module defining common features" do
18
+ Bear.included_modules.include?(Koala::HTTPService).should be_true
19
+ end
20
+
21
+ describe "when making a request" do
22
+ before(:each) do
23
+ # Setup stubs for make_request to execute without exceptions
24
+ @mock_body = stub('Typhoeus response body')
25
+ @mock_headers_hash = stub({:value => "headers hash"})
26
+ @mock_http_response = stub(Typhoeus::Response, :code => 1, :headers_hash => @mock_headers_hash, :body => @mock_body)
27
+
28
+ # Typhoeus is an included module, so we stub methods on Bear itself
29
+ Bear.stub(:post).and_return(@mock_http_response)
30
+ Bear.stub(:get).and_return(@mock_http_response)
31
+ end
32
+
33
+ it "should use POST if verb is not GET" do
34
+ Bear.should_receive(:post).and_return(@mock_http_response)
35
+ Bear.make_request('anything', {}, 'anything')
36
+ end
37
+
38
+ it "should use GET if that verb is specified" do
39
+ Bear.should_receive(:get).and_return(@mock_http_response)
40
+ Bear.make_request('anything', {}, 'get')
41
+ end
42
+
43
+ describe "the connection" do
44
+ it "should use SSL if the request has an access token" do
45
+ Bear.should_receive(:post).with(/https\:/, anything)
46
+
47
+ Bear.make_request('anything', {"access_token" => "123"}, 'anything')
48
+ end
49
+
50
+ it "should use SSL if always_use_ssl is true, even if there's no token" do
51
+ Bear.should_receive(:post).with(/https\:/, anything)
52
+
53
+ Bear.always_use_ssl = true
54
+ Bear.make_request('anything', {}, 'anything')
55
+ end
56
+
57
+ it "should use SSL if the :use_ssl option is provided, even if there's no token" do
58
+ Bear.should_receive(:post).with(/https\:/, anything)
59
+
60
+ Bear.always_use_ssl = true
61
+ Bear.make_request('anything', {}, 'anything', :use_ssl => true)
62
+ end
63
+
64
+ it "should not use SSL if always_use_ssl is false and there's no token" do
65
+ Bear.should_receive(:post).with(/http\:/, anything)
66
+
67
+ Bear.make_request('anything', {}, 'anything')
68
+ end
69
+
70
+ it "should use the graph server by default" do
71
+ Bear.should_receive(:post).with(Regexp.new(Koala::Facebook::GRAPH_SERVER), anything)
72
+
73
+ Bear.make_request('anything', {}, 'anything')
74
+ end
75
+
76
+ it "should use the REST server if the :rest_api option is true" do
77
+ Bear.should_receive(:post).with(Regexp.new(Koala::Facebook::REST_SERVER), anything)
78
+
79
+ Bear.make_request('anything', {}, 'anything', :rest_api => true)
80
+ end
81
+ end
82
+
83
+ it "should pass the arguments to Typhoeus under the :params key" do
84
+ args = {:a => 2}
85
+ Bear.should_receive(:post).with(anything, hash_including(:params => args))
86
+
87
+ Bear.make_request('anything', args, "post")
88
+ end
89
+
90
+ it "should add the method to the arguments if the method isn't get or post" do
91
+ method = "telekenesis"
92
+ Bear.should_receive(:post).with(anything, hash_including(:params => {:method => method}))
93
+
94
+ Bear.make_request('anything', {}, method)
95
+ end
96
+
97
+ it "should pass :typhoeus_options to Typhoeus if provided" do
98
+ t_options = {:a => :b}
99
+ Bear.should_receive(:post).with(anything, hash_including(t_options))
100
+
101
+ Bear.make_request("anything", {}, "post", :typhoeus_options => t_options)
102
+ end
103
+
104
+ it "should include the path in the request" do
105
+ path = "/a/b/c/1"
106
+ Bear.should_receive(:post).with(Regexp.new(path), anything)
107
+
108
+ Bear.make_request(path, {}, "post")
109
+ end
110
+
111
+ describe "the returned value" do
112
+ before(:each) do
113
+ @response = Bear.make_request('anything', {}, 'anything')
114
+ end
115
+
116
+ it "should return a Koala::Response object" do
117
+ @response.class.should == Koala::Response
118
+ end
119
+
120
+ it "should return a Koala::Response with the right status" do
121
+ @response.status.should == @mock_http_response.code
122
+ end
123
+
124
+ it "should reutrn a Koala::Response with the right body" do
125
+ @response.body.should == @mock_body
126
+ end
127
+
128
+ it "should return a Koala::Response with the Net::HTTPResponse object as headers" do
129
+ @response.headers.should == @mock_headers_hash
130
+ end
131
+ end # describe return value
132
+ end
133
+
134
+ describe "with file upload" do
135
+ it "should include an interface to NetHTTPService called NetHTTPInterface" do
136
+ # we should be able to access it
137
+ lambda { Koala::TyphoeusService::NetHTTPInterface }.should_not raise_exception(Exception)
138
+ Koala::TyphoeusService::NetHTTPInterface.included_modules.include?(Koala::NetHTTPService).should be_true
139
+ end
140
+
141
+ it "should call the NetHTTPInterface if multipart is required" do
142
+ method = "any_method"
143
+ args = {}
144
+ verb = "get"
145
+ options = {}
146
+
147
+ Bear.stub(:params_require_multipart?).and_return(true)
148
+ Koala::TyphoeusService::NetHTTPInterface.should_receive(:make_request).with(method, args, verb, options)
149
+
150
+ Bear.make_request(method, args, verb, options)
151
+ end
152
+
153
+ # Typhoeus file uploads currently don't work
154
+ # for live tests, run the Graph API tests with Typhoues, which will run file uploads
155
+ # it "should pass any files directly on to Typhoues" do
156
+ # args = {:file => File.new(__FILE__, "r")}
157
+ # Bear.should_receive(:post).with(anything, hash_including(:params => args)).and_return(Typhoeus::Response.new)
158
+ # Bear.make_request("anything", args, :post)
159
+ # end
160
+ end
161
+ end
162
+ end
@@ -19,7 +19,7 @@ module LiveTestingDataHelper
19
19
  errors = []
20
20
 
21
21
  if count > 0
22
- print "\nCleaning up #{count} temporary #{count > 1 ? "objects" : "object"}..."
22
+ print "\nCleaning up #{count} temporary #{count > 1 ? "objects" : "object (#{@temporary_object_ids.first})"}..."
23
23
  @temporary_object_ids.each do |id|
24
24
  # get our API
25
25
  api = @api || (@test_users ? @test_users.graph_api : nil)
@@ -10,12 +10,9 @@ class FacebookOAuthTests < Test::Unit::TestCase
10
10
  @raw_token_string = @oauth_data["raw_token_string"]
11
11
  @raw_offline_access_token_string = @oauth_data["raw_offline_access_token_string"]
12
12
 
13
- # per Facebook's example:
14
- # http://developers.facebook.com/docs/authentication/canvas
15
- # this allows us to use Facebook's example data while running the other live data
16
- @request_secret = @oauth_data["request_secret"] || @secret
17
- @signed_request = @oauth_data["signed_request"]
18
- @signed_request_result = @oauth_data["signed_request_result"]
13
+ # for signed requests (http://developers.facebook.com/docs/authentication/canvas/encryption_proposal)
14
+ @signed_params = @oauth_data["signed_params"]
15
+ @signed_params_result = @oauth_data["signed_params_result"]
19
16
 
20
17
  # this should expanded to cover all variables
21
18
  raise Exception, "Must supply app data to run FacebookOAuthTests!" unless @app_id && @secret && @callback_url &&
@@ -24,9 +21,9 @@ class FacebookOAuthTests < Test::Unit::TestCase
24
21
 
25
22
  @oauth = Koala::Facebook::OAuth.new(@app_id, @secret, @callback_url)
26
23
 
27
- time = Time.now
28
- Time.stub!(:now).and_return(time)
29
- time.stub!(:to_i).and_return(1273363199)
24
+ @time = Time.now
25
+ Time.stub!(:now).and_return(@time)
26
+ @time.stub!(:to_i).and_return(1273363199)
30
27
  end
31
28
 
32
29
  # initialization
@@ -350,86 +347,23 @@ class FacebookOAuthTests < Test::Unit::TestCase
350
347
  end
351
348
 
352
349
  describe "for parsing signed requests" do
353
- before :each do
354
- # you can test against live data by updating the YML, or you can use the default data
355
- # which tests against Facebook's example on http://developers.facebook.com/docs/authentication/canvas
356
- @oauth = Koala::Facebook::OAuth.new(@app_id, @request_secret || @app_secret)
357
- end
358
-
359
- it "should break the request into the encoded signature and the payload" do
360
- @signed_request.should_receive(:split).with(".").and_return(["", ""])
361
- @oauth.parse_signed_request(@signed_request)
350
+ # the signed request code comes directly from Facebook
351
+ # so we only need to test at a high level that it works
352
+ # signed params refers to http://developers.facebook.com/docs/authentication/canvas
353
+ # signed request refers to http://developers.facebook.com/docs/authentication/canvas/encryption_proposal
354
+ it "should throw an error if the algorithm is unsupported" do
355
+ JSON.stub!(:parse).and_return("algorithm" => "my fun algorithm")
356
+ lambda { @oauth.parse_signed_request(@signed_request) }.should raise_error
362
357
  end
363
358
 
364
- it "should base64 URL decode the signed request" do
365
- sig = ""
366
- @signed_request.should_receive(:split).with(".").and_return([sig, "1"])
367
- @oauth.should_receive(:base64_url_decode).with(sig).and_return("4")
368
- @oauth.parse_signed_request(@signed_request)
359
+ it "should throw an error if the signature is invalid" do
360
+ OpenSSL::HMAC.stub!(:hexdigest).and_return("i'm an invalid signature")
361
+ lambda { @oauth.parse_signed_request(@signed_request) }.should raise_error
369
362
  end
370
363
 
371
- it "should base64 URL decode the signed request" do
372
- sig = @signed_request.split(".")[0]
373
- @oauth.should_receive(:base64_url_decode).with(sig).and_return(nil)
374
- @oauth.parse_signed_request(@signed_request)
375
- end
376
-
377
- it "should get the sha64 encoded payload using proper arguments from OpenSSL::HMAC" do
378
- payload = ""
379
- @signed_request.should_receive(:split).with(".").and_return(["1", payload])
380
- OpenSSL::HMAC.should_receive(:digest).with("sha256", @request_secret, payload)
381
- @oauth.parse_signed_request(@signed_request)
382
- end
383
-
384
- it "should compare the encoded payload with the signature" do
385
- sig = "2"
386
- @oauth.should_receive(:base64_url_decode).and_return(sig)
387
- encoded_payload = "1"
388
- OpenSSL::HMAC.should_receive(:digest).with(anything, anything, anything).and_return(encoded_payload)
389
- encoded_payload.should_receive(:==).with(sig)
390
- @oauth.parse_signed_request(@signed_request)
391
- end
392
-
393
- describe "if the encoded payload matches the signature" do
394
- before :each do
395
- # set it up so the sig will match the encoded payload
396
- raw_sig = ""
397
- @sig = "2"
398
- @payload = "1"
399
- @signed_request.should_receive(:split).and_return([raw_sig, @payload])
400
- @oauth.should_receive(:base64_url_decode).with(raw_sig).and_return(@sig)
401
- OpenSSL::HMAC.should_receive(:digest).with(anything, anything, anything).and_return(@sig.dup)
402
- end
403
-
404
- it "should base64_url_decode the payload" do
405
- @oauth.should_receive(:base64_url_decode).with(@payload).ordered.and_return("{}")
406
- @oauth.parse_signed_request(@signed_request)
407
- end
408
-
409
- it "should JSON decode the payload" do
410
- result = "{}"
411
- @oauth.should_receive(:base64_url_decode).with(@payload).and_return(result)
412
- JSON.should_receive(:parse).with(result)
413
- @oauth.parse_signed_request(@signed_request)
414
- end
415
- end
416
-
417
- describe "if the encoded payload does not match the signature" do
418
- before :each do
419
- sig = ""
420
- @signed_request.should_receive(:split).and_return([sig, ""])
421
- OpenSSL::HMAC.should_receive(:digest).with(anything, anything, anything).and_return("hi")
422
- end
423
-
424
- it "should return nil" do
425
- @oauth.parse_signed_request(@signed_request).should be_nil
426
- end
427
- end
428
-
429
- describe "run against data" do
430
- it "should work" do
431
- @oauth.parse_signed_request(@signed_request).should == @signed_request_result
432
- end
364
+ it "properly parses requests" do
365
+ @oauth = Koala::Facebook::OAuth.new(@app_id, @secret || @app_secret)
366
+ @oauth.parse_signed_request(@signed_params).should == @signed_params_result
433
367
  end
434
368
  end
435
369