cloudfuji_paperclip 2.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. data/.gitignore +22 -0
  2. data/.travis.yml +13 -0
  3. data/Appraisals +14 -0
  4. data/CONTRIBUTING.md +38 -0
  5. data/Gemfile +5 -0
  6. data/Gemfile.lock +137 -0
  7. data/LICENSE +26 -0
  8. data/README.md +444 -0
  9. data/Rakefile +41 -0
  10. data/cucumber/paperclip_steps.rb +6 -0
  11. data/features/basic_integration.feature +46 -0
  12. data/features/rake_tasks.feature +63 -0
  13. data/features/step_definitions/attachment_steps.rb +65 -0
  14. data/features/step_definitions/html_steps.rb +15 -0
  15. data/features/step_definitions/rails_steps.rb +182 -0
  16. data/features/step_definitions/s3_steps.rb +14 -0
  17. data/features/step_definitions/web_steps.rb +209 -0
  18. data/features/support/env.rb +8 -0
  19. data/features/support/fakeweb.rb +3 -0
  20. data/features/support/fixtures/.boot_config.rb.swo +0 -0
  21. data/features/support/fixtures/boot_config.txt +15 -0
  22. data/features/support/fixtures/gemfile.txt +5 -0
  23. data/features/support/fixtures/preinitializer.txt +20 -0
  24. data/features/support/paths.rb +28 -0
  25. data/features/support/rails.rb +46 -0
  26. data/features/support/selectors.rb +19 -0
  27. data/gemfiles/rails2.gemfile +9 -0
  28. data/gemfiles/rails3.gemfile +9 -0
  29. data/gemfiles/rails3_1.gemfile +9 -0
  30. data/generators/paperclip/USAGE +5 -0
  31. data/generators/paperclip/paperclip_generator.rb +27 -0
  32. data/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  33. data/init.rb +4 -0
  34. data/lib/generators/paperclip/USAGE +8 -0
  35. data/lib/generators/paperclip/paperclip_generator.rb +33 -0
  36. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  37. data/lib/paperclip/attachment.rb +468 -0
  38. data/lib/paperclip/callback_compatibility.rb +61 -0
  39. data/lib/paperclip/geometry.rb +120 -0
  40. data/lib/paperclip/interpolations.rb +174 -0
  41. data/lib/paperclip/iostream.rb +45 -0
  42. data/lib/paperclip/matchers/have_attached_file_matcher.rb +57 -0
  43. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +81 -0
  44. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +54 -0
  45. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +95 -0
  46. data/lib/paperclip/matchers.rb +64 -0
  47. data/lib/paperclip/missing_attachment_styles.rb +87 -0
  48. data/lib/paperclip/processor.rb +58 -0
  49. data/lib/paperclip/railtie.rb +31 -0
  50. data/lib/paperclip/schema.rb +39 -0
  51. data/lib/paperclip/storage/filesystem.rb +81 -0
  52. data/lib/paperclip/storage/fog.rb +174 -0
  53. data/lib/paperclip/storage/s3.rb +333 -0
  54. data/lib/paperclip/storage.rb +3 -0
  55. data/lib/paperclip/style.rb +103 -0
  56. data/lib/paperclip/thumbnail.rb +105 -0
  57. data/lib/paperclip/upfile.rb +62 -0
  58. data/lib/paperclip/url_generator.rb +64 -0
  59. data/lib/paperclip/version.rb +3 -0
  60. data/lib/paperclip.rb +487 -0
  61. data/lib/tasks/paperclip.rake +101 -0
  62. data/paperclip.gemspec +41 -0
  63. data/rails/init.rb +2 -0
  64. data/shoulda_macros/paperclip.rb +124 -0
  65. data/test/.gitignore +1 -0
  66. data/test/attachment_test.rb +1116 -0
  67. data/test/database.yml +4 -0
  68. data/test/fixtures/12k.png +0 -0
  69. data/test/fixtures/50x50.png +0 -0
  70. data/test/fixtures/5k.png +0 -0
  71. data/test/fixtures/animated.gif +0 -0
  72. data/test/fixtures/bad.png +1 -0
  73. data/test/fixtures/fog.yml +8 -0
  74. data/test/fixtures/question?mark.png +0 -0
  75. data/test/fixtures/s3.yml +8 -0
  76. data/test/fixtures/spaced file.png +0 -0
  77. data/test/fixtures/text.txt +1 -0
  78. data/test/fixtures/twopage.pdf +0 -0
  79. data/test/fixtures/uppercase.PNG +0 -0
  80. data/test/geometry_test.rb +206 -0
  81. data/test/helper.rb +177 -0
  82. data/test/integration_test.rb +654 -0
  83. data/test/interpolations_test.rb +216 -0
  84. data/test/iostream_test.rb +71 -0
  85. data/test/matchers/have_attached_file_matcher_test.rb +24 -0
  86. data/test/matchers/validate_attachment_content_type_matcher_test.rb +87 -0
  87. data/test/matchers/validate_attachment_presence_matcher_test.rb +26 -0
  88. data/test/matchers/validate_attachment_size_matcher_test.rb +51 -0
  89. data/test/paperclip_missing_attachment_styles_test.rb +80 -0
  90. data/test/paperclip_test.rb +390 -0
  91. data/test/processor_test.rb +10 -0
  92. data/test/schema_test.rb +98 -0
  93. data/test/storage/filesystem_test.rb +56 -0
  94. data/test/storage/fog_test.rb +219 -0
  95. data/test/storage/s3_live_test.rb +138 -0
  96. data/test/storage/s3_test.rb +943 -0
  97. data/test/style_test.rb +209 -0
  98. data/test/support/mock_attachment.rb +22 -0
  99. data/test/support/mock_interpolator.rb +24 -0
  100. data/test/support/mock_model.rb +2 -0
  101. data/test/support/mock_url_generator_builder.rb +27 -0
  102. data/test/thumbnail_test.rb +383 -0
  103. data/test/upfile_test.rb +53 -0
  104. data/test/url_generator_test.rb +187 -0
  105. metadata +404 -0
