koala 0.10.0 → 1.0.0.beta

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.
@@ -0,0 +1,86 @@
1
+ shared_examples_for "Koala GraphAPI" do
2
+ # all Graph API instances should pass these tests, regardless of configuration
3
+
4
+ # API
5
+ it "should never use the rest api server" do
6
+ Koala.should_receive(:make_request).with(
7
+ anything,
8
+ anything,
9
+ anything,
10
+ hash_not_including(:rest_api => true)
11
+ ).and_return(Koala::Response.new(200, "", {}))
12
+
13
+ @api.api("anything")
14
+ end
15
+
16
+ # GRAPH CALL
17
+ describe "graph_call" do
18
+ it "should pass all arguments to the api method" do
19
+ args = ["koppel", {}, "get", {:a => :b}]
20
+
21
+ @api.should_receive(:api).with(*args)
22
+
23
+ @api.graph_call(*args)
24
+ end
25
+
26
+ it "should throw an APIError if the result hash has an error key" do
27
+ Koala.stub(:make_request).and_return(Koala::Response.new(500, {"error" => "An error occurred!"}, {}))
28
+ lambda { @api.graph_call("koppel", {}) }.should raise_exception(Koala::Facebook::APIError)
29
+ end
30
+ end
31
+
32
+ # SEARCH
33
+ it "should be able to search" do
34
+ result = @api.search("facebook")
35
+ result.length.should be_an(Integer)
36
+ end
37
+
38
+ # DATA
39
+ # access public info
40
+
41
+ it "should get public data about a user" do
42
+ result = @api.get_object("koppel")
43
+ # the results should have an ID and a name, among other things
44
+ (result["id"] && result["name"]).should_not be_nil
45
+ end
46
+
47
+ it "should get public data about a Page" do
48
+ result = @api.get_object("contextoptional")
49
+ # the results should have an ID and a name, among other things
50
+ (result["id"] && result["name"]).should
51
+ end
52
+
53
+ it "should be able to get multiple objects" do
54
+ results = @api.get_objects(["contextoptional", "naitik"])
55
+ results.length.should == 2
56
+ end
57
+
58
+ it "should be able to access a user's picture" do
59
+ @api.get_picture("chris.baclig").should =~ /http\:\/\//
60
+ end
61
+
62
+ it "should be able to access a user's picture, given a picture type" do
63
+ @api.get_picture("chris.baclig", {:type => 'large'}).should =~ /^http\:\/\//
64
+ end
65
+
66
+ it "should be able to access connections from public Pages" do
67
+ result = @api.get_connections("contextoptional", "photos")
68
+ result.should be_a(Array)
69
+ end
70
+
71
+ # SEARCH
72
+ it "should be able to search" do
73
+ result = @api.search("facebook")
74
+ result.length.should be_an(Integer)
75
+ end
76
+
77
+ # PAGING THROUGH COLLECTIONS
78
+ # see also graph_collection_tests
79
+ it "should make a request for a page when provided a specific set of page params" do
80
+ query = [1, 2]
81
+ @api.should_receive(:graph_call).with(*query)
82
+ @api.get_page(query)
83
+ end
84
+
85
+
86
+ end
@@ -1,150 +1,154 @@
1
1
  shared_examples_for "Koala GraphAPI with an access token" do
2
- it "should get public data about a user" do
3
- result = @api.get_object("koppel")
4
- # the results should have an ID and a name, among other things
5
- (result["id"] && result["name"]).should_not be_nil
6
- end
7
2
 
8
- it "should get private data about a user" do
9
- result = @api.get_object("koppel")
10
- # updated_time should be a pretty fixed test case
11
- result["updated_time"].should_not be_nil
12
- end
3
+ it "should get private data about a user" do
4
+ result = @api.get_object("koppel")
5
+ # updated_time should be a pretty fixed test case
6
+ result["updated_time"].should_not be_nil
7
+ end
13
8
 
