paperclip-youtube 2.3.8.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 (62) hide show
  1. data/LICENSE +26 -0
  2. data/README.md +91 -0
  3. data/Rakefile +80 -0
  4. data/generators/paperclip/USAGE +5 -0
  5. data/generators/paperclip/paperclip_generator.rb +27 -0
  6. data/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  7. data/init.rb +1 -0
  8. data/lib/generators/paperclip/USAGE +8 -0
  9. data/lib/generators/paperclip/paperclip_generator.rb +31 -0
  10. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  11. data/lib/paperclip.rb +378 -0
  12. data/lib/paperclip/attachment.rb +376 -0
  13. data/lib/paperclip/callback_compatability.rb +61 -0
  14. data/lib/paperclip/command_line.rb +86 -0
  15. data/lib/paperclip/geometry.rb +115 -0
  16. data/lib/paperclip/interpolations.rb +130 -0
  17. data/lib/paperclip/iostream.rb +45 -0
  18. data/lib/paperclip/matchers.rb +33 -0
  19. data/lib/paperclip/matchers/have_attached_file_matcher.rb +57 -0
  20. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +75 -0
  21. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +54 -0
  22. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +95 -0
  23. data/lib/paperclip/processor.rb +58 -0
  24. data/lib/paperclip/railtie.rb +24 -0
  25. data/lib/paperclip/storage.rb +3 -0
  26. data/lib/paperclip/storage/filesystem.rb +73 -0
  27. data/lib/paperclip/storage/s3.rb +192 -0
  28. data/lib/paperclip/storage/youtube.rb +331 -0
  29. data/lib/paperclip/style.rb +90 -0
  30. data/lib/paperclip/thumbnail.rb +79 -0
  31. data/lib/paperclip/upfile.rb +55 -0
  32. data/lib/paperclip/version.rb +3 -0
  33. data/lib/tasks/paperclip.rake +72 -0
  34. data/rails/init.rb +2 -0
  35. data/shoulda_macros/paperclip.rb +118 -0
  36. data/test/attachment_test.rb +921 -0
  37. data/test/command_line_test.rb +138 -0
  38. data/test/database.yml +4 -0
  39. data/test/fixtures/12k.png +0 -0
  40. data/test/fixtures/50x50.png +0 -0
  41. data/test/fixtures/5k.png +0 -0
  42. data/test/fixtures/bad.png +1 -0
  43. data/test/fixtures/s3.yml +8 -0
  44. data/test/fixtures/text.txt +0 -0
  45. data/test/fixtures/twopage.pdf +0 -0
  46. data/test/fixtures/uppercase.PNG +0 -0
  47. data/test/geometry_test.rb +177 -0
  48. data/test/helper.rb +146 -0
  49. data/test/integration_test.rb +570 -0
  50. data/test/interpolations_test.rb +143 -0
  51. data/test/iostream_test.rb +71 -0
  52. data/test/matchers/have_attached_file_matcher_test.rb +24 -0
  53. data/test/matchers/validate_attachment_content_type_matcher_test.rb +47 -0
  54. data/test/matchers/validate_attachment_presence_matcher_test.rb +26 -0
  55. data/test/matchers/validate_attachment_size_matcher_test.rb +51 -0
  56. data/test/paperclip_test.rb +301 -0
  57. data/test/processor_test.rb +10 -0
  58. data/test/storage_test.rb +386 -0
  59. data/test/style_test.rb +141 -0
  60. data/test/thumbnail_test.rb +227 -0
  61. data/test/upfile_test.rb +36 -0
  62. metadata +195 -0