@@ -0,0 +1,390 @@
1
+ require './test/helper'
2
+
3
+ class PaperclipTest < Test::Unit::TestCase
4
+ context "Calling Paperclip.run" do
5
+ setup do
6
+ Paperclip.options[:log_command] = false
7
+ Cocaine::CommandLine.expects(:new).with("convert", "stuff", {}).returns(stub(:run))
8
+ @original_command_line_path = Cocaine::CommandLine.path
9
+ end
10
+
11
+ teardown do
12
+ Paperclip.options[:log_command] = true
13
+ Cocaine::CommandLine.path = @original_command_line_path
14
+ end
15
+
16
+ should "run the command with Cocaine" do
17
+ Paperclip.run("convert", "stuff")
18
+ end
19
+
20
+ should "save Cocaine::CommandLine.path that set before" do
21
+ Cocaine::CommandLine.path = "/opt/my_app/bin"
22
+ Paperclip.run("convert", "stuff")
23
+ assert_equal [Cocaine::CommandLine.path].flatten.include?("/opt/my_app/bin"), true
24
+ end
25
+ end
26
+
27
+ context "Calling Paperclip.run with a logger" do
28
+ should "pass the defined logger if :log_command is set" do
29
+ Paperclip.options[:log_command] = true
30
+ Cocaine::CommandLine.expects(:new).with("convert", "stuff", :logger => Paperclip.logger).returns(stub(:run))
31
+ Paperclip.run("convert", "stuff")
32
+ end
33
+ end
34
+
35
+ context "Paperclip.each_instance_with_attachment" do
36
+ setup do
37
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
38
+ d1 = Dummy.create(:avatar => @file)
39
+ d2 = Dummy.create
40
+ d3 = Dummy.create(:avatar => @file)
41
+ @expected = [d1, d3]
42
+ end
43
+ should "yield every instance of a model that has an attachment" do
44
+ actual = []
45
+ Paperclip.each_instance_with_attachment("Dummy", "avatar") do |instance|
46
+ actual << instance
47
+ end
48
+ assert_same_elements @expected, actual
49
+ end
50
+ end
51
+
52
+ should "raise when sent #processor and the name of a class that doesn't exist" do
53
+ assert_raises(NameError){ Paperclip.processor(:boogey_man) }
54
+ end
55
+
56
+ should "return a class when sent #processor and the name of a class under Paperclip" do
57
+ assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
58
+ end
59
+
60
+ should "get a class from a namespaced class name" do
61
+ class ::One; class Two; end; end
62
+ assert_equal ::One::Two, Paperclip.class_for("One::Two")
63
+ end
64
+
65
+ should "raise when class doesn't exist in specified namespace" do
66
+ class ::Three; end
67
+ class ::Four; end
68
+ assert_raise NameError do
69
+ Paperclip.class_for("Three::Four")
70
+ end
71
+ end
72
+
73
+ context "Attachments with clashing URLs should raise error" do
74
+ setup do
75
+ class Dummy2 < ActiveRecord::Base
76
+ include Paperclip::Glue
77
+ end
78
+ end
79
+
80
+ should "generate warning if attachment is redefined with the same url string" do
81
+ Paperclip.expects(:log).with("Duplicate URL for blah with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in Dummy class")
82
+ Dummy.class_eval do
83
+ has_attached_file :blah
84
+ end
85
+ Dummy2.class_eval do
86
+ has_attached_file :blah
87
+ end
88
+ end
89
+
90
+ should "not generate warning if attachment is redifined with the same url string but has :class in it" do
91
+ Paperclip.expects(:log).never
92
+ Dummy.class_eval do
93
+ has_attached_file :blah, :url => "/system/:class/:attachment/:id/:style/:filename"
94
+ end
95
+ Dummy2.class_eval do
96
+ has_attached_file :blah, :url => "/system/:class/:attachment/:id/:style/:filename"
97
+ end
98
+ end
99
+ end
100
+
101
+ context "An ActiveRecord model with an 'avatar' attachment" do
102
+ setup do
103
+ rebuild_model :path => "tmp/:class/omg/:style.:extension"
104
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
105
+ end
106
+
107
+ teardown { @file.close }
108
+
109
+ should "not error when trying to also create a 'blah' attachment" do
110
+ assert_nothing_raised do
111
+ Dummy.class_eval do
112
+ has_attached_file :blah
113
+ end
114
+ end
115
+ end
116
+
117
+ context "that is attr_protected" do
118
+ setup do
119
+ Dummy.class_eval do
120
+ attr_protected :avatar
121
+ end
122
+ @dummy = Dummy.new
123
+ end
124
+
125
+ should "not assign the avatar on mass-set" do
126
+ @dummy.attributes = { :other => "I'm set!",
127
+ :avatar => @file }
128
+
129
+ assert_equal "I'm set!", @dummy.other
130
+ assert ! @dummy.avatar?
131
+ end
132
+
133
+ should "still allow assigment on normal set" do
134
+ @dummy.other = "I'm set!"
135
+ @dummy.avatar = @file
136
+
137
+ assert_equal "I'm set!", @dummy.other
138
+ assert @dummy.avatar?
139
+ end
140
+ end
141
+
142
+ context "with a subclass" do
143
+ setup do
144
+ class ::SubDummy < Dummy; end
145
+ end
146
+
147
+ should "be able to use the attachment from the subclass" do
148
+ assert_nothing_raised do
149
+ @subdummy = SubDummy.create(:avatar => @file)
150
+ end
151
+ end
152
+
153
+ should "be able to see the attachment definition from the subclass's class" do
154
+ assert_equal "tmp/:class/omg/:style.:extension",
155
+ SubDummy.attachment_definitions[:avatar][:path]
156
+ end
157
+
158
+ teardown do
159
+ Object.send(:remove_const, "SubDummy") rescue nil
160
+ end
161
+ end
162
+
163
+ should "have an #avatar method" do
164
+ assert Dummy.new.respond_to?(:avatar)
165
+ end
166
+
167
+ should "have an #avatar= method" do
168
+ assert Dummy.new.respond_to?(:avatar=)
169
+ end
170
+
171
+ context "that is valid" do
172
+ setup do
173
+ @dummy = Dummy.new
174
+ @dummy.avatar = @file
175
+ end
176
+
177
+ should "be valid" do
178
+ assert @dummy.valid?
179
+ end
180
+ end
181
+
182
+ context "a validation with an if guard clause" do
183
+ context "as a lambda" do
184
+ setup do
185
+ Dummy.send(:"validates_attachment_presence", :avatar, :if => lambda{|i| i.foo })
186
+ @dummy = Dummy.new
187
+ @dummy.stubs(:avatar_file_name).returns(nil)
188
+ end
189
+
190
+ should "attempt validation if the guard returns true" do
191
+ @dummy.expects(:foo).returns(true)
192
+ assert ! @dummy.valid?
193
+ end
194
+
195
+ should "not attempt validation if the guard returns false" do
196
+ @dummy.expects(:foo).returns(false)
197
+ assert @dummy.valid?
198
+ end
199
+ end
200
+
201
+ context "as a method name" do
202
+ setup do
203
+ Dummy.send(:"validates_attachment_presence", :avatar, :if => :foo)
204
+ @dummy = Dummy.new
205
+ @dummy.stubs(:avatar_file_name).returns(nil)
206
+ end
207
+
208
+ should "attempt validation if the guard returns true" do
209
+ @dummy.expects(:foo).returns(true)
210
+ assert ! @dummy.valid?
211
+ end
212
+
213
+ should "not attempt validation if the guard returns false" do
214
+ @dummy.expects(:foo).returns(false)
215
+ assert @dummy.valid?
216
+ end
217
+ end
218
+ end
219
+
220
+ context "a validation with an unless guard clause" do
221
+ context "as a lambda" do
222
+ setup do
223
+ Dummy.send(:"validates_attachment_presence", :avatar, :unless => lambda{|i| i.foo })
224
+ @dummy = Dummy.new
225
+ @dummy.stubs(:avatar_file_name).returns(nil)
226
+ end
227
+
228
+ should "attempt validation if the guard returns true" do
229
+ @dummy.expects(:foo).returns(false)
230
+ assert ! @dummy.valid?
231
+ end
232
+
233
+ should "not attempt validation if the guard returns false" do
234
+ @dummy.expects(:foo).returns(true)
235
+ assert @dummy.valid?
236
+ end
237
+ end
238
+
239
+ context "as a method name" do
240
+ setup do
241
+ Dummy.send(:"validates_attachment_presence", :avatar, :unless => :foo)
242
+ @dummy = Dummy.new
243
+ @dummy.stubs(:avatar_file_name).returns(nil)
244
+ end
245
+
246
+ should "attempt validation if the guard returns true" do
247
+ @dummy.expects(:foo).returns(false)
248
+ assert ! @dummy.valid?
249
+ end
250
+
251
+ should "not attempt validation if the guard returns false" do
252
+ @dummy.expects(:foo).returns(true)
253
+ assert @dummy.valid?
254
+ end
255
+ end
256
+ end
257
+
258
+ should "not have Attachment in the ActiveRecord::Base namespace" do
259
+ assert_raises(NameError) do
260
+ ActiveRecord::Base::Attachment
261
+ end
262
+ end
263
+
264
+ def self.should_validate validation, options, valid_file, invalid_file
265
+ context "with #{validation} validation and #{options.inspect} options" do
266
+ setup do
267
+ rebuild_class
268
+ Dummy.send(:"validates_attachment_#{validation}", :avatar, options)
269
+ @dummy = Dummy.new
270
+ end
271
+ context "and assigning nil" do
272
+ setup do
273
+ @dummy.avatar = nil
274
+ @dummy.valid?
275
+ end
276
+ if validation == :presence
277
+ should "have an error on the attachment" do
278
+ assert @dummy.errors[:avatar]
279
+ assert @dummy.errors[:avatar_file_name]
280
+ end
281
+ else
282
+ should "not have an error on the attachment" do
283
+ assert @dummy.errors.blank?, @dummy.errors.full_messages.join(", ")
284
+ end
285
+ end
286
+ end
287
+ context "and assigned a valid file" do
288
+ setup do
289
+ @dummy.avatar = valid_file
290
+ @dummy.valid?
291
+ end
292
+ should "not have an error" do
293
+ assert_equal 0, @dummy.errors.size, @dummy.errors.full_messages.join(", ")
294
+ end
295
+ end
296
+ context "and assigned an invalid file" do
297
+ setup do
298
+ @dummy.avatar = invalid_file
299
+ @dummy.valid?
300
+ end
301
+ should "have an error" do
302
+ assert @dummy.errors.size > 0
303
+ end
304
+ end
305
+ end
306
+ end
307
+
308
+ [[:presence, {}, "5k.png", nil],
309
+ [:size, {:in => 1..10240}, "5k.png", "12k.png"],
310
+ [:size, {:less_than => 10240}, "5k.png", "12k.png"],
311
+ [:size, {:greater_than => 8096}, "12k.png", "5k.png"],
312
+ [:content_type, {:content_type => "image/png"}, "5k.png", "text.txt"],
313
+ [:content_type, {:content_type => "text/plain"}, "text.txt", "5k.png"],
314
+ [:content_type, {:content_type => %r{image/.*}}, "5k.png", "text.txt"]].each do |args|
315
+ validation, options, valid_file, invalid_file = args
316
+ valid_file &&= File.open(File.join(FIXTURES_DIR, valid_file), "rb")
317
+ invalid_file &&= File.open(File.join(FIXTURES_DIR, invalid_file), "rb")
318
+
319
+ should_validate validation, options, valid_file, invalid_file
320
+ end
321
+
322
+ context "with content_type validation and lambda message" do
323
+ context "and assigned an invalid file" do
324
+ setup do
325
+ Dummy.send(:"validates_attachment_content_type", :avatar, :content_type => %r{image/.*}, :message => lambda {'lambda content type message'})
326
+ @dummy = Dummy.new
327
+ @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "text.txt"), "rb")
328
+ @dummy.valid?
329
+ end
330
+
331
+ should "have a content type error message" do
332
+ assert [@dummy.errors[:avatar_content_type]].flatten.any?{|error| error =~ %r/lambda content type message/ }
333
+ end
334
+ end
335
+ end
336
+
337
+ context "with size validation and less_than 10240 option" do
338
+ context "and assigned an invalid file" do
339
+ setup do
340
+ Dummy.send(:"validates_attachment_size", :avatar, :less_than => 10240)
341
+ @dummy = Dummy.new
342
+ @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "12k.png"), "rb")
343
+ @dummy.valid?
344
+ end
345
+
346
+ should "have a file size min/max error message" do
347
+ assert [@dummy.errors[:avatar_file_size]].flatten.any?{|error| error =~ %r/between 0 and 10240 bytes/ }
348
+ end
349
+ end
350
+ end
351
+
352
+ context "with size validation and less_than 10240 option with lambda message" do
353
+ context "and assigned an invalid file" do
354
+ setup do
355
+ Dummy.send(:"validates_attachment_size", :avatar, :less_than => 10240, :message => lambda {'lambda between 0 and 10240 bytes'})
356
+ @dummy = Dummy.new
357
+ @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "12k.png"), "rb")
358
+ @dummy.valid?
359
+ end
360
+
361
+ should "have a file size min/max error message" do
362
+ assert [@dummy.errors[:avatar_file_size]].flatten.any?{|error| error =~ %r/lambda between 0 and 10240 bytes/ }
363
+ end
364
+ end
365
+ end
366
+
367
+ end
368
+
369
+ context "configuring a custom processor" do
370
+ setup do
371
+ @freedom_processor = Class.new do
372
+ def make(file, options = {}, attachment = nil)
373
+ file
374
+ end
375
+ end.new
376
+
377
+ Paperclip.configure do |config|
378
+ config.register_processor(:freedom, @freedom_processor)
379
+ end
380
+ end
381
+
382
+ should "be able to find the custom processor" do
383
+ assert_equal @freedom_processor, Paperclip.processor(:freedom)
384
+ end
385
+
386
+ teardown do
387
+ Paperclip.clear_processors!
388
+ end
389
+ end
390
+ end
@@ -0,0 +1,10 @@
1
+ require './test/helper'
2
+
3
+ class ProcessorTest < Test::Unit::TestCase
4
+ should "instantiate and call #make when sent #make to the class" do
5
+ processor = mock
6
+ processor.expects(:make).with()
7
+ Paperclip::Processor.expects(:new).with(:one, :two, :three).returns(processor)
8
+ Paperclip::Processor.make(:one, :two, :three)
9
+ end
10
+ end
@@ -0,0 +1,98 @@
1
+ require './test/helper'
2
+ require 'paperclip/schema'
3
+
4
+ class MockSchema
5
+ include Paperclip::Schema
6
+
7
+ def initialize(table_name = nil)
8
+ @table_name = table_name
9
+ @columns = {}
10
+ @deleted_columns = []
11
+ end
12
+
13
+ def column(name, type)
14
+ @columns[name] = type
15
+ end
16
+
17
+ def remove_column(table_name, column_name)
18
+ return if @table_name && @table_name != table_name
19
+ @columns.delete(column_name)
20
+ @deleted_columns.push(column_name)
21
+ end
22
+
23
+ def has_column?(column_name)
24
+ @columns.key?(column_name)
25
+ end
26
+
27
+ def deleted_column?(column_name)
28
+ @deleted_columns.include?(column_name)
29
+ end
30
+
31
+ def type_of(column_name)
32
+ @columns[column_name]
33
+ end
34
+ end
35
+
36
+ class SchemaTest < Test::Unit::TestCase
37
+ context "Migrating up" do
38
+ setup do
39
+ @schema = MockSchema.new
40
+ @schema.has_attached_file :avatar
41
+ end
42
+
43
+ should "create the file_name column" do
44
+ assert @schema.has_column?(:avatar_file_name)
45
+ end
46
+
47
+ should "create the content_type column" do
48
+ assert @schema.has_column?(:avatar_content_type)
49
+ end
50
+
51
+ should "create the file_size column" do
52
+ assert @schema.has_column?(:avatar_file_size)
53
+ end
54
+
55
+ should "create the updated_at column" do
56
+ assert @schema.has_column?(:avatar_updated_at)
57
+ end
58
+
59
+ should "make the file_name column a string" do
60
+ assert_equal :string, @schema.type_of(:avatar_file_name)
61
+ end
62
+
63
+ should "make the content_type column a string" do
64
+ assert_equal :string, @schema.type_of(:avatar_content_type)
65
+ end
66
+
67
+ should "make the file_size column an integer" do
68
+ assert_equal :integer, @schema.type_of(:avatar_file_size)
69
+ end
70
+
71
+ should "make the updated_at column a datetime" do
72
+ assert_equal :datetime, @schema.type_of(:avatar_updated_at)
73
+ end
74
+ end
75
+
76
+ context "Migrating down" do
77
+ setup do
78
+ @schema = MockSchema.new(:users)
79
+ @schema.drop_attached_file :users, :avatar
80
+ end
81
+
82
+ should "remove the file_name column" do
83
+ assert @schema.deleted_column?(:avatar_file_name)
84
+ end
85
+
86
+ should "remove the content_type column" do
87
+ assert @schema.deleted_column?(:avatar_content_type)
88
+ end
89
+
90
+ should "remove the file_size column" do
91
+ assert @schema.deleted_column?(:avatar_file_size)
92
+ end
93
+
94
+ should "remove the updated_at column" do
95
+ assert @schema.deleted_column?(:avatar_updated_at)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,56 @@
1
+ require './test/helper'
2
+
3
+ class FileSystemTest < Test::Unit::TestCase
4
+ context "Filesystem" do
5
+ setup do
6
+ rebuild_model :styles => { :thumbnail => "25x25#" }
7
+ @dummy = Dummy.create!
8
+
9
+ @dummy.avatar = File.open(fixture_file('5k.png'))
10
+ end
11
+
12
+ should "allow file assignment" do
13
+ assert @dummy.save
14
+ end
15
+
16
+ should "store the original" do
17
+ @dummy.save
18
+ assert File.exists?(@dummy.avatar.path)
19
+ end
20
+
21
+ should "store the thumbnail" do
22
+ @dummy.save
23
+ assert File.exists?(@dummy.avatar.path(:thumbnail))
24
+ end
25
+
26
+ should "clean up file objects" do
27
+ File.stubs(:exist?).returns(true)
28
+ Paperclip::Tempfile.any_instance.expects(:close).at_least_once()
29
+ Paperclip::Tempfile.any_instance.expects(:unlink).at_least_once()
30
+
31
+ @dummy.save!
32
+ end
33
+
34
+ context "with file that has space in file name" do
35
+ setup do
36
+ rebuild_model :styles => { :thumbnail => "25x25#" }
37
+ @dummy = Dummy.create!
38
+
39
+ @dummy.avatar = File.open(fixture_file('spaced file.png'))
40
+ @dummy.save
41
+ end
42
+
43
+ should "store the file" do
44
+ assert File.exists?(@dummy.avatar.path)
45
+ end
46
+
47
+ should "store the path unescaped" do
48
+ assert_match /\/spaced file\.png/, @dummy.avatar.path
49
+ end
50
+
51
+ should "return an escaped version of URL" do
52
+ assert_match /\/spaced%20file\.png/, @dummy.avatar.url
53
+ end
54
+ end
55
+ end
56
+ end