14
- it "should get public data about a Page" do
15
- result = @api.get_object("contextoptional")
16
- # the results should have an ID and a name, among other things
17
- (result["id"] && result["name"]).should
18
- end
19
-
20
- it "should get data about 'me'" do
21
- result = @api.get_object("me")
22
- result["updated_time"].should
23
- end
24
-
25
- it "should be able to get multiple objects" do
26
- result = @api.get_objects(["contextoptional", "naitik"])
27
- result.length.should == 2
28
- end
29
-
30
- it "should be able to access a user's picture" do
31
- @api.get_picture("chris.baclig").should =~ /http\:\/\//
32
- end
33
-
34
- it "should be able to access a user's picture, given a picture type" do
35
- @api.get_picture("chris.baclig", {:type => 'large'}).should =~ /^http\:\/\//
36
- end
9
+ it "should get data about 'me'" do
10
+ result = @api.get_object("me")
11
+ result["updated_time"].should
12
+ end
13
+
14
+ it "should be able to get multiple objects" do
15
+ result = @api.get_objects(["contextoptional", "naitik"])
16
+ result.length.should == 2
17
+ end
18
+ it "should be able to access connections from users" do
19
+ result = @api.get_connections("lukeshepard", "likes")
20
+ result.length.should > 0
21
+ end
22
+
23
+ # PUT
24
+ it "should be able to write an object to the graph" do
25
+ result = @api.put_wall_post("Hello, world, from the test suite!")
26
+ @temporary_object_id = result["id"]
27
+ @temporary_object_id.should_not be_nil
28
+ end
29
+
30
+ # DELETE
31
+ it "should be able to delete posts" do
32
+ result = @api.put_wall_post("Hello, world, from the test suite delete method!")
33
+ object_id_to_delete = result["id"]
34
+ delete_result = @api.delete_object(object_id_to_delete)
35
+ delete_result.should == true
36
+ end
37
37
 
38
- it "should be able to access connections from users" do
39
- result = @api.get_connections("lukeshepard", "likes")
40
- result.length.should > 0
41
- end
38
+ it "should be able to delete likes" do
39
+ result = @api.put_wall_post("Hello, world, from the test suite delete method!")
40
+ @temporary_object_id = result["id"]
41
+ @api.put_like(@temporary_object_id)
42
+ delete_like_result = @api.delete_like(@temporary_object_id)
43
+ delete_like_result.should == true
44
+ end
42
45
 
43
- it "should be able to access connections from public Pages" do
44
- result = @api.get_connections("contextoptional", "photos")
45
- result.should be_a(Array)
46
- end
46
+ # additional put tests
47
+ it "should be able to verify messages posted to a wall" do
48
+ message = "the cats are asleep"
49
+ put_result = @api.put_wall_post(message)
50
+ @temporary_object_id = put_result["id"]
51
+ get_result = @api.get_object(@temporary_object_id)
52
+
53
+ # make sure the message we sent is the message that got posted
54
+ get_result["message"].should == message
55
+ end
56
+
57
+ it "should be able to post a message with an attachment to a feed" do
58
+ result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "Context Optional", :link => "http://www.contextoptional.com/"})
59
+ @temporary_object_id = result["id"]
60
+ @temporary_object_id.should_not be_nil
61
+ end
62
+
63
+ it "should be able to post photos to the user's wall with an open file object" do
64
+ file_hash = {
65
+ "content_type" => "image/jpg",
66
+ "path" => File.join(File.dirname(__FILE__), "..", "assets", "beach.jpg"),
67
+ "file" => File.open(File.join(File.dirname(__FILE__), "..", "assets", "beach.jpg"))
68
+ }
69
+ result = @api.put_picture(file_hash)
70
+ @temporary_object_id = result["id"]
71
+ @temporary_object_id.should_not be_nil
72
+ end
73
+
74
+ it "should be able to post photos to the user's wall without an open file object" do
75
+ file_hash = {
76
+ "content_type" => "image/jpg",
77
+ "path" => File.join(File.dirname(__FILE__), "..", "assets", "beach.jpg")
78
+ }
79
+ result = @api.put_picture(file_hash)
80
+ @temporary_object_id = result["id"]
81
+ @temporary_object_id.should_not be_nil
82
+ end
47
83
 
