cemeng-paperclip 2.3.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 (62) hide show
  1. data/LICENSE +26 -0
  2. data/README.rdoc +182 -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 +402 -0
  12. data/lib/paperclip/attachment.rb +347 -0
  13. data/lib/paperclip/callback_compatability.rb +61 -0
  14. data/lib/paperclip/command_line.rb +80 -0
  15. data/lib/paperclip/geometry.rb +115 -0
  16. data/lib/paperclip/interpolations.rb +114 -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 +25 -0
  25. data/lib/paperclip/storage.rb +3 -0
  26. data/lib/paperclip/storage/database.rb +204 -0
  27. data/lib/paperclip/storage/filesystem.rb +73 -0
  28. data/lib/paperclip/storage/s3.rb +192 -0
  29. data/lib/paperclip/style.rb +91 -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 +79 -0
  34. data/rails/init.rb +2 -0
  35. data/shoulda_macros/paperclip.rb +118 -0
  36. data/test/attachment_test.rb +804 -0
  37. data/test/command_line_test.rb +133 -0
  38. data/test/database.yml +4 -0
  39. data/test/database_storage_test.rb +267 -0
  40. data/test/fixtures/12k.png +0 -0
  41. data/test/fixtures/50x50.png +0 -0
  42. data/test/fixtures/5k.png +0 -0
  43. data/test/fixtures/bad.png +1 -0
  44. data/test/fixtures/s3.yml +8 -0
  45. data/test/fixtures/text.txt +0 -0
  46. data/test/fixtures/twopage.pdf +0 -0
  47. data/test/geometry_test.rb +177 -0
  48. data/test/helper.rb +146 -0
  49. data/test/integration_test.rb +482 -0
  50. data/test/interpolations_test.rb +127 -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 +254 -0
  57. data/test/processor_test.rb +10 -0
  58. data/test/storage_test.rb +363 -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 +186 -0
