cloudfuji_paperclip 2.4.6

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 (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