48
- # paging
49
- # see also graph_collection_tests
50
- it "should make a request for a page when provided a specific set of page params" do
51
- query = [1, 2]
52
- @api.should_receive(:graph_call).with(*query)
53
- @api.get_page(query)
54
- end
84
+ it "should be able to verify a photo posted to a user's wall" do
85
+ file_hash = {
86
+ "content_type" => "image/jpg",
87
+ "path" => File.join(File.dirname(__FILE__), "..", "assets", "beach.jpg")
88
+ }
89
+ expected_message = "This is the test message"
55
90
 
91
+ result = @api.put_picture(file_hash, :message => expected_message)
92
+ @temporary_object_id = result["id"]
93
+ @temporary_object_id.should_not be_nil
56
94
 
57
- # PUT
58
- it "should be able to write an object to the graph" do
59
- result = @api.put_wall_post("Hello, world, from the test suite!")
60
- @temporary_object_id = result["id"]
61
- @temporary_object_id.should_not be_nil
62
- end
63
-
64
- # DELETE
65
- it "should be able to delete posts" do
66
- result = @api.put_wall_post("Hello, world, from the test suite delete method!")
67
- object_id_to_delete = result["id"]
68
- delete_result = @api.delete_object(object_id_to_delete)
69
- delete_result.should == true
70
- end
95
+ get_result = @api.get_object(@temporary_object_id)
96
+ get_result["name"].should == expected_message
97
+ end
98
+
99
+ it "should be able to verify a message with an attachment posted to a feed" do
100
+ attachment = {"name" => "Context Optional", "link" => "http://www.contextoptional.com/"}
101
+ result = @api.put_wall_post("Hello, world, from the test suite again!", attachment)
102
+ @temporary_object_id = result["id"]
103
+ get_result = @api.get_object(@temporary_object_id)
71
104
 
72
- # additional put tests
73
- it "should be able to verify messages posted to a wall" do
74
- message = "the cats are asleep"
75
- put_result = @api.put_wall_post(message)
76
- @temporary_object_id = put_result["id"]
77
- get_result = @api.get_object(@temporary_object_id)
78
-
79
- # make sure the message we sent is the message that got posted
80
- get_result["message"].should == message
81
- end
105
+ # make sure the result we fetch includes all the parameters we sent
106
+ it_matches = attachment.inject(true) {|valid, param| valid && (get_result[param[0]] == attachment[param[0]])}
107
+ it_matches.should == true
108
+ end
82
109
 
83
- it "should be able to post a message with an attachment to a feed" do
84
- result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "Context Optional", :link => "http://www.contextoptional.com/"})
85
- @temporary_object_id = result["id"]
86
- @temporary_object_id.should_not be_nil
87
- end
88
-
89
- it "should be able to verify a message with an attachment posted to a feed" do
90
- attachment = {"name" => "Context Optional", "link" => "http://www.contextoptional.com/"}
91
- result = @api.put_wall_post("Hello, world, from the test suite again!", attachment)
92
- @temporary_object_id = result["id"]
93
- get_result = @api.get_object(@temporary_object_id)
94
-
95
- # make sure the result we fetch includes all the parameters we sent
96
- it_matches = attachment.inject(true) {|valid, param| valid && (get_result[param[0]] == attachment[param[0]])}
97
- it_matches.should == true
98
- end
110
+ it "should be able to comment on an object" do
111
+ result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
112
+ @temporary_object_id = result["id"]
99
113
 