@@ -0,0 +1,570 @@
1
+ require './test/helper'
2
+
3
+ class IntegrationTest < Test::Unit::TestCase
4
+ context "Many models at once" do
5
+ setup do
6
+ rebuild_model
7
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
8
+ 300.times do |i|
9
+ Dummy.create! :avatar => @file
10
+ end
11
+ end
12
+
13
+ should "not exceed the open file limit" do
14
+ assert_nothing_raised do
15
+ dummies = Dummy.find(:all)
16
+ dummies.each { |dummy| dummy.avatar }
17
+ end
18
+ end
19
+ end
20
+
21
+ context "An attachment" do
22
+ setup do
23
+ rebuild_model :styles => { :thumb => "50x50#" }
24
+ @dummy = Dummy.new
25
+ @file = File.new(File.join(File.dirname(__FILE__),
26
+ "fixtures",
27
+ "5k.png"), 'rb')
28
+ @dummy.avatar = @file
29
+ assert @dummy.save
30
+ end
31
+
32
+ teardown { @file.close }
33
+
34
+ should "create its thumbnails properly" do
35
+ assert_match /\b50x50\b/, `identify "#{@dummy.avatar.path(:thumb)}"`
36
+ end
37
+
38
+ context 'reprocessing with unreadable original' do
39
+ setup { File.chmod(0000, @dummy.avatar.path) }
40
+
41
+ should "not raise an error" do
42
+ assert_nothing_raised do
43
+ @dummy.avatar.reprocess!
44
+ end
45
+ end
46
+
47
+ should "return false" do
48
+ assert ! @dummy.avatar.reprocess!
49
+ end
50
+
51
+ teardown { File.chmod(0644, @dummy.avatar.path) }
52
+ end
53
+
54
+ context "redefining its attachment styles" do
55
+ setup do
56
+ Dummy.class_eval do
57
+ has_attached_file :avatar, :styles => { :thumb => "150x25#" }
58
+ has_attached_file :avatar, :styles => { :thumb => "150x25#", :dynamic => lambda { |a| '50x50#' } }
59
+ end
60
+ @d2 = Dummy.find(@dummy.id)
61
+ @d2.avatar.reprocess!
62
+ @d2.save
63
+ end
64
+
65
+ should "create its thumbnails properly" do
66
+ assert_match /\b150x25\b/, `identify "#{@dummy.avatar.path(:thumb)}"`
67
+ assert_match /\b50x50\b/, `identify "#{@dummy.avatar.path(:dynamic)}"`
68
+ end
69
+ end
70
+ end
71
+
72
+ context "Attachment" do
73
+ setup do
74
+ @thumb_path = "./test/../public/system/avatars/1/thumb/5k.png"
75
+ File.delete(@thumb_path) if File.exists?(@thumb_path)
76
+ rebuild_model :styles => { :thumb => "50x50#" }
77
+ @dummy = Dummy.new
78
+ @file = File.new(File.join(File.dirname(__FILE__),
79
+ "fixtures",
80
+ "5k.png"), 'rb')
81
+
82
+ end
83
+
84
+ teardown { @file.close }
85
+
86
+ should "not create the thumbnails upon saving when post-processing is disabled" do
87
+ @dummy.avatar.post_processing = false
88
+ @dummy.avatar = @file
89
+ assert @dummy.save
90
+ assert !File.exists?(@thumb_path)
91
+ end
92
+
93
+ should "create the thumbnails upon saving when post_processing is enabled" do
94
+ @dummy.avatar.post_processing = true
95
+ @dummy.avatar = @file
96
+ assert @dummy.save
97
+ assert File.exists?(@thumb_path)
98
+ end
99
+ end
100
+
101
+ context "Attachment with no generated thumbnails" do
102
+ setup do
103
+ @thumb_small_path = "./test/../public/system/avatars/1/thumb_small/5k.png"
104
+ @thumb_large_path = "./test/../public/system/avatars/1/thumb_large/5k.png"
105
+ File.delete(@thumb_small_path) if File.exists?(@thumb_small_path)
106
+ File.delete(@thumb_large_path) if File.exists?(@thumb_large_path)
107
+ rebuild_model :styles => { :thumb_small => "50x50#", :thumb_large => "60x60#" }
108
+ @dummy = Dummy.new
109
+ @file = File.new(File.join(File.dirname(__FILE__),
110
+ "fixtures",
111
+ "5k.png"), 'rb')
112
+
113
+ @dummy.avatar.post_processing = false
114
+ @dummy.avatar = @file
115
+ assert @dummy.save
116
+ @dummy.avatar.post_processing = true
117
+ end
118
+
119
+ teardown { @file.close }
120
+
121
+ should "allow us to create all thumbnails in one go" do
122
+ assert !File.exists?(@thumb_small_path)
123
+ assert !File.exists?(@thumb_large_path)
124
+
125
+ @dummy.avatar.reprocess!
126
+
127
+ assert File.exists?(@thumb_small_path)
128
+ assert File.exists?(@thumb_large_path)
129
+ end
130
+
131
+ should "allow us to selectively create each thumbnail" do
132
+ assert !File.exists?(@thumb_small_path)
133
+ assert !File.exists?(@thumb_large_path)
134
+
135
+ @dummy.avatar.reprocess! :thumb_small
136
+ assert File.exists?(@thumb_small_path)
137
+ assert !File.exists?(@thumb_large_path)
138
+
139
+ @dummy.avatar.reprocess! :thumb_large
140
+ assert File.exists?(@thumb_large_path)
141
+ end
142
+ end
143
+
144
+ context "A model that modifies its original" do
145
+ setup do
146
+ rebuild_model :styles => { :original => "2x2#" }
147
+ @dummy = Dummy.new
148
+ @file = File.new(File.join(File.dirname(__FILE__),
149
+ "fixtures",
150
+ "5k.png"), 'rb')
151
+ @dummy.avatar = @file
152
+ end
153
+
154
+ should "report the file size of the processed file and not the original" do
155
+ assert_not_equal @file.size, @dummy.avatar.size
156
+ end
157
+
158
+ teardown { @file.close }
159
+ end
160
+
161
+ context "A model with attachments scoped under an id" do
162
+ setup do
163
+ rebuild_model :styles => { :large => "100x100",
164
+ :medium => "50x50" },
165
+ :path => ":rails_root/tmp/:id/:attachments/:style.:extension"
166
+ @dummy = Dummy.new
167
+ @file = File.new(File.join(File.dirname(__FILE__),
168
+ "fixtures",
169
+ "5k.png"), 'rb')
170
+ @dummy.avatar = @file
171
+ end
172
+
173
+ teardown { @file.close }
174
+
175
+ context "when saved" do
176
+ setup do
177
+ @dummy.save
178
+ @saved_path = @dummy.avatar.path(:large)
179
+ end
180
+
181
+ should "have a large file in the right place" do
182
+ assert File.exists?(@dummy.avatar.path(:large))
183
+ end
184
+
185
+ context "and deleted" do
186
+ setup do
187
+ @dummy.avatar.clear
188
+ @dummy.save
189
+ end
190
+
191
+ should "not have a large file in the right place anymore" do
192
+ assert ! File.exists?(@saved_path)
193
+ end
194
+
195
+ should "not have its next two parent directories" do
196
+ assert ! File.exists?(File.dirname(@saved_path))
197
+ assert ! File.exists?(File.dirname(File.dirname(@saved_path)))
198
+ end
199
+
200
+ before_should "not die if an unexpected SystemCallError happens" do
201
+ FileUtils.stubs(:rmdir).raises(Errno::EPIPE)
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ context "A model with no attachment validation" do
208
+ setup do
209
+ rebuild_model :styles => { :large => "300x300>",
210
+ :medium => "100x100",
211
+ :thumb => ["32x32#", :gif] },
212
+ :default_style => :medium,
213
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
214
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
215
+ @dummy = Dummy.new
216
+ end
217
+
218
+ should "have its definition return false when asked about whiny_thumbnails" do
219
+ assert ! Dummy.attachment_definitions[:avatar][:whiny_thumbnails]
220
+ end
221
+
222
+ context "when validates_attachment_thumbnails is called" do
223
+ setup do
224
+ Dummy.validates_attachment_thumbnails :avatar
225
+ end
226
+
227
+ should "have its definition return true when asked about whiny_thumbnails" do
228
+ assert_equal true, Dummy.attachment_definitions[:avatar][:whiny_thumbnails]
229
+ end
230
+ end
231
+
232
+ context "redefined to have attachment validations" do
233
+ setup do
234
+ rebuild_model :styles => { :large => "300x300>",
235
+ :medium => "100x100",
236
+ :thumb => ["32x32#", :gif] },
237
+ :whiny_thumbnails => true,
238
+ :default_style => :medium,
239
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
240
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
241
+ end
242
+
243
+ should "have its definition return true when asked about whiny_thumbnails" do
244
+ assert_equal true, Dummy.attachment_definitions[:avatar][:whiny_thumbnails]
245
+ end
246
+ end
247
+ end
248
+
249
+ context "A model with no convert_options setting" do
250
+ setup do
251
+ rebuild_model :styles => { :large => "300x300>",
252
+ :medium => "100x100",
253
+ :thumb => ["32x32#", :gif] },
254
+ :default_style => :medium,
255
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
256
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
257
+ @dummy = Dummy.new
258
+ end
259
+
260
+ should "have its definition return nil when asked about convert_options" do
261
+ assert ! Dummy.attachment_definitions[:avatar][:convert_options]
262
+ end
263
+
264
+ context "redefined to have convert_options setting" do
265
+ setup do
266
+ rebuild_model :styles => { :large => "300x300>",
267
+ :medium => "100x100",
268
+ :thumb => ["32x32#", :gif] },
269
+ :convert_options => "-strip -depth 8",
270
+ :default_style => :medium,
271
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
272
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
273
+ end
274
+
275
+ should "have its definition return convert_options value when asked about convert_options" do
276
+ assert_equal "-strip -depth 8", Dummy.attachment_definitions[:avatar][:convert_options]
277
+ end
278
+ end
279
+ end
280
+
281
+ context "A model with a filesystem attachment" do
282
+ setup do
283
+ rebuild_model :styles => { :large => "300x300>",
284
+ :medium => "100x100",
285
+ :thumb => ["32x32#", :gif] },
286
+ :whiny_thumbnails => true,
287
+ :default_style => :medium,
288
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
289
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
290
+ @dummy = Dummy.new
291
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
292
+ @bad_file = File.new(File.join(FIXTURES_DIR, "bad.png"), 'rb')
293
+
294
+ assert @dummy.avatar = @file
295
+ assert @dummy.valid?, @dummy.errors.full_messages.join(", ")
296
+ assert @dummy.save
297
+ end
298
+
299
+ should "write and delete its files" do
300
+ [["434x66", :original],
301
+ ["300x46", :large],
302
+ ["100x15", :medium],
303
+ ["32x32", :thumb]].each do |geo, style|
304
+ cmd = %Q[identify -format "%wx%h" "#{@dummy.avatar.path(style)}"]
305
+ assert_equal geo, `#{cmd}`.chomp, cmd
306
+ end
307
+
308
+ saved_paths = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.path(s) }
309
+
310
+ @d2 = Dummy.find(@dummy.id)
311
+ assert_equal "100x15", `identify -format "%wx%h" "#{@d2.avatar.path}"`.chomp
312
+ assert_equal "434x66", `identify -format "%wx%h" "#{@d2.avatar.path(:original)}"`.chomp
313
+ assert_equal "300x46", `identify -format "%wx%h" "#{@d2.avatar.path(:large)}"`.chomp
314
+ assert_equal "100x15", `identify -format "%wx%h" "#{@d2.avatar.path(:medium)}"`.chomp
315
+ assert_equal "32x32", `identify -format "%wx%h" "#{@d2.avatar.path(:thumb)}"`.chomp
316
+
317
+ @dummy.avatar = "not a valid file but not nil"
318
+ assert_equal File.basename(@file.path), @dummy.avatar_file_name
319
+ assert @dummy.valid?
320
+ assert @dummy.save
321
+
322
+ saved_paths.each do |p|
323
+ assert File.exists?(p)
324
+ end
325
+
326
+ @dummy.avatar.clear
327
+ assert_nil @dummy.avatar_file_name
328
+ assert @dummy.valid?
329
+ assert @dummy.save
330
+
331
+ saved_paths.each do |p|
332
+ assert ! File.exists?(p)
333
+ end
334
+
335
+ @d2 = Dummy.find(@dummy.id)
336
+ assert_nil @d2.avatar_file_name
337
+ end
338
+
339
+ should "work exactly the same when new as when reloaded" do
340
+ @d2 = Dummy.find(@dummy.id)
341
+
342
+ assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
343
+ [:thumb, :medium, :large, :original].each do |style|
344
+ assert_equal @dummy.avatar.path(style), @d2.avatar.path(style)
345
+ end
346
+
347
+ saved_paths = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.path(s) }
348
+
349
+ @d2.avatar.clear
350
+ assert @d2.save
351
+
352
+ saved_paths.each do |p|
353
+ assert ! File.exists?(p)
354
+ end
355
+ end
356
+
357
+ should "know the difference between good files, bad files, and not files" do
358
+ expected = @dummy.avatar.to_file
359
+ @dummy.avatar = "not a file"
360
+ assert @dummy.valid?
361
+ assert_equal expected.path, @dummy.avatar.path
362
+ expected.close
363
+
364
+ @dummy.avatar = @bad_file
365
+ assert ! @dummy.valid?
366
+ end
367
+
368
+ should "know the difference between good files, bad files, and not files when validating" do
369
+ Dummy.validates_attachment_presence :avatar
370
+ @d2 = Dummy.find(@dummy.id)
371
+ @d2.avatar = @file
372
+ assert @d2.valid?, @d2.errors.full_messages.inspect
373
+ @d2.avatar = @bad_file
374
+ assert ! @d2.valid?
375
+ end
376
+
377
+ should "be able to reload without saving and not have the file disappear" do
378
+ @dummy.avatar = @file
379
+ assert @dummy.save
380
+ @dummy.avatar.clear
381
+ assert_nil @dummy.avatar_file_name
382
+ @dummy.reload
383
+ assert_equal "5k.png", @dummy.avatar_file_name
384
+ end
385
+
386
+ context "that is assigned its file from another Paperclip attachment" do
387
+ setup do
388
+ @dummy2 = Dummy.new
389
+ @file2 = File.new(File.join(FIXTURES_DIR, "12k.png"), 'rb')
390
+ assert @dummy2.avatar = @file2
391
+ @dummy2.save
392
+ end
393
+
394
+ should "work when assigned a file" do
395
+ assert_not_equal `identify -format "%wx%h" "#{@dummy.avatar.path(:original)}"`,
396
+ `identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
397
+
398
+ assert @dummy.avatar = @dummy2.avatar
399
+ @dummy.save
400
+ assert_equal `identify -format "%wx%h" "#{@dummy.avatar.path(:original)}"`,
401
+ `identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
402
+ end
403
+ end
404
+
405
+ end
406
+
407
+ context "A model with an attachments association and a Paperclip attachment" do
408
+ setup do
409
+ Dummy.class_eval do
410
+ has_many :attachments, :class_name => 'Dummy'
411
+ end
412
+
413
+ @dummy = Dummy.new
414
+ @dummy.avatar = File.new(File.join(File.dirname(__FILE__),
415
+ "fixtures",
416
+ "5k.png"), 'rb')
417
+ end
418
+
419
+ should "should not error when saving" do
420
+ assert_nothing_raised do
421
+ @dummy.save!
422
+ end
423
+ end
424
+ end
425
+
426
+ if ENV['S3_TEST_BUCKET']
427
+ def s3_files_for attachment
428
+ [:thumb, :medium, :large, :original].inject({}) do |files, style|
429
+ data = `curl "#{attachment.url(style)}" 2>/dev/null`.chomp
430
+ t = Tempfile.new("paperclip-test")
431
+ t.binmode
432
+ t.write(data)
433
+ t.rewind
434
+ files[style] = t
435
+ files
436
+ end
437
+ end
438
+
439
+ def s3_headers_for attachment, style
440
+ `curl --head "#{attachment.url(style)}" 2>/dev/null`.split("\n").inject({}) do |h,head|
441
+ split_head = head.chomp.split(/\s*:\s*/, 2)
442
+ h[split_head.first.downcase] = split_head.last unless split_head.empty?
443
+ h
444
+ end
445
+ end
446
+
447
+ context "A model with an S3 attachment" do
448
+ setup do
449
+ rebuild_model :styles => { :large => "300x300>",
450
+ :medium => "100x100",
451
+ :thumb => ["32x32#", :gif] },
452
+ :storage => :s3,
453
+ :whiny_thumbnails => true,
454
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "s3.yml")),
455
+ :default_style => :medium,
456
+ :bucket => ENV['S3_TEST_BUCKET'],
457
+ :path => ":class/:attachment/:id/:style/:basename.:extension"
458
+ @dummy = Dummy.new
459
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
460
+ @bad_file = File.new(File.join(FIXTURES_DIR, "bad.png"), 'rb')
461
+
462
+ assert @dummy.avatar = @file
463
+ assert @dummy.valid?
464
+ assert @dummy.save
465
+
466
+ @files_on_s3 = s3_files_for @dummy.avatar
467
+ end
468
+
469
+ should "have the same contents as the original" do
470
+ @file.rewind
471
+ assert_equal @file.read, @files_on_s3[:original].read
472
+ end
473
+
474
+ should "write and delete its files" do
475
+ [["434x66", :original],
476
+ ["300x46", :large],
477
+ ["100x15", :medium],
478
+ ["32x32", :thumb]].each do |geo, style|
479
+ cmd = %Q[identify -format "%wx%h" "#{@files_on_s3[style].path}"]
480
+ assert_equal geo, `#{cmd}`.chomp, cmd
481
+ end
482
+
483
+ @d2 = Dummy.find(@dummy.id)
484
+ @d2_files = s3_files_for @d2.avatar
485
+ [["434x66", :original],
486
+ ["300x46", :large],
487
+ ["100x15", :medium],
488
+ ["32x32", :thumb]].each do |geo, style|
489
+ cmd = %Q[identify -format "%wx%h" "#{@d2_files[style].path}"]
490
+ assert_equal geo, `#{cmd}`.chomp, cmd
491
+ end
492
+
493
+ @dummy.avatar = "not a valid file but not nil"
494
+ assert_equal File.basename(@file.path), @dummy.avatar_file_name
495
+ assert @dummy.valid?
496
+ assert @dummy.save
497
+
498
+ [:thumb, :medium, :large, :original].each do |style|
499
+ assert @dummy.avatar.exists?(style)
500
+ end
501
+
502
+ @dummy.avatar.clear
503
+ assert_nil @dummy.avatar_file_name
504
+ assert @dummy.valid?
505
+ assert @dummy.save
506
+
507
+ [:thumb, :medium, :large, :original].each do |style|
508
+ assert ! @dummy.avatar.exists?(style)
509
+ end
510
+
511
+ @d2 = Dummy.find(@dummy.id)
512
+ assert_nil @d2.avatar_file_name
513
+ end
514
+
515
+ should "work exactly the same when new as when reloaded" do
516
+ @d2 = Dummy.find(@dummy.id)
517
+
518
+ assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
519
+ [:thumb, :medium, :large, :original].each do |style|
520
+ assert_equal @dummy.avatar.to_file(style).read, @d2.avatar.to_file(style).read
521
+ end
522
+
523
+ saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
524
+
525
+ @d2.avatar.clear
526
+ assert @d2.save
527
+
528
+ [:thumb, :medium, :large, :original].each do |style|
529
+ assert ! @dummy.avatar.exists?(style)
530
+ end
531
+ end
532
+
533
+ should "know the difference between good files, bad files, not files, and nil" do
534
+ expected = @dummy.avatar.to_file
535
+ @dummy.avatar = "not a file"
536
+ assert @dummy.valid?
537
+ assert_equal expected.read, @dummy.avatar.to_file.read
538
+
539
+ @dummy.avatar = @bad_file
540
+ assert ! @dummy.valid?
541
+ @dummy.avatar = nil
542
+ assert @dummy.valid?
543
+
544
+ Dummy.validates_attachment_presence :avatar
545
+ @d2 = Dummy.find(@dummy.id)
546
+ @d2.avatar = @file
547
+ assert @d2.valid?
548
+ @d2.avatar = @bad_file
549
+ assert ! @d2.valid?
550
+ @d2.avatar = nil
551
+ assert ! @d2.valid?
552
+ end
553
+
554
+ should "be able to reload without saving and not have the file disappear" do
555
+ @dummy.avatar = @file
556
+ assert @dummy.save
557
+ @dummy.avatar = nil
558
+ assert_nil @dummy.avatar_file_name
559
+ @dummy.reload
560
+ assert_equal "5k.png", @dummy.avatar_file_name
561
+ end
562
+
563
+ should "have the right content type" do
564
+ headers = s3_headers_for(@dummy.avatar, :original)
565
+ assert_equal 'image/png', headers['content-type']
566
+ end
567
+ end
568
+ end
569
+ end
570
+