thoughtbot-paperclip 2.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,455 @@
1
+ require 'test/helper'
2
+
3
+ class Dummy
4
+ # This is a dummy class
5
+ end
6
+
7
+ class AttachmentTest < Test::Unit::TestCase
8
+ context "Attachment default_options" do
9
+ setup do
10
+ rebuild_model
11
+ @old_default_options = Paperclip::Attachment.default_options.dup
12
+ @new_default_options = @old_default_options.merge({
13
+ :path => "argle/bargle",
14
+ :url => "fooferon",
15
+ :default_url => "not here.png"
16
+ })
17
+ end
18
+
19
+ teardown do
20
+ Paperclip::Attachment.default_options.merge! @old_default_options
21
+ end
22
+
23
+ should "be overrideable" do
24
+ Paperclip::Attachment.default_options.merge!(@new_default_options)
25
+ @new_default_options.keys.each do |key|
26
+ assert_equal @new_default_options[key],
27
+ Paperclip::Attachment.default_options[key]
28
+ end
29
+ end
30
+
31
+ context "without an Attachment" do
32
+ setup do
33
+ @dummy = Dummy.new
34
+ end
35
+
36
+ should "return false when asked exists?" do
37
+ assert !@dummy.avatar.exists?
38
+ end
39
+ end
40
+
41
+ context "on an Attachment" do
42
+ setup do
43
+ @dummy = Dummy.new
44
+ @attachment = @dummy.avatar
45
+ end
46
+
47
+ Paperclip::Attachment.default_options.keys.each do |key|
48
+ should "be the default_options for #{key}" do
49
+ assert_equal @old_default_options[key],
50
+ @attachment.instance_variable_get("@#{key}"),
51
+ key
52
+ end
53
+ end
54
+
55
+ context "when redefined" do
56
+ setup do
57
+ Paperclip::Attachment.default_options.merge!(@new_default_options)
58
+ @dummy = Dummy.new
59
+ @attachment = @dummy.avatar
60
+ end
61
+
62
+ Paperclip::Attachment.default_options.keys.each do |key|
63
+ should "be the new default_options for #{key}" do
64
+ assert_equal @new_default_options[key],
65
+ @attachment.instance_variable_get("@#{key}"),
66
+ key
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ context "An attachment with similarly named interpolations" do
74
+ setup do
75
+ rebuild_model :path => ":id.omg/:id-bbq/:idwhat/:id_partition.wtf"
76
+ @dummy = Dummy.new
77
+ @dummy.stubs(:id).returns(1024)
78
+ @file = File.new(File.join(File.dirname(__FILE__),
79
+ "fixtures",
80
+ "5k.png"), 'rb')
81
+ @dummy.avatar = @file
82
+ end
83
+
84
+ should "make sure that they are interpolated correctly" do
85
+ assert_equal "1024.omg/1024-bbq/1024what/000/001/024.wtf", @dummy.avatar.path
86
+ end
87
+ end
88
+
89
+ context "An attachment with a :rails_env interpolation" do
90
+ setup do
91
+ @rails_env = "blah"
92
+ @id = 1024
93
+ rebuild_model :path => ":rails_env/:id.png"
94
+ @dummy = Dummy.new
95
+ @dummy.stubs(:id).returns(@id)
96
+ @file = File.new(File.join(File.dirname(__FILE__),
97
+ "fixtures",
98
+ "5k.png"), 'rb')
99
+ @dummy.avatar = @file
100
+ end
101
+
102
+ should "return the proper path" do
103
+ temporary_rails_env(@rails_env) {
104
+ assert_equal "#{@rails_env}/#{@id}.png", @dummy.avatar.path
105
+ }
106
+ end
107
+ end
108
+
109
+ context "An attachment with :convert_options" do
110
+ setup do
111
+ rebuild_model :styles => {
112
+ :thumb => "100x100",
113
+ :large => "400x400"
114
+ },
115
+ :convert_options => {
116
+ :all => "-do_stuff",
117
+ :thumb => "-thumbnailize"
118
+ }
119
+ @dummy = Dummy.new
120
+ end
121
+
122
+ should "report the correct options when sent #extra_options_for(:thumb)" do
123
+ assert_equal "-thumbnailize -do_stuff", @dummy.avatar.send(:extra_options_for, :thumb), @dummy.avatar.convert_options.inspect
124
+ end
125
+
126
+ should "report the correct options when sent #extra_options_for(:large)" do
127
+ assert_equal "-do_stuff", @dummy.avatar.send(:extra_options_for, :large)
128
+ end
129
+
130
+ context "when given a file" do
131
+ setup do
132
+ @file = File.new(File.join(File.dirname(__FILE__),
133
+ "fixtures",
134
+ "5k.png"), 'rb')
135
+ Paperclip::Thumbnail.stubs(:make)
136
+ [:thumb, :large].each do |style|
137
+ @dummy.avatar.stubs(:extra_options_for).with(style)
138
+ end
139
+ end
140
+
141
+ [:thumb, :large].each do |style|
142
+ should "call extra_options_for(#{style})" do
143
+ @dummy.avatar.expects(:extra_options_for).with(style)
144
+ @dummy.avatar = @file
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ context "Assigning an attachment" do
151
+ setup do
152
+ rebuild_model
153
+
154
+ @not_file = mock
155
+ @not_file.stubs(:nil?).returns(false)
156
+ @not_file.expects(:to_tempfile).returns(self)
157
+ @not_file.expects(:original_filename).returns("filename.png\r\n")
158
+ @not_file.expects(:content_type).returns("image/png\r\n")
159
+ @not_file.expects(:size).returns(10).times(2)
160
+
161
+ @dummy = Dummy.new
162
+ @attachment = @dummy.avatar
163
+ @attachment.expects(:valid_assignment?).with(@not_file).returns(true)
164
+ @attachment.expects(:queue_existing_for_delete)
165
+ @attachment.expects(:post_process)
166
+ @attachment.expects(:validate)
167
+ @dummy.avatar = @not_file
168
+ end
169
+
170
+ should "strip whitespace from original_filename field" do
171
+ assert_equal "filename.png", @dummy.avatar.original_filename
172
+ end
173
+
174
+ should "strip whitespace from content_type field" do
175
+ assert_equal "image/png", @dummy.avatar.instance.avatar_content_type
176
+ end
177
+ end
178
+
179
+ context "Attachment with strange letters" do
180
+ setup do
181
+ rebuild_model
182
+
183
+ @not_file = mock
184
+ @not_file.stubs(:nil?).returns(false)
185
+ @not_file.expects(:to_tempfile).returns(self)
186
+ @not_file.expects(:original_filename).returns("sheep_say_bæ.png\r\n")
187
+ @not_file.expects(:content_type).returns("image/png\r\n")
188
+ @not_file.expects(:size).returns(10).times(2)
189
+
190
+ @dummy = Dummy.new
191
+ @attachment = @dummy.avatar
192
+ @attachment.expects(:valid_assignment?).with(@not_file).returns(true)
193
+ @attachment.expects(:queue_existing_for_delete)
194
+ @attachment.expects(:post_process)
195
+ @attachment.expects(:validate)
196
+ @dummy.avatar = @not_file
197
+ end
198
+
199
+ should "remove strange letters and replace with underscore (_)" do
200
+ assert_equal "sheep_say_b_.png", @dummy.avatar.original_filename
201
+ end
202
+
203
+ end
204
+
205
+ context "An attachment" do
206
+ setup do
207
+ Paperclip::Attachment.default_options.merge!({
208
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
209
+ })
210
+ FileUtils.rm_rf("tmp")
211
+ rebuild_model
212
+ @instance = Dummy.new
213
+ @attachment = Paperclip::Attachment.new(:avatar, @instance)
214
+ @file = File.new(File.join(File.dirname(__FILE__),
215
+ "fixtures",
216
+ "5k.png"), 'rb')
217
+ end
218
+
219
+ should "raise if there are not the correct columns when you try to assign" do
220
+ @other_attachment = Paperclip::Attachment.new(:not_here, @instance)
221
+ assert_raises(Paperclip::PaperclipError) do
222
+ @other_attachment.assign(@file)
223
+ end
224
+ end
225
+
226
+ should "return its default_url when no file assigned" do
227
+ assert @attachment.to_file.nil?
228
+ assert_equal "/avatars/original/missing.png", @attachment.url
229
+ assert_equal "/avatars/blah/missing.png", @attachment.url(:blah)
230
+ end
231
+
232
+ should "return nil as path when no file assigned" do
233
+ assert @attachment.to_file.nil?
234
+ assert_equal nil, @attachment.path
235
+ assert_equal nil, @attachment.path(:blah)
236
+ end
237
+
238
+ context "with a file assigned in the database" do
239
+ setup do
240
+ @attachment.stubs(:instance_read).with(:file_name).returns("5k.png")
241
+ @attachment.stubs(:instance_read).with(:content_type).returns("image/png")
242
+ @attachment.stubs(:instance_read).with(:file_size).returns(12345)
243
+ now = Time.now
244
+ Time.stubs(:now).returns(now)
245
+ @attachment.stubs(:instance_read).with(:updated_at).returns(Time.now)
246
+ end
247
+
248
+ should "return a correct url even if the file does not exist" do
249
+ assert_nil @attachment.to_file
250
+ assert_match %r{^/avatars/#{@instance.id}/blah/5k\.png}, @attachment.url(:blah)
251
+ end
252
+
253
+ should "make sure the updated_at mtime is in the url if it is defined" do
254
+ assert_match %r{#{Time.now.to_i}$}, @attachment.url(:blah)
255
+ end
256
+
257
+ context "with the updated_at field removed" do
258
+ setup do
259
+ @attachment.stubs(:instance_read).with(:updated_at).returns(nil)
260
+ end
261
+
262
+ should "only return the url without the updated_at when sent #url" do
263
+ assert_match "/avatars/#{@instance.id}/blah/5k.png", @attachment.url(:blah)
264
+ end
265
+ end
266
+
267
+ should "return the proper path when filename has a single .'s" do
268
+ assert_equal "./test/../tmp/avatars/dummies/original/#{@instance.id}/5k.png", @attachment.path
269
+ end
270
+
271
+ should "return the proper path when filename has multiple .'s" do
272
+ @attachment.stubs(:instance_read).with(:file_name).returns("5k.old.png")
273
+ assert_equal "./test/../tmp/avatars/dummies/original/#{@instance.id}/5k.old.png", @attachment.path
274
+ end
275
+
276
+ context "when expecting three styles" do
277
+ setup do
278
+ styles = {:styles => { :large => ["400x400", :png],
279
+ :medium => ["100x100", :gif],
280
+ :small => ["32x32#", :jpg]}}
281
+ @attachment = Paperclip::Attachment.new(:avatar,
282
+ @instance,
283
+ styles)
284
+ end
285
+
286
+ context "and assigned a file" do
287
+ setup do
288
+ now = Time.now
289
+ Time.stubs(:now).returns(now)
290
+ @attachment.assign(@file)
291
+ end
292
+
293
+ should "be dirty" do
294
+ assert @attachment.dirty?
295
+ end
296
+
297
+ context "and saved" do
298
+ setup do
299
+ @attachment.save
300
+ end
301
+
302
+ should "return the real url" do
303
+ file = @attachment.to_file
304
+ assert file
305
+ assert_match %r{^/avatars/#{@instance.id}/original/5k\.png}, @attachment.url
306
+ assert_match %r{^/avatars/#{@instance.id}/small/5k\.jpg}, @attachment.url(:small)
307
+ file.close
308
+ end
309
+
310
+ should "commit the files to disk" do
311
+ [:large, :medium, :small].each do |style|
312
+ io = @attachment.to_io(style)
313
+ assert File.exists?(io)
314
+ assert ! io.is_a?(::Tempfile)
315
+ io.close
316
+ end
317
+ end
318
+
319
+ should "save the files as the right formats and sizes" do
320
+ [[:large, 400, 61, "PNG"],
321
+ [:medium, 100, 15, "GIF"],
322
+ [:small, 32, 32, "JPEG"]].each do |style|
323
+ cmd = %Q[identify -format "%w %h %b %m" "#{@attachment.path(style.first)}"]
324
+ out = `#{cmd}`
325
+ width, height, size, format = out.split(" ")
326
+ assert_equal style[1].to_s, width.to_s
327
+ assert_equal style[2].to_s, height.to_s
328
+ assert_equal style[3].to_s, format.to_s
329
+ end
330
+ end
331
+
332
+ should "still have its #file attribute not be nil" do
333
+ assert ! (file = @attachment.to_file).nil?
334
+ file.close
335
+ end
336
+
337
+ context "and deleted" do
338
+ setup do
339
+ @existing_names = @attachment.styles.keys.collect do |style|
340
+ @attachment.path(style)
341
+ end
342
+ @attachment.expects(:instance_write).with(:file_name, nil)
343
+ @attachment.expects(:instance_write).with(:content_type, nil)
344
+ @attachment.expects(:instance_write).with(:file_size, nil)
345
+ @attachment.expects(:instance_write).with(:updated_at, nil)
346
+ @attachment.assign nil
347
+ @attachment.save
348
+ end
349
+
350
+ should "delete the files" do
351
+ @existing_names.each{|f| assert ! File.exists?(f) }
352
+ end
353
+ end
354
+ end
355
+ end
356
+ end
357
+
358
+ end
359
+
360
+ context "when trying a nonexistant storage type" do
361
+ setup do
362
+ rebuild_model :storage => :not_here
363
+ end
364
+
365
+ should "not be able to find the module" do
366
+ assert_raise(NameError){ Dummy.new.avatar }
367
+ end
368
+ end
369
+ end
370
+
371
+ context "An attachment with only a avatar_file_name column" do
372
+ setup do
373
+ ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
374
+ table.column :avatar_file_name, :string
375
+ end
376
+ rebuild_class
377
+ @dummy = Dummy.new
378
+ @file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
379
+ end
380
+
381
+ should "not error when assigned an attachment" do
382
+ assert_nothing_raised { @dummy.avatar = @file }
383
+ end
384
+
385
+ should "return nil when sent #avatar_updated_at" do
386
+ @dummy.avatar = @file
387
+ assert_nil @dummy.avatar.updated_at
388
+ end
389
+
390
+ should "return the right value when sent #avatar_file_size" do
391
+ @dummy.avatar = @file
392
+ assert_equal @file.size, @dummy.avatar.size
393
+ end
394
+
395
+ context "and avatar_updated_at column" do
396
+ setup do
397
+ ActiveRecord::Base.connection.add_column :dummies, :avatar_updated_at, :timestamp
398
+ rebuild_class
399
+ @dummy = Dummy.new
400
+ end
401
+
402
+ should "not error when assigned an attachment" do
403
+ assert_nothing_raised { @dummy.avatar = @file }
404
+ end
405
+
406
+ should "return the right value when sent #avatar_updated_at" do
407
+ now = Time.now
408
+ Time.stubs(:now).returns(now)
409
+ @dummy.avatar = @file
410
+ assert_equal now.to_i, @dummy.avatar.updated_at
411
+ end
412
+ end
413
+
414
+ context "and avatar_content_type column" do
415
+ setup do
416
+ ActiveRecord::Base.connection.add_column :dummies, :avatar_content_type, :string
417
+ rebuild_class
418
+ @dummy = Dummy.new
419
+ end
420
+
421
+ should "not error when assigned an attachment" do
422
+ assert_nothing_raised { @dummy.avatar = @file }
423
+ end
424
+
425
+ should "return the right value when sent #avatar_content_type" do
426
+ @dummy.avatar = @file
427
+ assert_equal "image/png", @dummy.avatar.content_type
428
+ end
429
+ end
430
+
431
+ context "and avatar_file_size column" do
432
+ setup do
433
+ ActiveRecord::Base.connection.add_column :dummies, :avatar_file_size, :integer
434
+ rebuild_class
435
+ @dummy = Dummy.new
436
+ end
437
+
438
+ should "not error when assigned an attachment" do
439
+ assert_nothing_raised { @dummy.avatar = @file }
440
+ end
441
+
442
+ should "return the right value when sent #avatar_file_size" do
443
+ @dummy.avatar = @file
444
+ assert_equal @file.size, @dummy.avatar.size
445
+ end
446
+
447
+ should "return the right value when saved, reloaded, and sent #avatar_file_size" do
448
+ @dummy.avatar = @file
449
+ @dummy.save
450
+ @dummy = Dummy.find(@dummy.id)
451
+ assert_equal @file.size, @dummy.avatar.size
452
+ end
453
+ end
454
+ end
455
+ end