100
- it "should be able to comment on an object" do
101
- result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
102
- @temporary_object_id = result["id"]
103
-
104
- # this will be deleted when the post gets deleted
105
- comment_result = @api.put_comment(@temporary_object_id, "it's my comment!")
106
- comment_result.should_not be_nil
107
- end
108
-
109
- it "should be able to verify a comment posted about an object" do
110
- message_text = "Hello, world, from the test suite, testing comments!"
111
- result = @api.put_wall_post(message_text)
112
- @temporary_object_id = result["id"]
113
-
114
- # this will be deleted when the post gets deleted
115
- comment_text = "it's my comment!"
116
- comment_result = @api.put_comment(@temporary_object_id, comment_text)
117
- get_result = @api.get_object(comment_result["id"])
118
-
119
- # make sure the text of the comment matches what we sent
120
- get_result["message"].should == comment_text
121
- end
114
+ # this will be deleted when the post gets deleted
115
+ comment_result = @api.put_comment(@temporary_object_id, "it's my comment!")
116
+ comment_result.should_not be_nil
117
+ end
122
118
 
123
- it "should be able to like an object" do
124
- result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
125
- @temporary_object_id = result["id"]
126
- like_result = @api.put_like(@temporary_object_id)
127
- end
119
+ it "should be able to verify a comment posted about an object" do
120
+ message_text = "Hello, world, from the test suite, testing comments!"
121
+ result = @api.put_wall_post(message_text)
122
+ @temporary_object_id = result["id"]
128
123
 
129
- # SEARCH
130
- it "should be able to search" do
131
- result = @api.search("facebook")
132
- result.length.should be_an(Integer)
133
- end
124
+ # this will be deleted when the post gets deleted
125
+ comment_text = "it's my comment!"
126
+ comment_result = @api.put_comment(@temporary_object_id, comment_text)
127
+ get_result = @api.get_object(comment_result["id"])
134
128
 
135
- # API
136
- # the above tests test this already, but we should consider additional api tests
129
+ # make sure the text of the comment matches what we sent
130
+ get_result["message"].should == comment_text
131
+ end
137
132
 
138
- it_should_behave_like "Koala GraphAPI with GraphCollection"
133
+ it "should be able to like an object" do
134
+ result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
135
+ @temporary_object_id = result["id"]
136
+ like_result = @api.put_like(@temporary_object_id)
137
+ like_result.should be_true
138
+ end
139
139
  end
140
140
 
141
141
  class FacebookWithAccessTokenTests < Test::Unit::TestCase
142
142
  describe "Koala GraphAPI with an access token" do
143
143
  include LiveTestingDataHelper
144
- it_should_behave_like "Koala GraphAPI with an access token"
145
-
144
+
146
145
  before :each do
147
146
  @api = Koala::Facebook::GraphAPI.new(@token)
148
147
  end
148
+
149
+ it_should_behave_like "Koala GraphAPI"
150
+ it_should_behave_like "Koala GraphAPI with an access token"
151
+ it_should_behave_like "Koala GraphAPI with GraphCollection"
152
+
149
153
  end
150
154
  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)
@@ -5,10 +5,19 @@ class NetHTTPServiceTests < Test::Unit::TestCase
5
5
  end
6
6
 
7
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
+
8
13
  it "should define a make_request static module method" do
9
14
  Bear.respond_to?(:make_request).should be_true
10
15
  end
11
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
+
12
21
  describe "when making a request" do
13
22
  before(:each) do
14
23
  # Setup stubs for make_request to execute without exceptions
@@ -16,7 +25,7 @@ class NetHTTPServiceTests < Test::Unit::TestCase
16
25
  @mock_body = stub('Net::HTTPResponse body')
17
26
  @http_request_result = [@mock_http_response, @mock_body]
18
27
 
19
- # to_ary is called in Ruby 1.9 to provide backwards compatibility
28
+ # to_ary is called in Ruby 1.9 to provide backwards compatibility
20
29
  # with the response, body = http.get() syntax we use
21
30
  @mock_http_response.stub!(:to_ary).and_return(@http_request_result)
22
31
 
@@ -31,33 +40,102 @@ class NetHTTPServiceTests < Test::Unit::TestCase
31
40
  Net::HTTP.stub(:new).and_return(@http_mock)