@@ -0,0 +1,146 @@
1
+ require 'rubygems'
2
+ require 'tempfile'
3
+ require 'test/unit'
4
+
5
+ require 'shoulda'
6
+ require 'mocha'
7
+
8
+ require 'active_record'
9
+ require 'active_record/version'
10
+ require 'active_support'
11
+
12
+ puts "Testing against version #{ActiveRecord::VERSION::STRING}"
13
+
14
+ `ruby -e 'exit 0'` # Prime $? with a value.
15
+
16
+ begin
17
+ require 'ruby-debug'
18
+ rescue LoadError => e
19
+ puts "debugger disabled"
20
+ end
21
+
22
+ ROOT = File.join(File.dirname(__FILE__), '..')
23
+
24
+ def silence_warnings
25
+ old_verbose, $VERBOSE = $VERBOSE, nil
26
+ yield
27
+ ensure
28
+ $VERBOSE = old_verbose
29
+ end
30
+
31
+ class Test::Unit::TestCase
32
+ def setup
33
+ silence_warnings do
34
+ Object.const_set(:Rails, stub('Rails', :root => ROOT, :env => 'test'))
35
+ end
36
+ end
37
+ end
38
+
39
+ $LOAD_PATH << File.join(ROOT, 'lib')
40
+ $LOAD_PATH << File.join(ROOT, 'lib', 'paperclip')
41
+
42
+ require File.join(ROOT, 'lib', 'paperclip.rb')
43
+
44
+ require './shoulda_macros/paperclip'
45
+
46
+ FIXTURES_DIR = File.join(File.dirname(__FILE__), "fixtures")
47
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
48
+ ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FILE__) + "/debug.log")
49
+ ActiveRecord::Base.establish_connection(config['test'])
50
+
51
+ def reset_class class_name
52
+ ActiveRecord::Base.send(:include, Paperclip::Glue)
53
+ Object.send(:remove_const, class_name) rescue nil
54
+ klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
55
+ klass.class_eval{ include Paperclip::Glue }
56
+ klass
57
+ end
58
+
59
+ def reset_table table_name, &block
60
+ block ||= lambda { |table| true }
61
+ ActiveRecord::Base.connection.create_table :dummies, {:force => true}, &block
62
+ end
63
+
64
+ def modify_table table_name, &block
65
+ ActiveRecord::Base.connection.change_table :dummies, &block
66
+ end
67
+
68
+ def rebuild_model options = {}
69
+ ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
70
+ table.column :other, :string
71
+ table.column :avatar_file_name, :string
72
+ table.column :avatar_content_type, :string
73
+ table.column :avatar_file_size, :integer
74
+ table.column :avatar_updated_at, :datetime
75
+ table.column :avatar_fingerprint, :string
76
+ end
77
+ rebuild_class options
78
+ end
79
+
80
+ def rebuild_class options = {}
81
+ ActiveRecord::Base.send(:include, Paperclip::Glue)
82
+ Object.send(:remove_const, "Dummy") rescue nil
83
+ Object.const_set("Dummy", Class.new(ActiveRecord::Base))
84
+ Dummy.class_eval do
85
+ include Paperclip::Glue
86
+ has_attached_file :avatar, options
87
+ end
88
+ end
89
+
90
+ class FakeModel
91
+ attr_accessor :avatar_file_name,
92
+ :avatar_file_size,
93
+ :avatar_last_updated,
94
+ :avatar_content_type,
95
+ :avatar_fingerprint,
96
+ :id
97
+
98
+ def errors
99
+ @errors ||= []
100
+ end
101
+
102
+ def run_paperclip_callbacks name, *args
103
+ end
104
+
105
+ end
106
+
107
+ def attachment options
108
+ Paperclip::Attachment.new(:avatar, FakeModel.new, options)
109
+ end
110
+
111
+ def silence_warnings
112
+ old_verbose, $VERBOSE = $VERBOSE, nil
113
+ yield
114
+ ensure
115
+ $VERBOSE = old_verbose
116
+ end
117
+
118
+ def should_accept_dummy_class
119
+ should "accept the class" do
120
+ assert_accepts @matcher, @dummy_class
121
+ end
122
+
123
+ should "accept an instance of that class" do
124
+ assert_accepts @matcher, @dummy_class.new
125
+ end
126
+ end
127
+
128
+ def should_reject_dummy_class
129
+ should "reject the class" do
130
+ assert_rejects @matcher, @dummy_class
131
+ end
132
+
133
+ should "reject an instance of that class" do
134
+ assert_rejects @matcher, @dummy_class.new
135
+ end
136
+ end
137
+
138
+ def with_exitstatus_returning(code)
139
+ saved_exitstatus = $?.nil? ? 0 : $?.exitstatus
140
+ begin
141
+ `ruby -e 'exit #{code.to_i}'`
142
+ yield
143
+ ensure
144
+ `ruby -e 'exit #{saved_exitstatus.to_i}'`
145
+ end
146
+ end
@@ -0,0 +1,482 @@
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 "redefining its attachment styles" do
39
+ setup do
40
+ Dummy.class_eval do
41
+ has_attached_file :avatar, :styles => { :thumb => "150x25#" }
42
+ has_attached_file :avatar, :styles => { :thumb => "150x25#", :dynamic => lambda { |a| '50x50#' } }
43
+ end
44
+ @d2 = Dummy.find(@dummy.id)
45
+ @d2.avatar.reprocess!
46
+ @d2.save
47
+ end
48
+
49
+ should "create its thumbnails properly" do
50
+ assert_match /\b150x25\b/, `identify "#{@dummy.avatar.path(:thumb)}"`
51
+ assert_match /\b50x50\b/, `identify "#{@dummy.avatar.path(:dynamic)}"`
52
+ end
53
+ end
54
+ end
55
+
56
+ context "A model that modifies its original" do
57
+ setup do
58
+ rebuild_model :styles => { :original => "2x2#" }
59
+ @dummy = Dummy.new
60
+ @file = File.new(File.join(File.dirname(__FILE__),
61
+ "fixtures",
62
+ "5k.png"), 'rb')
63
+ @dummy.avatar = @file
64
+ end
65
+
66
+ should "report the file size of the processed file and not the original" do
67
+ assert_not_equal @file.size, @dummy.avatar.size
68
+ end
69
+
70
+ teardown { @file.close }
71
+ end
72
+
73
+ context "A model with attachments scoped under an id" do
74
+ setup do
75
+ rebuild_model :styles => { :large => "100x100",
76
+ :medium => "50x50" },
77
+ :path => ":rails_root/tmp/:id/:attachments/:style.:extension"
78
+ @dummy = Dummy.new
79
+ @file = File.new(File.join(File.dirname(__FILE__),
80
+ "fixtures",
81
+ "5k.png"), 'rb')
82
+ @dummy.avatar = @file
83
+ end
84
+
85
+ teardown { @file.close }
86
+
87
+ context "when saved" do
88
+ setup do
89
+ @dummy.save
90
+ @saved_path = @dummy.avatar.path(:large)
91
+ end
92
+
93
+ should "have a large file in the right place" do
94
+ assert File.exists?(@dummy.avatar.path(:large))
95
+ end
96
+
97
+ context "and deleted" do
98
+ setup do
99
+ @dummy.avatar.clear
100
+ @dummy.save
101
+ end
102
+
103
+ should "not have a large file in the right place anymore" do
104
+ assert ! File.exists?(@saved_path)
105
+ end
106
+
107
+ should "not have its next two parent directories" do
108
+ assert ! File.exists?(File.dirname(@saved_path))
109
+ assert ! File.exists?(File.dirname(File.dirname(@saved_path)))
110
+ end
111
+
112
+ before_should "not die if an unexpected SystemCallError happens" do
113
+ FileUtils.stubs(:rmdir).raises(Errno::EPIPE)
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ context "A model with no attachment validation" do
120
+ setup do
121
+ rebuild_model :styles => { :large => "300x300>",
122
+ :medium => "100x100",
123
+ :thumb => ["32x32#", :gif] },
124
+ :default_style => :medium,
125
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
126
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
127
+ @dummy = Dummy.new
128
+ end
129
+
130
+ should "have its definition return false when asked about whiny_thumbnails" do
131
+ assert ! Dummy.attachment_definitions[:avatar][:whiny_thumbnails]
132
+ end
133
+
134
+ context "when validates_attachment_thumbnails is called" do
135
+ setup do
136
+ Dummy.validates_attachment_thumbnails :avatar
137
+ end
138
+
139
+ should "have its definition return true when asked about whiny_thumbnails" do
140
+ assert_equal true, Dummy.attachment_definitions[:avatar][:whiny_thumbnails]
141
+ end
142
+ end
143
+
144
+ context "redefined to have attachment validations" do
145
+ setup do
146
+ rebuild_model :styles => { :large => "300x300>",
147
+ :medium => "100x100",
148
+ :thumb => ["32x32#", :gif] },
149
+ :whiny_thumbnails => true,
150
+ :default_style => :medium,
151
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
152
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
153
+ end
154
+
155
+ should "have its definition return true when asked about whiny_thumbnails" do
156
+ assert_equal true, Dummy.attachment_definitions[:avatar][:whiny_thumbnails]
157
+ end
158
+ end
159
+ end
160
+
161
+ context "A model with no convert_options setting" do
162
+ setup do
163
+ rebuild_model :styles => { :large => "300x300>",
164
+ :medium => "100x100",
165
+ :thumb => ["32x32#", :gif] },
166
+ :default_style => :medium,
167
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
168
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
169
+ @dummy = Dummy.new
170
+ end
171
+
172
+ should "have its definition return nil when asked about convert_options" do
173
+ assert ! Dummy.attachment_definitions[:avatar][:convert_options]
174
+ end
175
+
176
+ context "redefined to have convert_options setting" do
177
+ setup do
178
+ rebuild_model :styles => { :large => "300x300>",
179
+ :medium => "100x100",
180
+ :thumb => ["32x32#", :gif] },
181
+ :convert_options => "-strip -depth 8",
182
+ :default_style => :medium,
183
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
184
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
185
+ end
186
+
187
+ should "have its definition return convert_options value when asked about convert_options" do
188
+ assert_equal "-strip -depth 8", Dummy.attachment_definitions[:avatar][:convert_options]
189
+ end
190
+ end
191
+ end
192
+
193
+ context "A model with a filesystem attachment" do
194
+ setup do
195
+ rebuild_model :styles => { :large => "300x300>",
196
+ :medium => "100x100",
197
+ :thumb => ["32x32#", :gif] },
198
+ :whiny_thumbnails => true,
199
+ :default_style => :medium,
200
+ :url => "/:attachment/:class/:style/:id/:basename.:extension",
201
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
202
+ @dummy = Dummy.new
203
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
204
+ @bad_file = File.new(File.join(FIXTURES_DIR, "bad.png"), 'rb')
205
+
206
+ assert @dummy.avatar = @file
207
+ assert @dummy.valid?, @dummy.errors.full_messages.join(", ")
208
+ assert @dummy.save
209
+ end
210
+
211
+ should "write and delete its files" do
212
+ [["434x66", :original],
213
+ ["300x46", :large],
214
+ ["100x15", :medium],
215
+ ["32x32", :thumb]].each do |geo, style|
216
+ cmd = %Q[identify -format "%wx%h" "#{@dummy.avatar.path(style)}"]
217
+ assert_equal geo, `#{cmd}`.chomp, cmd
218
+ end
219
+
220
+ saved_paths = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.path(s) }
221
+
222
+ @d2 = Dummy.find(@dummy.id)
223
+ assert_equal "100x15", `identify -format "%wx%h" "#{@d2.avatar.path}"`.chomp
224
+ assert_equal "434x66", `identify -format "%wx%h" "#{@d2.avatar.path(:original)}"`.chomp
225
+ assert_equal "300x46", `identify -format "%wx%h" "#{@d2.avatar.path(:large)}"`.chomp
226
+ assert_equal "100x15", `identify -format "%wx%h" "#{@d2.avatar.path(:medium)}"`.chomp
227
+ assert_equal "32x32", `identify -format "%wx%h" "#{@d2.avatar.path(:thumb)}"`.chomp
228
+
229
+ @dummy.avatar = "not a valid file but not nil"
230
+ assert_equal File.basename(@file.path), @dummy.avatar_file_name
231
+ assert @dummy.valid?
232
+ assert @dummy.save
233
+
234
+ saved_paths.each do |p|
235
+ assert File.exists?(p)
236
+ end
237
+
238
+ @dummy.avatar.clear
239
+ assert_nil @dummy.avatar_file_name
240
+ assert @dummy.valid?
241
+ assert @dummy.save
242
+
243
+ saved_paths.each do |p|
244
+ assert ! File.exists?(p)
245
+ end
246
+
247
+ @d2 = Dummy.find(@dummy.id)
248
+ assert_nil @d2.avatar_file_name
249
+ end
250
+
251
+ should "work exactly the same when new as when reloaded" do
252
+ @d2 = Dummy.find(@dummy.id)
253
+
254
+ assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
255
+ [:thumb, :medium, :large, :original].each do |style|
256
+ assert_equal @dummy.avatar.path(style), @d2.avatar.path(style)
257
+ end
258
+
259
+ saved_paths = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.path(s) }
260
+
261
+ @d2.avatar.clear
262
+ assert @d2.save
263
+
264
+ saved_paths.each do |p|
265
+ assert ! File.exists?(p)
266
+ end
267
+ end
268
+
269
+ should "know the difference between good files, bad files, and not files" do
270
+ expected = @dummy.avatar.to_file
271
+ @dummy.avatar = "not a file"
272
+ assert @dummy.valid?
273
+ assert_equal expected.path, @dummy.avatar.path
274
+ expected.close
275
+
276
+ @dummy.avatar = @bad_file
277
+ assert ! @dummy.valid?
278
+ end
279
+
280
+ should "know the difference between good files, bad files, and not files when validating" do
281
+ Dummy.validates_attachment_presence :avatar
282
+ @d2 = Dummy.find(@dummy.id)
283
+ @d2.avatar = @file
284
+ assert @d2.valid?, @d2.errors.full_messages.inspect
285
+ @d2.avatar = @bad_file
286
+ assert ! @d2.valid?
287
+ end
288
+
289
+ should "be able to reload without saving and not have the file disappear" do
290
+ @dummy.avatar = @file
291
+ assert @dummy.save
292
+ @dummy.avatar.clear
293
+ assert_nil @dummy.avatar_file_name
294
+ @dummy.reload
295
+ assert_equal "5k.png", @dummy.avatar_file_name
296
+ end
297
+
298
+ context "that is assigned its file from another Paperclip attachment" do
299
+ setup do
300
+ @dummy2 = Dummy.new
301
+ @file2 = File.new(File.join(FIXTURES_DIR, "12k.png"), 'rb')
302
+ assert @dummy2.avatar = @file2
303
+ @dummy2.save
304
+ end
305
+
306
+ should "work when assigned a file" do
307
+ assert_not_equal `identify -format "%wx%h" "#{@dummy.avatar.path(:original)}"`,
308
+ `identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
309
+
310
+ assert @dummy.avatar = @dummy2.avatar
311
+ @dummy.save
312
+ assert_equal `identify -format "%wx%h" "#{@dummy.avatar.path(:original)}"`,
313
+ `identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
314
+ end
315
+ end
316
+
317
+ end
318
+
319
+ context "A model with an attachments association and a Paperclip attachment" do
320
+ setup do
321
+ Dummy.class_eval do
322
+ has_many :attachments, :class_name => 'Dummy'
323
+ end
324
+
325
+ @dummy = Dummy.new
326
+ @dummy.avatar = File.new(File.join(File.dirname(__FILE__),
327
+ "fixtures",
328
+ "5k.png"), 'rb')
329
+ end
330
+
331
+ should "should not error when saving" do
332
+ assert_nothing_raised do
333
+ @dummy.save!
334
+ end
335
+ end
336
+ end
337
+
338
+ if ENV['S3_TEST_BUCKET']
339
+ def s3_files_for attachment
340
+ [:thumb, :medium, :large, :original].inject({}) do |files, style|
341
+ data = `curl "#{attachment.url(style)}" 2>/dev/null`.chomp
342
+ t = Tempfile.new("paperclip-test")
343
+ t.binmode
344
+ t.write(data)
345
+ t.rewind
346
+ files[style] = t
347
+ files
348
+ end
349
+ end
350
+
351
+ def s3_headers_for attachment, style
352
+ `curl --head "#{attachment.url(style)}" 2>/dev/null`.split("\n").inject({}) do |h,head|
353
+ split_head = head.chomp.split(/\s*:\s*/, 2)
354
+ h[split_head.first.downcase] = split_head.last unless split_head.empty?
355
+ h
356
+ end
357
+ end
358
+
359
+ context "A model with an S3 attachment" do
360
+ setup do
361
+ rebuild_model :styles => { :large => "300x300>",
362
+ :medium => "100x100",
363
+ :thumb => ["32x32#", :gif] },
364
+ :storage => :s3,
365
+ :whiny_thumbnails => true,
366
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "s3.yml")),
367
+ :default_style => :medium,
368
+ :bucket => ENV['S3_TEST_BUCKET'],
369
+ :path => ":class/:attachment/:id/:style/:basename.:extension"
370
+ @dummy = Dummy.new
371
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
372
+ @bad_file = File.new(File.join(FIXTURES_DIR, "bad.png"), 'rb')
373
+
374
+ assert @dummy.avatar = @file
375
+ assert @dummy.valid?
376
+ assert @dummy.save
377
+
378
+ @files_on_s3 = s3_files_for @dummy.avatar
379
+ end
380
+
381
+ should "have the same contents as the original" do
382
+ @file.rewind
383
+ assert_equal @file.read, @files_on_s3[:original].read
384
+ end
385
+
386
+ should "write and delete its files" do
387
+ [["434x66", :original],
388
+ ["300x46", :large],
389
+ ["100x15", :medium],
390
+ ["32x32", :thumb]].each do |geo, style|
391
+ cmd = %Q[identify -format "%wx%h" "#{@files_on_s3[style].path}"]
392
+ assert_equal geo, `#{cmd}`.chomp, cmd
393
+ end
394
+
395
+ @d2 = Dummy.find(@dummy.id)
396
+ @d2_files = s3_files_for @d2.avatar
397
+ [["434x66", :original],
398
+ ["300x46", :large],
399
+ ["100x15", :medium],
400
+ ["32x32", :thumb]].each do |geo, style|
401
+ cmd = %Q[identify -format "%wx%h" "#{@d2_files[style].path}"]
402
+ assert_equal geo, `#{cmd}`.chomp, cmd
403
+ end
404
+
405
+ @dummy.avatar = "not a valid file but not nil"
406
+ assert_equal File.basename(@file.path), @dummy.avatar_file_name
407
+ assert @dummy.valid?
408
+ assert @dummy.save
409
+
410
+ [:thumb, :medium, :large, :original].each do |style|
411
+ assert @dummy.avatar.exists?(style)
412
+ end
413
+
414
+ @dummy.avatar.clear
415
+ assert_nil @dummy.avatar_file_name
416
+ assert @dummy.valid?
417
+ assert @dummy.save
418
+
419
+ [:thumb, :medium, :large, :original].each do |style|
420
+ assert ! @dummy.avatar.exists?(style)
421
+ end
422
+
423
+ @d2 = Dummy.find(@dummy.id)
424
+ assert_nil @d2.avatar_file_name
425
+ end
426
+
427
+ should "work exactly the same when new as when reloaded" do
428
+ @d2 = Dummy.find(@dummy.id)
429
+
430
+ assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
431
+ [:thumb, :medium, :large, :original].each do |style|
432
+ assert_equal @dummy.avatar.to_file(style).read, @d2.avatar.to_file(style).read
433
+ end
434
+
435
+ saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
436
+
437
+ @d2.avatar.clear
438
+ assert @d2.save
439
+
440
+ [:thumb, :medium, :large, :original].each do |style|
441
+ assert ! @dummy.avatar.exists?(style)
442
+ end
443
+ end
444
+
445
+ should "know the difference between good files, bad files, not files, and nil" do
446
+ expected = @dummy.avatar.to_file
447
+ @dummy.avatar = "not a file"
448
+ assert @dummy.valid?
449
+ assert_equal expected.read, @dummy.avatar.to_file.read
450
+
451
+ @dummy.avatar = @bad_file
452
+ assert ! @dummy.valid?
453
+ @dummy.avatar = nil
454
+ assert @dummy.valid?
455
+
456
+ Dummy.validates_attachment_presence :avatar
457
+ @d2 = Dummy.find(@dummy.id)
458
+ @d2.avatar = @file
459
+ assert @d2.valid?
460
+ @d2.avatar = @bad_file
461
+ assert ! @d2.valid?
462
+ @d2.avatar = nil
463
+ assert ! @d2.valid?
464
+ end
465
+
466
+ should "be able to reload without saving and not have the file disappear" do
467
+ @dummy.avatar = @file
468
+ assert @dummy.save
469
+ @dummy.avatar = nil
470
+ assert_nil @dummy.avatar_file_name
471
+ @dummy.reload
472
+ assert_equal "5k.png", @dummy.avatar_file_name
473
+ end
474
+
475
+ should "have the right content type" do
476
+ headers = s3_headers_for(@dummy.avatar, :original)
477
+ assert_equal 'image/png', headers['content-type']
478
+ end
479
+ end
480
+ end
481
+ end
482
+