32
41
  end
33
42
 
34
- it "should use POST if verb is not GET" do
35
- @http_yield_mock.should_receive(:post).and_return(@mock_http_response)
36
- @http_mock.should_receive(:start).and_yield(@http_yield_mock)
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)
37
47
 
38
- Bear.make_request('anything', {}, 'anything')
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
39
67
  end
40
68
 
41
- it "should use port 443" do
42
- Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
69
+ describe "if the request has an access token" do
70
+ before :each do
71
+ @args = {"access_token" => "123"}
72
+ end
43
73
 
44
- Bear.make_request('anything', {}, 'anything')
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
45
85
  end
46
86
 
47
- it "should use SSL" do
48
- @http_mock.should_receive('use_ssl=').with(true)
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)
49
94
 
50
- Bear.make_request('anything', {}, 'anything')
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
51
129
  end
52
130
 
53
131
  it "should use the graph server by default" do
54
132
  Net::HTTP.should_receive(:new).with(Koala::Facebook::GRAPH_SERVER, anything).and_return(@http_mock)
55
- Bear.make_request('anything', {}, 'anything')
133
+ Bear.make_request('anything', {}, 'anything')
56
134
  end
57
135
 
58
136
  it "should use the REST server if the :rest_api option is true" do
59
137
  Net::HTTP.should_receive(:new).with(Koala::Facebook::REST_SERVER, anything).and_return(@http_mock)
60
- Bear.make_request('anything', {}, 'anything', :rest_api => true)
138
+ Bear.make_request('anything', {}, 'anything', :rest_api => true)
61
139
  end
62
140
 
63
141
  it "should turn off vertificate validaiton warnings" do
@@ -82,7 +160,7 @@ class NetHTTPServiceTests < Test::Unit::TestCase
82
160
  path = mock('Path')
83
161
  @http_yield_mock.should_receive(:post).with(path, anything).and_return(@http_request_result)
84
162
 
85
- Bear.make_request(path, {}, 'post')
163
+ Bear.make_request(path, {}, 'post')
86
164
  end
87
165
 
88
166
  it "should use encoded parameters" do
@@ -94,6 +172,45 @@ class NetHTTPServiceTests < Test::Unit::TestCase
94
172
 
95
173
  Bear.make_request('anything', args, 'post')
96
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
97
214
  end
98
215
 
99
216
  describe "via GET" do
@@ -125,7 +242,7 @@ class NetHTTPServiceTests < Test::Unit::TestCase
125
242
  end
126
243
 
127
244
  it "should return a Koala::Response with the right status" do
128
- @response.status.should == @mock_http_response.code
245
+ @response.status.should == @mock_http_response.code
129
246
  end
130
247
 
131
248
  it "should reutrn a Koala::Response with the right body" do
@@ -182,5 +299,132 @@ class NetHTTPServiceTests < Test::Unit::TestCase
182
299
  end
183
300
  end
184
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
+ valid_file_hash = stub("Stub Valid File Hash")
306
+
307
+ Bear.stub!("is_valid_file_hash?").and_return(false)
308
+ Bear.stub!("is_valid_file_hash?").with(valid_file_hash).and_return(true)
309
+
310
+ args = {
311
+ "key1" => "val",
312
+ "key2" => "val",
313
+ "key3" => valid_file_hash,
314
+ "key4" => "val"
315
+ }
316
+
317
+ Bear.params_require_multipart?(args).should be_true
318
+ end
319
+
320
+ describe "and looking at individual values" do
321
+ before(:each) do
322
+ @valid_hash = {
323
+ "content_type" => 1,
324
+ "path" => 1
325
+ }
326
+ end
327
+
328
+ it "should only accept hashes" do
329
+ Bear.is_valid_file_hash?(@valid_hash).should be_true
330
+
331
+ @valid_hash.stub!("kind_of?").with(Hash).and_return(false)
332
+ Bear.is_valid_file_hash?(@valid_hash).should be_false
333
+ end
334
+
335
+ it "should always require a content_type key" do
336
+ @valid_hash.delete("content_type")
337
+ Bear.is_valid_file_hash?(@valid_hash).should be_false
338
+ end
339
+
340
+ it "should always require the path key" do
341
+ @valid_hash.delete("path")
342
+ Bear.is_valid_file_hash?(@valid_hash).should be_false
343
+ end
344
+
345
+ describe "with file IOs" do
346
+ before :each do
347
+ @stub_file = stub('Stub IO File')
348
+ @valid_hash["file"] = @stub_file
349
+ end
350
+
351
+ it "should accept hashes with the file object that responds to read" do
352
+ @stub_file.should_receive("respond_to?").with(:read).and_return(true)
353
+
354
+ @valid_hash["file"] = @stub_file
355
+ Bear.is_valid_file_hash?(@valid_hash).should be_true
356
+ end
357
+
358
+ it "should not accept hashes with a file object that does not respond to read" do
359
+ @stub_file.should_receive("respond_to?").with(:read).and_return(false)
360
+
361
+ @valid_hash["file"] = @stub_file
362
+ Bear.is_valid_file_hash?(@valid_hash).should be_false
363
+ end
364
+
365
+ end
366
+ end
367
+ end
368
+
369
+ describe "when encoding multipart/form-data params" do
370
+ it "should replace valid file hashes with file objects with UploadIO objects" do
371
+ file_hash_stub = {
372
+ "path" => "Fake File Name",
373
+ "content_type" => "Fake Content Type"
374
+ }
375
+
376
+ # UploadIO should be created
377
+ uploadio_stub = stub("UploadIO Shell Stub")
378
+ UploadIO.should_receive("new").with(file_hash_stub["path"], file_hash_stub["content_type"]).and_return(uploadio_stub)
379
+
380
+ # Ruby 1.9 test compatibility
381
+ content_stub = "UploadIOContent Stub"
382
+ uploadio_stub.stub(:to_ary).and_return([content_stub])
383
+
384
+ args = {
385
+ "not_a_file" => "not a file",
386
+ "file" => file_hash_stub
387
+ }
388
+
389
+ # Check that is_valid_file_hash is called on the file_hash_stub
390
+ Bear.stub!("is_valid_file_hash?").and_return(false)
391
+ Bear.should_receive("is_valid_file_hash?").with(file_hash_stub).and_return(true)
392
+
393
+ result = Bear.encode_multipart_params(args)
394
+
395
+ result["not_a_file"] == args["not_a_file"]
396
+ result["file"] == content_stub
397
+ end
398
+
399
+ it "should replace valid file hashes with file objects with UploadIO objects" do
400
+ file_hash_stub = {
401
+ "file" => "Fake File IO",
402
+ "path" => "Fake File Name",
403
+ "content_type" => "Fake Content Type"
404
+ }
405
+
406
+ # UploadIO should be created
407
+ uploadio_stub = stub("UploadIO Shell Stub")
408
+ UploadIO.should_receive("new").with(file_hash_stub["file"], file_hash_stub["content_type"], file_hash_stub["path"]).and_return(uploadio_stub)
409
+
410
+ # Ruby 1.9 test compatibility
411
+ content_stub = "UploadIOContent Stub"
412
+ uploadio_stub.stub(:to_ary).and_return([content_stub])
413
+
414
+ args = {
415
+ "not_a_file" => "not a file",
416
+ "file" => file_hash_stub
417
+ }
418
+
419
+ # Check that is_valid_file_hash is called on the file_hash_stub
420
+ Bear.stub!("is_valid_file_hash?").and_return(false)
421
+ Bear.should_receive("is_valid_file_hash?").with(file_hash_stub).and_return(true)
422
+
423
+ result = Bear.encode_multipart_params(args)
424
+
425
+ result["not_a_file"] == args["not_a_file"]
426
+ result["file"] == content_stub
427
+ end
428
+ end
185
429
  end
186
430
  end