mender_paperclip 2.4.3
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.
- data/LICENSE +26 -0
- data/README.md +402 -0
- data/Rakefile +86 -0
- data/generators/paperclip/USAGE +5 -0
- data/generators/paperclip/paperclip_generator.rb +27 -0
- data/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
- data/init.rb +4 -0
- data/lib/generators/paperclip/USAGE +8 -0
- data/lib/generators/paperclip/paperclip_generator.rb +33 -0
- data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
- data/lib/paperclip/attachment.rb +454 -0
- data/lib/paperclip/callback_compatibility.rb +61 -0
- data/lib/paperclip/geometry.rb +120 -0
- data/lib/paperclip/interpolations.rb +181 -0
- data/lib/paperclip/iostream.rb +45 -0
- data/lib/paperclip/matchers/have_attached_file_matcher.rb +57 -0
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +81 -0
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +54 -0
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +95 -0
- data/lib/paperclip/matchers.rb +33 -0
- data/lib/paperclip/missing_attachment_styles.rb +87 -0
- data/lib/paperclip/options.rb +79 -0
- data/lib/paperclip/processor.rb +58 -0
- data/lib/paperclip/railtie.rb +26 -0
- data/lib/paperclip/storage/filesystem.rb +81 -0
- data/lib/paperclip/storage/fog.rb +162 -0
- data/lib/paperclip/storage/s3.rb +262 -0
- data/lib/paperclip/storage.rb +3 -0
- data/lib/paperclip/style.rb +95 -0
- data/lib/paperclip/thumbnail.rb +105 -0
- data/lib/paperclip/upfile.rb +62 -0
- data/lib/paperclip/version.rb +3 -0
- data/lib/paperclip.rb +478 -0
- data/lib/tasks/paperclip.rake +97 -0
- data/rails/init.rb +2 -0
- data/shoulda_macros/paperclip.rb +124 -0
- data/test/attachment_test.rb +1120 -0
- data/test/database.yml +4 -0
- data/test/fixtures/12k.png +0 -0
- data/test/fixtures/50x50.png +0 -0
- data/test/fixtures/5k.png +0 -0
- data/test/fixtures/animated.gif +0 -0
- data/test/fixtures/bad.png +1 -0
- data/test/fixtures/fog.yml +8 -0
- data/test/fixtures/s3.yml +8 -0
- data/test/fixtures/spaced file.png +0 -0
- data/test/fixtures/text.txt +1 -0
- data/test/fixtures/twopage.pdf +0 -0
- data/test/fixtures/uppercase.PNG +0 -0
- data/test/fog_test.rb +191 -0
- data/test/geometry_test.rb +206 -0
- data/test/helper.rb +152 -0
- data/test/integration_test.rb +654 -0
- data/test/interpolations_test.rb +195 -0
- data/test/iostream_test.rb +71 -0
- data/test/matchers/have_attached_file_matcher_test.rb +24 -0
- data/test/matchers/validate_attachment_content_type_matcher_test.rb +87 -0
- data/test/matchers/validate_attachment_presence_matcher_test.rb +26 -0
- data/test/matchers/validate_attachment_size_matcher_test.rb +51 -0
- data/test/options_test.rb +68 -0
- data/test/paperclip_missing_attachment_styles_test.rb +80 -0
- data/test/paperclip_test.rb +329 -0
- data/test/processor_test.rb +10 -0
- data/test/storage/filesystem_test.rb +52 -0
- data/test/storage/s3_live_test.rb +51 -0
- data/test/storage/s3_test.rb +633 -0
- data/test/style_test.rb +180 -0
- data/test/thumbnail_test.rb +383 -0
- data/test/upfile_test.rb +53 -0
- metadata +243 -0
@@ -0,0 +1,1120 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require './test/helper'
|
3
|
+
|
4
|
+
class Dummy
|
5
|
+
# This is a dummy class
|
6
|
+
end
|
7
|
+
|
8
|
+
class AttachmentTest < Test::Unit::TestCase
|
9
|
+
should "return the path based on the url by default" do
|
10
|
+
@attachment = attachment :url => "/:class/:id/:basename"
|
11
|
+
@model = @attachment.instance
|
12
|
+
@model.id = 1234
|
13
|
+
@model.avatar_file_name = "fake.jpg"
|
14
|
+
assert_equal "#{Rails.root}/public/fake_models/1234/fake", @attachment.path
|
15
|
+
end
|
16
|
+
|
17
|
+
should "return the url by interpolating the default_url option when no file assigned" do
|
18
|
+
@attachment = attachment :default_url => ":class/blegga.png"
|
19
|
+
@model = @attachment.instance
|
20
|
+
assert_nil @model.avatar_file_name
|
21
|
+
assert_equal "fake_models/blegga.png", @attachment.url
|
22
|
+
end
|
23
|
+
|
24
|
+
should "return the url by executing and interpolating the default_url Proc when no file assigned" do
|
25
|
+
@attachment = attachment :default_url => lambda { |a| ":class/blegga.png" }
|
26
|
+
@model = @attachment.instance
|
27
|
+
assert_nil @model.avatar_file_name
|
28
|
+
assert_equal "fake_models/blegga.png", @attachment.url
|
29
|
+
end
|
30
|
+
|
31
|
+
should "return the url by executing and interpolating the default_url Proc with attachment arg when no file assigned" do
|
32
|
+
@attachment = attachment :default_url => lambda { |a| a.instance.some_method_to_determine_default_url }
|
33
|
+
@model = @attachment.instance
|
34
|
+
@model.stubs(:some_method_to_determine_default_url).returns(":class/blegga.png")
|
35
|
+
assert_nil @model.avatar_file_name
|
36
|
+
assert_equal "fake_models/blegga.png", @attachment.url
|
37
|
+
end
|
38
|
+
|
39
|
+
should "return the url by executing and interpolating the default_url when assigned with symbol as method in attachment model" do
|
40
|
+
@attachment = attachment :default_url => :some_method_to_determine_default_url
|
41
|
+
@model = @attachment.instance
|
42
|
+
@model.stubs(:some_method_to_determine_default_url).returns(":class/female_:style_blegga.png")
|
43
|
+
assert_equal "fake_models/female_foostyle_blegga.png", @attachment.url(:foostyle)
|
44
|
+
end
|
45
|
+
|
46
|
+
context "Attachment default_options" do
|
47
|
+
setup do
|
48
|
+
rebuild_model
|
49
|
+
@old_default_options = Paperclip::Attachment.default_options.dup
|
50
|
+
@new_default_options = @old_default_options.merge({
|
51
|
+
:path => "argle/bargle",
|
52
|
+
:url => "fooferon",
|
53
|
+
:default_url => "not here.png"
|
54
|
+
})
|
55
|
+
end
|
56
|
+
|
57
|
+
teardown do
|
58
|
+
Paperclip::Attachment.default_options.merge! @old_default_options
|
59
|
+
end
|
60
|
+
|
61
|
+
should "be overrideable" do
|
62
|
+
Paperclip::Attachment.default_options.merge!(@new_default_options)
|
63
|
+
@new_default_options.keys.each do |key|
|
64
|
+
assert_equal @new_default_options[key],
|
65
|
+
Paperclip::Attachment.default_options[key]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "without an Attachment" do
|
70
|
+
setup do
|
71
|
+
@dummy = Dummy.new
|
72
|
+
end
|
73
|
+
|
74
|
+
should "return false when asked exists?" do
|
75
|
+
assert !@dummy.avatar.exists?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "on an Attachment" do
|
80
|
+
setup do
|
81
|
+
@dummy = Dummy.new
|
82
|
+
@attachment = @dummy.avatar
|
83
|
+
end
|
84
|
+
|
85
|
+
Paperclip::Attachment.default_options.keys.each do |key|
|
86
|
+
should "be the default_options for #{key}" do
|
87
|
+
assert_equal @old_default_options[key],
|
88
|
+
@attachment.options.send(key),
|
89
|
+
key
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when redefined" do
|
94
|
+
setup do
|
95
|
+
Paperclip::Attachment.default_options.merge!(@new_default_options)
|
96
|
+
@dummy = Dummy.new
|
97
|
+
@attachment = @dummy.avatar
|
98
|
+
end
|
99
|
+
|
100
|
+
Paperclip::Attachment.default_options.keys.each do |key|
|
101
|
+
should "be the new default_options for #{key}" do
|
102
|
+
assert_equal @new_default_options[key],
|
103
|
+
@attachment.options.send(key),
|
104
|
+
key
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "An attachment with similarly named interpolations" do
|
112
|
+
setup do
|
113
|
+
rebuild_model :path => ":id.omg/:id-bbq/:idwhat/:id_partition.wtf"
|
114
|
+
@dummy = Dummy.new
|
115
|
+
@dummy.stubs(:id).returns(1024)
|
116
|
+
@file = File.new(File.join(File.dirname(__FILE__),
|
117
|
+
"fixtures",
|
118
|
+
"5k.png"), 'rb')
|
119
|
+
@dummy.avatar = @file
|
120
|
+
end
|
121
|
+
|
122
|
+
teardown { @file.close }
|
123
|
+
|
124
|
+
should "make sure that they are interpolated correctly" do
|
125
|
+
assert_equal "1024.omg/1024-bbq/1024what/000/001/024.wtf", @dummy.avatar.path
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "An attachment with :timestamp interpolations" do
|
130
|
+
setup do
|
131
|
+
@file = StringIO.new("...")
|
132
|
+
@zone = 'UTC'
|
133
|
+
Time.stubs(:zone).returns(@zone)
|
134
|
+
@zone_default = 'Eastern Time (US & Canada)'
|
135
|
+
Time.stubs(:zone_default).returns(@zone_default)
|
136
|
+
end
|
137
|
+
|
138
|
+
context "using default time zone" do
|
139
|
+
setup do
|
140
|
+
rebuild_model :path => ":timestamp", :use_default_time_zone => true
|
141
|
+
@dummy = Dummy.new
|
142
|
+
@dummy.avatar = @file
|
143
|
+
end
|
144
|
+
|
145
|
+
should "return a time in the default zone" do
|
146
|
+
assert_equal @dummy.avatar_updated_at.in_time_zone(@zone_default).to_s, @dummy.avatar.path
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "using per-thread time zone" do
|
151
|
+
setup do
|
152
|
+
rebuild_model :path => ":timestamp", :use_default_time_zone => false
|
153
|
+
@dummy = Dummy.new
|
154
|
+
@dummy.avatar = @file
|
155
|
+
end
|
156
|
+
|
157
|
+
should "return a time in the per-thread zone" do
|
158
|
+
assert_equal @dummy.avatar_updated_at.in_time_zone(@zone).to_s, @dummy.avatar.path
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "An attachment with :hash interpolations" do
|
164
|
+
setup do
|
165
|
+
@file = StringIO.new("...")
|
166
|
+
end
|
167
|
+
|
168
|
+
should "raise if no secret is provided" do
|
169
|
+
@attachment = attachment :path => ":hash"
|
170
|
+
@attachment.assign @file
|
171
|
+
|
172
|
+
assert_raise ArgumentError do
|
173
|
+
@attachment.path
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context "when secret is set" do
|
178
|
+
setup do
|
179
|
+
@attachment = attachment :path => ":hash", :hash_secret => "w00t"
|
180
|
+
@attachment.stubs(:instance_read).with(:updated_at).returns(Time.at(1234567890))
|
181
|
+
@attachment.stubs(:instance_read).with(:file_name).returns("bla.txt")
|
182
|
+
@attachment.instance.id = 1234
|
183
|
+
@attachment.assign @file
|
184
|
+
end
|
185
|
+
|
186
|
+
should "interpolate the hash data" do
|
187
|
+
@attachment.expects(:interpolate).with(@attachment.options.hash_data,anything).returns("interpolated_stuff")
|
188
|
+
@attachment.hash
|
189
|
+
end
|
190
|
+
|
191
|
+
should "result in the correct interpolation" do
|
192
|
+
assert_equal "fake_models/avatars/1234/original/1234567890", @attachment.send(:interpolate,@attachment.options.hash_data)
|
193
|
+
end
|
194
|
+
|
195
|
+
should "result in a correct hash" do
|
196
|
+
assert_equal "d22b617d1bf10016aa7d046d16427ae203f39fce", @attachment.path
|
197
|
+
end
|
198
|
+
|
199
|
+
should "generate a hash digest with the correct style" do
|
200
|
+
OpenSSL::HMAC.expects(:hexdigest).with(anything, anything, "fake_models/avatars/1234/medium/1234567890")
|
201
|
+
@attachment.path("medium")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "An attachment with a :rails_env interpolation" do
|
207
|
+
setup do
|
208
|
+
@rails_env = "blah"
|
209
|
+
@id = 1024
|
210
|
+
rebuild_model :path => ":rails_env/:id.png"
|
211
|
+
@dummy = Dummy.new
|
212
|
+
@dummy.stubs(:id).returns(@id)
|
213
|
+
@file = StringIO.new(".")
|
214
|
+
@dummy.avatar = @file
|
215
|
+
Rails.stubs(:env).returns(@rails_env)
|
216
|
+
end
|
217
|
+
|
218
|
+
should "return the proper path" do
|
219
|
+
assert_equal "#{@rails_env}/#{@id}.png", @dummy.avatar.path
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
context "An attachment with a default style and an extension interpolation" do
|
224
|
+
setup do
|
225
|
+
@attachment = attachment :path => ":basename.:extension",
|
226
|
+
:styles => { :default => ["100x100", :png] },
|
227
|
+
:default_style => :default
|
228
|
+
@file = StringIO.new("...")
|
229
|
+
@file.stubs(:original_filename).returns("file.jpg")
|
230
|
+
end
|
231
|
+
should "return the right extension for the path" do
|
232
|
+
@attachment.assign(@file)
|
233
|
+
assert_equal "file.png", @attachment.path
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context "An attachment with :convert_options" do
|
238
|
+
setup do
|
239
|
+
rebuild_model :styles => {
|
240
|
+
:thumb => "100x100",
|
241
|
+
:large => "400x400"
|
242
|
+
},
|
243
|
+
:convert_options => {
|
244
|
+
:all => "-do_stuff",
|
245
|
+
:thumb => "-thumbnailize"
|
246
|
+
}
|
247
|
+
@dummy = Dummy.new
|
248
|
+
@dummy.avatar
|
249
|
+
end
|
250
|
+
|
251
|
+
should "report the correct options when sent #extra_options_for(:thumb)" do
|
252
|
+
assert_equal "-thumbnailize -do_stuff", @dummy.avatar.send(:extra_options_for, :thumb), @dummy.avatar.convert_options.inspect
|
253
|
+
end
|
254
|
+
|
255
|
+
should "report the correct options when sent #extra_options_for(:large)" do
|
256
|
+
assert_equal "-do_stuff", @dummy.avatar.send(:extra_options_for, :large)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context "An attachment with :source_file_options" do
|
261
|
+
setup do
|
262
|
+
rebuild_model :styles => {
|
263
|
+
:thumb => "100x100",
|
264
|
+
:large => "400x400"
|
265
|
+
},
|
266
|
+
:source_file_options => {
|
267
|
+
:all => "-density 400",
|
268
|
+
:thumb => "-depth 8"
|
269
|
+
}
|
270
|
+
@dummy = Dummy.new
|
271
|
+
@dummy.avatar
|
272
|
+
end
|
273
|
+
|
274
|
+
should "report the correct options when sent #extra_source_file_options_for(:thumb)" do
|
275
|
+
assert_equal "-depth 8 -density 400", @dummy.avatar.send(:extra_source_file_options_for, :thumb), @dummy.avatar.options.source_file_options.inspect
|
276
|
+
end
|
277
|
+
|
278
|
+
should "report the correct options when sent #extra_source_file_options_for(:large)" do
|
279
|
+
assert_equal "-density 400", @dummy.avatar.send(:extra_source_file_options_for, :large)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context "An attachment with :only_process" do
|
284
|
+
setup do
|
285
|
+
rebuild_model :styles => {
|
286
|
+
:thumb => "100x100",
|
287
|
+
:large => "400x400"
|
288
|
+
},
|
289
|
+
:only_process => [:thumb]
|
290
|
+
@file = StringIO.new("...")
|
291
|
+
@attachment = Dummy.new.avatar
|
292
|
+
end
|
293
|
+
|
294
|
+
should "only process the provided style" do
|
295
|
+
@attachment.expects(:post_process).with(:thumb)
|
296
|
+
@attachment.expects(:post_process).with(:large).never
|
297
|
+
@attachment.assign(@file)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
context "An attachment with :convert_options that is a proc" do
|
302
|
+
setup do
|
303
|
+
rebuild_model :styles => {
|
304
|
+
:thumb => "100x100",
|
305
|
+
:large => "400x400"
|
306
|
+
},
|
307
|
+
:convert_options => {
|
308
|
+
:all => lambda{|i| i.all },
|
309
|
+
:thumb => lambda{|i| i.thumb }
|
310
|
+
}
|
311
|
+
Dummy.class_eval do
|
312
|
+
def all; "-all"; end
|
313
|
+
def thumb; "-thumb"; end
|
314
|
+
end
|
315
|
+
@dummy = Dummy.new
|
316
|
+
@dummy.avatar
|
317
|
+
end
|
318
|
+
|
319
|
+
should "report the correct options when sent #extra_options_for(:thumb)" do
|
320
|
+
assert_equal "-thumb -all", @dummy.avatar.send(:extra_options_for, :thumb), @dummy.avatar.convert_options.inspect
|
321
|
+
end
|
322
|
+
|
323
|
+
should "report the correct options when sent #extra_options_for(:large)" do
|
324
|
+
assert_equal "-all", @dummy.avatar.send(:extra_options_for, :large)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
context "An attachment with :path that is a proc" do
|
329
|
+
setup do
|
330
|
+
rebuild_model :path => lambda{ |attachment| "path/#{attachment.instance.other}.:extension" }
|
331
|
+
|
332
|
+
@file = File.new(File.join(File.dirname(__FILE__),
|
333
|
+
"fixtures",
|
334
|
+
"5k.png"), 'rb')
|
335
|
+
@dummyA = Dummy.new(:other => 'a')
|
336
|
+
@dummyA.avatar = @file
|
337
|
+
@dummyB = Dummy.new(:other => 'b')
|
338
|
+
@dummyB.avatar = @file
|
339
|
+
end
|
340
|
+
|
341
|
+
teardown { @file.close }
|
342
|
+
|
343
|
+
should "return correct path" do
|
344
|
+
assert_equal "path/a.png", @dummyA.avatar.path
|
345
|
+
assert_equal "path/b.png", @dummyB.avatar.path
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
context "An attachment with :styles that is a proc" do
|
350
|
+
setup do
|
351
|
+
rebuild_model :styles => lambda{ |attachment| {:thumb => "50x50#", :large => "400x400"} }
|
352
|
+
|
353
|
+
@attachment = Dummy.new.avatar
|
354
|
+
end
|
355
|
+
|
356
|
+
should "have the correct geometry" do
|
357
|
+
assert_equal "50x50#", @attachment.options.styles[:thumb][:geometry]
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
context "An attachment with conditional :styles that is a proc" do
|
362
|
+
setup do
|
363
|
+
rebuild_model :styles => lambda{ |attachment| attachment.instance.other == 'a' ? {:thumb => "50x50#"} : {:large => "400x400"} }
|
364
|
+
|
365
|
+
@dummy = Dummy.new(:other => 'a')
|
366
|
+
end
|
367
|
+
|
368
|
+
should "have the correct styles for the assigned instance values" do
|
369
|
+
assert_equal "50x50#", @dummy.avatar.options.styles[:thumb][:geometry]
|
370
|
+
assert_nil @dummy.avatar.options.styles[:large]
|
371
|
+
|
372
|
+
@dummy.other = 'b'
|
373
|
+
|
374
|
+
assert_equal "400x400", @dummy.avatar.options.styles[:large][:geometry]
|
375
|
+
assert_nil @dummy.avatar.options.styles[:thumb]
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
context "An attachment with :url that is a proc" do
|
380
|
+
setup do
|
381
|
+
rebuild_model :url => lambda{ |attachment| "path/#{attachment.instance.other}.:extension" }
|
382
|
+
|
383
|
+
@file = File.new(File.join(File.dirname(__FILE__),
|
384
|
+
"fixtures",
|
385
|
+
"5k.png"), 'rb')
|
386
|
+
@dummyA = Dummy.new(:other => 'a')
|
387
|
+
@dummyA.avatar = @file
|
388
|
+
@dummyB = Dummy.new(:other => 'b')
|
389
|
+
@dummyB.avatar = @file
|
390
|
+
end
|
391
|
+
|
392
|
+
teardown { @file.close }
|
393
|
+
|
394
|
+
should "return correct url" do
|
395
|
+
assert_equal "path/a.png", @dummyA.avatar.url(:original, false)
|
396
|
+
assert_equal "path/b.png", @dummyB.avatar.url(:original, false)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
geometry_specs = [
|
401
|
+
[ lambda{|z| "50x50#" }, :png ],
|
402
|
+
lambda{|z| "50x50#" },
|
403
|
+
{ :geometry => lambda{|z| "50x50#" } }
|
404
|
+
]
|
405
|
+
geometry_specs.each do |geometry_spec|
|
406
|
+
context "An attachment geometry like #{geometry_spec}" do
|
407
|
+
setup do
|
408
|
+
rebuild_model :styles => { :normal => geometry_spec }
|
409
|
+
@attachment = Dummy.new.avatar
|
410
|
+
end
|
411
|
+
|
412
|
+
context "when assigned" do
|
413
|
+
setup do
|
414
|
+
@file = StringIO.new(".")
|
415
|
+
@attachment.assign(@file)
|
416
|
+
end
|
417
|
+
|
418
|
+
should "have the correct geometry" do
|
419
|
+
assert_equal "50x50#", @attachment.options.styles[:normal][:geometry]
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
context "An attachment with both 'normal' and hash-style styles" do
|
426
|
+
setup do
|
427
|
+
rebuild_model :styles => {
|
428
|
+
:normal => ["50x50#", :png],
|
429
|
+
:hash => { :geometry => "50x50#", :format => :png }
|
430
|
+
}
|
431
|
+
@dummy = Dummy.new
|
432
|
+
@attachment = @dummy.avatar
|
433
|
+
end
|
434
|
+
|
435
|
+
[:processors, :whiny, :convert_options, :geometry, :format].each do |field|
|
436
|
+
should "have the same #{field} field" do
|
437
|
+
assert_equal @attachment.options.styles[:normal][field], @attachment.options.styles[:hash][field]
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
context "An attachment with :processors that is a proc" do
|
443
|
+
setup do
|
444
|
+
class Paperclip::Test < Paperclip::Processor; end
|
445
|
+
@file = StringIO.new("...")
|
446
|
+
Paperclip::Test.stubs(:make).returns(@file)
|
447
|
+
|
448
|
+
rebuild_model :styles => { :normal => '' }, :processors => lambda { |a| [ :test ] }
|
449
|
+
@attachment = Dummy.new.avatar
|
450
|
+
end
|
451
|
+
|
452
|
+
context "when assigned" do
|
453
|
+
setup do
|
454
|
+
@attachment.assign(StringIO.new("."))
|
455
|
+
end
|
456
|
+
|
457
|
+
should "have the correct processors" do
|
458
|
+
assert_equal [ :test ], @attachment.options.styles[:normal][:processors]
|
459
|
+
end
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
context "An attachment with erroring processor" do
|
464
|
+
setup do
|
465
|
+
rebuild_model :processor => [:thumbnail], :styles => { :small => '' }, :whiny_thumbnails => true
|
466
|
+
@dummy = Dummy.new
|
467
|
+
Paperclip::Thumbnail.expects(:make).raises(Paperclip::PaperclipError, "cannot be processed.")
|
468
|
+
@file = StringIO.new("...")
|
469
|
+
@file.stubs(:to_tempfile).returns(@file)
|
470
|
+
@dummy.avatar = @file
|
471
|
+
end
|
472
|
+
|
473
|
+
should "correctly forward processing error message to the instance" do
|
474
|
+
@dummy.valid?
|
475
|
+
assert_contains @dummy.errors.full_messages, "Avatar cannot be processed."
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
context "An attachment with multiple processors" do
|
480
|
+
setup do
|
481
|
+
class Paperclip::Test < Paperclip::Processor; end
|
482
|
+
@style_params = { :once => {:one => 1, :two => 2} }
|
483
|
+
rebuild_model :processors => [:thumbnail, :test], :styles => @style_params
|
484
|
+
@dummy = Dummy.new
|
485
|
+
@file = StringIO.new("...")
|
486
|
+
@file.stubs(:to_tempfile).returns(@file)
|
487
|
+
Paperclip::Test.stubs(:make).returns(@file)
|
488
|
+
Paperclip::Thumbnail.stubs(:make).returns(@file)
|
489
|
+
end
|
490
|
+
|
491
|
+
context "when assigned" do
|
492
|
+
setup { @dummy.avatar = @file }
|
493
|
+
|
494
|
+
before_should "call #make on all specified processors" do
|
495
|
+
Paperclip::Thumbnail.expects(:make).with(any_parameters).returns(@file)
|
496
|
+
Paperclip::Test.expects(:make).with(any_parameters).returns(@file)
|
497
|
+
end
|
498
|
+
|
499
|
+
before_should "call #make with the right parameters passed as second argument" do
|
500
|
+
expected_params = @style_params[:once].merge({
|
501
|
+
:processors => [:thumbnail, :test],
|
502
|
+
:whiny => true,
|
503
|
+
:convert_options => "",
|
504
|
+
:source_file_options => ""
|
505
|
+
})
|
506
|
+
Paperclip::Thumbnail.expects(:make).with(anything, expected_params, anything).returns(@file)
|
507
|
+
end
|
508
|
+
|
509
|
+
before_should "call #make with attachment passed as third argument" do
|
510
|
+
Paperclip::Test.expects(:make).with(anything, anything, @dummy.avatar).returns(@file)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
should "include the filesystem module when loading the filesystem storage" do
|
516
|
+
rebuild_model :storage => :filesystem
|
517
|
+
@dummy = Dummy.new
|
518
|
+
assert @dummy.avatar.is_a?(Paperclip::Storage::Filesystem)
|
519
|
+
end
|
520
|
+
|
521
|
+
should "include the filesystem module even if capitalization is wrong" do
|
522
|
+
rebuild_model :storage => :FileSystem
|
523
|
+
@dummy = Dummy.new
|
524
|
+
assert @dummy.avatar.is_a?(Paperclip::Storage::Filesystem)
|
525
|
+
|
526
|
+
rebuild_model :storage => :Filesystem
|
527
|
+
@dummy = Dummy.new
|
528
|
+
assert @dummy.avatar.is_a?(Paperclip::Storage::Filesystem)
|
529
|
+
end
|
530
|
+
|
531
|
+
should "convert underscored storage name to camelcase" do
|
532
|
+
rebuild_model :storage => :not_here
|
533
|
+
@dummy = Dummy.new
|
534
|
+
exception = assert_raises(Paperclip::StorageMethodNotFound) do |e|
|
535
|
+
@dummy.avatar
|
536
|
+
end
|
537
|
+
assert exception.message.include?("NotHere")
|
538
|
+
end
|
539
|
+
|
540
|
+
should "raise an error if you try to include a storage module that doesn't exist" do
|
541
|
+
rebuild_model :storage => :not_here
|
542
|
+
@dummy = Dummy.new
|
543
|
+
assert_raises(Paperclip::StorageMethodNotFound) do
|
544
|
+
@dummy.avatar
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
context "An attachment with styles but no processors defined" do
|
549
|
+
setup do
|
550
|
+
rebuild_model :processors => [], :styles => {:something => '1'}
|
551
|
+
@dummy = Dummy.new
|
552
|
+
@file = StringIO.new("...")
|
553
|
+
end
|
554
|
+
should "raise when assigned to" do
|
555
|
+
assert_raises(RuntimeError){ @dummy.avatar = @file }
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
context "An attachment without styles and with no processors defined" do
|
560
|
+
setup do
|
561
|
+
rebuild_model :processors => [], :styles => {}
|
562
|
+
@dummy = Dummy.new
|
563
|
+
@file = StringIO.new("...")
|
564
|
+
end
|
565
|
+
should "not raise when assigned to" do
|
566
|
+
@dummy.avatar = @file
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
context "Assigning an attachment with post_process hooks" do
|
571
|
+
setup do
|
572
|
+
rebuild_class :styles => { :something => "100x100#" }
|
573
|
+
Dummy.class_eval do
|
574
|
+
before_avatar_post_process :do_before_avatar
|
575
|
+
after_avatar_post_process :do_after_avatar
|
576
|
+
before_post_process :do_before_all
|
577
|
+
after_post_process :do_after_all
|
578
|
+
def do_before_avatar; end
|
579
|
+
def do_after_avatar; end
|
580
|
+
def do_before_all; end
|
581
|
+
def do_after_all; end
|
582
|
+
end
|
583
|
+
@file = StringIO.new(".")
|
584
|
+
@file.stubs(:to_tempfile).returns(@file)
|
585
|
+
@dummy = Dummy.new
|
586
|
+
Paperclip::Thumbnail.stubs(:make).returns(@file)
|
587
|
+
@attachment = @dummy.avatar
|
588
|
+
end
|
589
|
+
|
590
|
+
should "call the defined callbacks when assigned" do
|
591
|
+
@dummy.expects(:do_before_avatar).with()
|
592
|
+
@dummy.expects(:do_after_avatar).with()
|
593
|
+
@dummy.expects(:do_before_all).with()
|
594
|
+
@dummy.expects(:do_after_all).with()
|
595
|
+
Paperclip::Thumbnail.expects(:make).returns(@file)
|
596
|
+
@dummy.avatar = @file
|
597
|
+
end
|
598
|
+
|
599
|
+
should "not cancel the processing if a before_post_process returns nil" do
|
600
|
+
@dummy.expects(:do_before_avatar).with().returns(nil)
|
601
|
+
@dummy.expects(:do_after_avatar).with()
|
602
|
+
@dummy.expects(:do_before_all).with().returns(nil)
|
603
|
+
@dummy.expects(:do_after_all).with()
|
604
|
+
Paperclip::Thumbnail.expects(:make).returns(@file)
|
605
|
+
@dummy.avatar = @file
|
606
|
+
end
|
607
|
+
|
608
|
+
should "cancel the processing if a before_post_process returns false" do
|
609
|
+
@dummy.expects(:do_before_avatar).never
|
610
|
+
@dummy.expects(:do_after_avatar).never
|
611
|
+
@dummy.expects(:do_before_all).with().returns(false)
|
612
|
+
@dummy.expects(:do_after_all)
|
613
|
+
Paperclip::Thumbnail.expects(:make).never
|
614
|
+
@dummy.avatar = @file
|
615
|
+
end
|
616
|
+
|
617
|
+
should "cancel the processing if a before_avatar_post_process returns false" do
|
618
|
+
@dummy.expects(:do_before_avatar).with().returns(false)
|
619
|
+
@dummy.expects(:do_after_avatar)
|
620
|
+
@dummy.expects(:do_before_all).with().returns(true)
|
621
|
+
@dummy.expects(:do_after_all)
|
622
|
+
Paperclip::Thumbnail.expects(:make).never
|
623
|
+
@dummy.avatar = @file
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
627
|
+
context "Assigning an attachment" do
|
628
|
+
setup do
|
629
|
+
rebuild_model :styles => { :something => "100x100#" }
|
630
|
+
@file = StringIO.new(".")
|
631
|
+
@file.stubs(:original_filename).returns("5k.png\n\n")
|
632
|
+
@file.stubs(:content_type).returns("image/png\n\n")
|
633
|
+
@file.stubs(:to_tempfile).returns(@file)
|
634
|
+
@dummy = Dummy.new
|
635
|
+
Paperclip::Thumbnail.expects(:make).returns(@file)
|
636
|
+
@attachment = @dummy.avatar
|
637
|
+
@dummy.avatar = @file
|
638
|
+
end
|
639
|
+
|
640
|
+
should "strip whitespace from original_filename field" do
|
641
|
+
assert_equal "5k.png", @dummy.avatar.original_filename
|
642
|
+
end
|
643
|
+
|
644
|
+
should "strip whitespace from content_type field" do
|
645
|
+
assert_equal "image/png", @dummy.avatar.instance.avatar_content_type
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
649
|
+
context "Attachment with strange letters" do
|
650
|
+
setup do
|
651
|
+
rebuild_model
|
652
|
+
|
653
|
+
@not_file = mock("not_file")
|
654
|
+
@tempfile = mock("tempfile")
|
655
|
+
@not_file.stubs(:nil?).returns(false)
|
656
|
+
@not_file.expects(:size).returns(10)
|
657
|
+
@tempfile.expects(:size).returns(10)
|
658
|
+
@not_file.expects(:original_filename).returns("sheep_say_bæ.png\r\n")
|
659
|
+
@not_file.expects(:content_type).returns("image/png\r\n")
|
660
|
+
|
661
|
+
@dummy = Dummy.new
|
662
|
+
@attachment = @dummy.avatar
|
663
|
+
@attachment.expects(:valid_assignment?).with(@not_file).returns(true)
|
664
|
+
@attachment.expects(:queue_existing_for_delete)
|
665
|
+
@attachment.expects(:post_process)
|
666
|
+
@attachment.expects(:to_tempfile).returns(@tempfile)
|
667
|
+
@attachment.expects(:generate_fingerprint).with(@tempfile).returns("12345")
|
668
|
+
@attachment.expects(:generate_fingerprint).with(@not_file).returns("12345")
|
669
|
+
@dummy.avatar = @not_file
|
670
|
+
end
|
671
|
+
|
672
|
+
should "not remove strange letters" do
|
673
|
+
assert_equal "sheep_say_bæ.png", @dummy.avatar.original_filename
|
674
|
+
end
|
675
|
+
end
|
676
|
+
|
677
|
+
context "Attachment with uppercase extension and a default style" do
|
678
|
+
setup do
|
679
|
+
@old_defaults = Paperclip::Attachment.default_options.dup
|
680
|
+
Paperclip::Attachment.default_options.merge!({
|
681
|
+
:path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
|
682
|
+
})
|
683
|
+
FileUtils.rm_rf("tmp")
|
684
|
+
rebuild_model
|
685
|
+
@instance = Dummy.new
|
686
|
+
@instance.stubs(:id).returns 123
|
687
|
+
|
688
|
+
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "uppercase.PNG"), 'rb')
|
689
|
+
|
690
|
+
styles = {:styles => { :large => ["400x400", :jpg],
|
691
|
+
:medium => ["100x100", :jpg],
|
692
|
+
:small => ["32x32#", :jpg]},
|
693
|
+
:default_style => :small}
|
694
|
+
@attachment = Paperclip::Attachment.new(:avatar,
|
695
|
+
@instance,
|
696
|
+
styles)
|
697
|
+
now = Time.now
|
698
|
+
Time.stubs(:now).returns(now)
|
699
|
+
@attachment.assign(@file)
|
700
|
+
@attachment.save
|
701
|
+
end
|
702
|
+
|
703
|
+
teardown do
|
704
|
+
@file.close
|
705
|
+
Paperclip::Attachment.default_options.merge!(@old_defaults)
|
706
|
+
end
|
707
|
+
|
708
|
+
should "should have matching to_s and url methods" do
|
709
|
+
file = @attachment.to_file
|
710
|
+
assert file
|
711
|
+
assert_match @attachment.to_s, @attachment.url
|
712
|
+
assert_match @attachment.to_s(:small), @attachment.url(:small)
|
713
|
+
file.close
|
714
|
+
end
|
715
|
+
end
|
716
|
+
|
717
|
+
context "An attachment" do
|
718
|
+
setup do
|
719
|
+
@old_defaults = Paperclip::Attachment.default_options.dup
|
720
|
+
Paperclip::Attachment.default_options.merge!({
|
721
|
+
:path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
|
722
|
+
})
|
723
|
+
FileUtils.rm_rf("tmp")
|
724
|
+
rebuild_model
|
725
|
+
@instance = Dummy.new
|
726
|
+
@instance.stubs(:id).returns 123
|
727
|
+
@attachment = Paperclip::Attachment.new(:avatar, @instance)
|
728
|
+
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
|
729
|
+
end
|
730
|
+
|
731
|
+
teardown do
|
732
|
+
@file.close
|
733
|
+
Paperclip::Attachment.default_options.merge!(@old_defaults)
|
734
|
+
end
|
735
|
+
|
736
|
+
should "raise if there are not the correct columns when you try to assign" do
|
737
|
+
@other_attachment = Paperclip::Attachment.new(:not_here, @instance)
|
738
|
+
assert_raises(Paperclip::PaperclipError) do
|
739
|
+
@other_attachment.assign(@file)
|
740
|
+
end
|
741
|
+
end
|
742
|
+
|
743
|
+
should "return its default_url when no file assigned" do
|
744
|
+
assert @attachment.to_file.nil?
|
745
|
+
assert_equal "/avatars/original/missing.png", @attachment.url
|
746
|
+
assert_equal "/avatars/blah/missing.png", @attachment.url(:blah)
|
747
|
+
end
|
748
|
+
|
749
|
+
should "return nil as path when no file assigned" do
|
750
|
+
assert @attachment.to_file.nil?
|
751
|
+
assert_equal nil, @attachment.path
|
752
|
+
assert_equal nil, @attachment.path(:blah)
|
753
|
+
end
|
754
|
+
|
755
|
+
context "with a file assigned but not saved yet" do
|
756
|
+
should "clear out any attached files" do
|
757
|
+
@attachment.assign(@file)
|
758
|
+
assert !@attachment.queued_for_write.blank?
|
759
|
+
@attachment.clear
|
760
|
+
assert @attachment.queued_for_write.blank?
|
761
|
+
end
|
762
|
+
end
|
763
|
+
|
764
|
+
context "with a file assigned in the database" do
|
765
|
+
setup do
|
766
|
+
@attachment.stubs(:instance_read).with(:file_name).returns("5k.png")
|
767
|
+
@attachment.stubs(:instance_read).with(:content_type).returns("image/png")
|
768
|
+
@attachment.stubs(:instance_read).with(:file_size).returns(12345)
|
769
|
+
dtnow = DateTime.now
|
770
|
+
@now = Time.now
|
771
|
+
Time.stubs(:now).returns(@now)
|
772
|
+
@attachment.stubs(:instance_read).with(:updated_at).returns(dtnow)
|
773
|
+
end
|
774
|
+
|
775
|
+
should "return a correct url even if the file does not exist" do
|
776
|
+
assert_nil @attachment.to_file
|
777
|
+
assert_match %r{^/system/avatars/#{@instance.id}/blah/5k\.png}, @attachment.url(:blah)
|
778
|
+
end
|
779
|
+
|
780
|
+
should "make sure the updated_at mtime is in the url if it is defined" do
|
781
|
+
assert_match %r{#{@now.to_i}$}, @attachment.url(:blah)
|
782
|
+
end
|
783
|
+
|
784
|
+
should "make sure the updated_at mtime is NOT in the url if false is passed to the url method" do
|
785
|
+
assert_no_match %r{#{@now.to_i}$}, @attachment.url(:blah, false)
|
786
|
+
end
|
787
|
+
|
788
|
+
context "with the updated_at field removed" do
|
789
|
+
setup do
|
790
|
+
@attachment.stubs(:instance_read).with(:updated_at).returns(nil)
|
791
|
+
end
|
792
|
+
|
793
|
+
should "only return the url without the updated_at when sent #url" do
|
794
|
+
assert_match "/avatars/#{@instance.id}/blah/5k.png", @attachment.url(:blah)
|
795
|
+
end
|
796
|
+
end
|
797
|
+
|
798
|
+
should "return the proper path when filename has a single .'s" do
|
799
|
+
assert_equal File.expand_path("./test/../tmp/avatars/dummies/original/#{@instance.id}/5k.png"), File.expand_path(@attachment.path)
|
800
|
+
end
|
801
|
+
|
802
|
+
should "return the proper path when filename has multiple .'s" do
|
803
|
+
@attachment.stubs(:instance_read).with(:file_name).returns("5k.old.png")
|
804
|
+
assert_equal File.expand_path("./test/../tmp/avatars/dummies/original/#{@instance.id}/5k.old.png"), File.expand_path(@attachment.path)
|
805
|
+
end
|
806
|
+
|
807
|
+
context "when expecting three styles" do
|
808
|
+
setup do
|
809
|
+
styles = {:styles => { :large => ["400x400", :png],
|
810
|
+
:medium => ["100x100", :gif],
|
811
|
+
:small => ["32x32#", :jpg]}}
|
812
|
+
@attachment = Paperclip::Attachment.new(:avatar,
|
813
|
+
@instance,
|
814
|
+
styles)
|
815
|
+
end
|
816
|
+
|
817
|
+
context "and assigned a file" do
|
818
|
+
setup do
|
819
|
+
now = Time.now
|
820
|
+
Time.stubs(:now).returns(now)
|
821
|
+
@attachment.assign(@file)
|
822
|
+
end
|
823
|
+
|
824
|
+
should "be dirty" do
|
825
|
+
assert @attachment.dirty?
|
826
|
+
end
|
827
|
+
|
828
|
+
context "and saved" do
|
829
|
+
setup do
|
830
|
+
@attachment.save
|
831
|
+
end
|
832
|
+
|
833
|
+
should "return the real url" do
|
834
|
+
file = @attachment.to_file
|
835
|
+
assert file
|
836
|
+
assert_match %r{^/system/avatars/#{@instance.id}/original/5k\.png}, @attachment.url
|
837
|
+
assert_match %r{^/system/avatars/#{@instance.id}/small/5k\.jpg}, @attachment.url(:small)
|
838
|
+
file.close
|
839
|
+
end
|
840
|
+
|
841
|
+
should "commit the files to disk" do
|
842
|
+
[:large, :medium, :small].each do |style|
|
843
|
+
io = @attachment.to_file(style)
|
844
|
+
# p "in commit to disk test, io is #{io.inspect} and @instance.id is #{@instance.id}"
|
845
|
+
assert File.exists?(io.path)
|
846
|
+
assert ! io.is_a?(::Tempfile)
|
847
|
+
io.close
|
848
|
+
end
|
849
|
+
end
|
850
|
+
|
851
|
+
should "save the files as the right formats and sizes" do
|
852
|
+
[[:large, 400, 61, "PNG"],
|
853
|
+
[:medium, 100, 15, "GIF"],
|
854
|
+
[:small, 32, 32, "JPEG"]].each do |style|
|
855
|
+
cmd = %Q[identify -format "%w %h %b %m" "#{@attachment.path(style.first)}"]
|
856
|
+
out = `#{cmd}`
|
857
|
+
width, height, size, format = out.split(" ")
|
858
|
+
assert_equal style[1].to_s, width.to_s
|
859
|
+
assert_equal style[2].to_s, height.to_s
|
860
|
+
assert_equal style[3].to_s, format.to_s
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
should "still have its #file attribute not be nil" do
|
865
|
+
assert ! (file = @attachment.to_file).nil?
|
866
|
+
file.close
|
867
|
+
end
|
868
|
+
|
869
|
+
context "and trying to delete" do
|
870
|
+
setup do
|
871
|
+
@existing_names = @attachment.options.styles.keys.collect do |style|
|
872
|
+
@attachment.path(style)
|
873
|
+
end
|
874
|
+
end
|
875
|
+
|
876
|
+
should "delete the files after assigning nil" do
|
877
|
+
@attachment.expects(:instance_write).with(:file_name, nil)
|
878
|
+
@attachment.expects(:instance_write).with(:content_type, nil)
|
879
|
+
@attachment.expects(:instance_write).with(:file_size, nil)
|
880
|
+
@attachment.expects(:instance_write).with(:updated_at, nil)
|
881
|
+
@attachment.assign nil
|
882
|
+
@attachment.save
|
883
|
+
@existing_names.each{|f| assert ! File.exists?(f) }
|
884
|
+
end
|
885
|
+
|
886
|
+
should "delete the files when you call #clear and #save" do
|
887
|
+
@attachment.expects(:instance_write).with(:file_name, nil)
|
888
|
+
@attachment.expects(:instance_write).with(:content_type, nil)
|
889
|
+
@attachment.expects(:instance_write).with(:file_size, nil)
|
890
|
+
@attachment.expects(:instance_write).with(:updated_at, nil)
|
891
|
+
@attachment.clear
|
892
|
+
@attachment.save
|
893
|
+
@existing_names.each{|f| assert ! File.exists?(f) }
|
894
|
+
end
|
895
|
+
|
896
|
+
should "delete the files when you call #delete" do
|
897
|
+
@attachment.expects(:instance_write).with(:file_name, nil)
|
898
|
+
@attachment.expects(:instance_write).with(:content_type, nil)
|
899
|
+
@attachment.expects(:instance_write).with(:file_size, nil)
|
900
|
+
@attachment.expects(:instance_write).with(:updated_at, nil)
|
901
|
+
@attachment.destroy
|
902
|
+
@existing_names.each{|f| assert ! File.exists?(f) }
|
903
|
+
end
|
904
|
+
end
|
905
|
+
end
|
906
|
+
end
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
context "with a file that has space in file name" do
|
911
|
+
setup do
|
912
|
+
@attachment.stubs(:instance_read).with(:file_name).returns("spaced file.png")
|
913
|
+
@attachment.stubs(:instance_read).with(:content_type).returns("image/png")
|
914
|
+
@attachment.stubs(:instance_read).with(:file_size).returns(12345)
|
915
|
+
dtnow = DateTime.now
|
916
|
+
@now = Time.now
|
917
|
+
Time.stubs(:now).returns(@now)
|
918
|
+
@attachment.stubs(:instance_read).with(:updated_at).returns(dtnow)
|
919
|
+
end
|
920
|
+
|
921
|
+
should "returns an escaped version of the URL" do
|
922
|
+
assert_match /\/spaced%20file\.png/, @attachment.url
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
context "when trying a nonexistant storage type" do
|
927
|
+
setup do
|
928
|
+
rebuild_model :storage => :not_here
|
929
|
+
end
|
930
|
+
|
931
|
+
should "not be able to find the module" do
|
932
|
+
assert_raise(Paperclip::StorageMethodNotFound){ Dummy.new.avatar }
|
933
|
+
end
|
934
|
+
end
|
935
|
+
end
|
936
|
+
|
937
|
+
context "An attachment with only a avatar_file_name column" do
|
938
|
+
setup do
|
939
|
+
ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
|
940
|
+
table.column :avatar_file_name, :string
|
941
|
+
end
|
942
|
+
rebuild_class
|
943
|
+
@dummy = Dummy.new
|
944
|
+
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
|
945
|
+
end
|
946
|
+
|
947
|
+
teardown { @file.close }
|
948
|
+
|
949
|
+
should "not error when assigned an attachment" do
|
950
|
+
assert_nothing_raised { @dummy.avatar = @file }
|
951
|
+
end
|
952
|
+
|
953
|
+
should "return the time when sent #avatar_updated_at" do
|
954
|
+
now = Time.now
|
955
|
+
Time.stubs(:now).returns(now)
|
956
|
+
@dummy.avatar = @file
|
957
|
+
assert_equal now.to_i, @dummy.avatar.updated_at.to_i
|
958
|
+
end
|
959
|
+
|
960
|
+
should "return nil when reloaded and sent #avatar_updated_at" do
|
961
|
+
@dummy.save
|
962
|
+
@dummy.reload
|
963
|
+
assert_nil @dummy.avatar.updated_at
|
964
|
+
end
|
965
|
+
|
966
|
+
should "return the right value when sent #avatar_file_size" do
|
967
|
+
@dummy.avatar = @file
|
968
|
+
assert_equal @file.size, @dummy.avatar.size
|
969
|
+
end
|
970
|
+
|
971
|
+
context "and avatar_updated_at column" do
|
972
|
+
setup do
|
973
|
+
ActiveRecord::Base.connection.add_column :dummies, :avatar_updated_at, :timestamp
|
974
|
+
rebuild_class
|
975
|
+
@dummy = Dummy.new
|
976
|
+
end
|
977
|
+
|
978
|
+
should "not error when assigned an attachment" do
|
979
|
+
assert_nothing_raised { @dummy.avatar = @file }
|
980
|
+
end
|
981
|
+
|
982
|
+
should "return the right value when sent #avatar_updated_at" do
|
983
|
+
now = Time.now
|
984
|
+
Time.stubs(:now).returns(now)
|
985
|
+
@dummy.avatar = @file
|
986
|
+
assert_equal now.to_i, @dummy.avatar.updated_at
|
987
|
+
end
|
988
|
+
end
|
989
|
+
|
990
|
+
context "and avatar_content_type column" do
|
991
|
+
setup do
|
992
|
+
ActiveRecord::Base.connection.add_column :dummies, :avatar_content_type, :string
|
993
|
+
rebuild_class
|
994
|
+
@dummy = Dummy.new
|
995
|
+
end
|
996
|
+
|
997
|
+
should "not error when assigned an attachment" do
|
998
|
+
assert_nothing_raised { @dummy.avatar = @file }
|
999
|
+
end
|
1000
|
+
|
1001
|
+
should "return the right value when sent #avatar_content_type" do
|
1002
|
+
@dummy.avatar = @file
|
1003
|
+
assert_equal "image/png", @dummy.avatar.content_type
|
1004
|
+
end
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
context "and avatar_file_size column" do
|
1008
|
+
setup do
|
1009
|
+
ActiveRecord::Base.connection.add_column :dummies, :avatar_file_size, :integer
|
1010
|
+
rebuild_class
|
1011
|
+
@dummy = Dummy.new
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
should "not error when assigned an attachment" do
|
1015
|
+
assert_nothing_raised { @dummy.avatar = @file }
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
should "return the right value when sent #avatar_file_size" do
|
1019
|
+
@dummy.avatar = @file
|
1020
|
+
assert_equal @file.size, @dummy.avatar.size
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
should "return the right value when saved, reloaded, and sent #avatar_file_size" do
|
1024
|
+
@dummy.avatar = @file
|
1025
|
+
@dummy.save
|
1026
|
+
@dummy = Dummy.find(@dummy.id)
|
1027
|
+
assert_equal @file.size, @dummy.avatar.size
|
1028
|
+
end
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
context "and avatar_fingerprint column" do
|
1032
|
+
setup do
|
1033
|
+
ActiveRecord::Base.connection.add_column :dummies, :avatar_fingerprint, :string
|
1034
|
+
rebuild_class
|
1035
|
+
@dummy = Dummy.new
|
1036
|
+
end
|
1037
|
+
|
1038
|
+
should "not error when assigned an attachment" do
|
1039
|
+
assert_nothing_raised { @dummy.avatar = @file }
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
should "return the right value when sent #avatar_fingerprint" do
|
1043
|
+
@dummy.avatar = @file
|
1044
|
+
assert_equal 'aec488126c3b33c08a10c3fa303acf27', @dummy.avatar_fingerprint
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
should "return the right value when saved, reloaded, and sent #avatar_fingerprint" do
|
1048
|
+
@dummy.avatar = @file
|
1049
|
+
@dummy.save
|
1050
|
+
@dummy = Dummy.find(@dummy.id)
|
1051
|
+
assert_equal 'aec488126c3b33c08a10c3fa303acf27', @dummy.avatar_fingerprint
|
1052
|
+
end
|
1053
|
+
end
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
context "an attachment with delete_file option set to false" do
|
1057
|
+
setup do
|
1058
|
+
rebuild_model :preserve_files => true
|
1059
|
+
@dummy = Dummy.new
|
1060
|
+
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
|
1061
|
+
@dummy.avatar = @file
|
1062
|
+
@dummy.save!
|
1063
|
+
@attachment = @dummy.avatar
|
1064
|
+
@path = @attachment.path
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
should "not delete the files from storage when attachment is destroyed" do
|
1068
|
+
@attachment.destroy
|
1069
|
+
assert File.exists?(@path)
|
1070
|
+
end
|
1071
|
+
|
1072
|
+
should "not delete the file when model is destroyed" do
|
1073
|
+
@dummy.destroy
|
1074
|
+
assert File.exists?(@path)
|
1075
|
+
end
|
1076
|
+
end
|
1077
|
+
|
1078
|
+
context "setting an interpolation class" do
|
1079
|
+
should "produce the URL with the given interpolations" do
|
1080
|
+
Interpolator = Class.new do
|
1081
|
+
def self.interpolate(pattern, attachment, style_name)
|
1082
|
+
"hello"
|
1083
|
+
end
|
1084
|
+
end
|
1085
|
+
|
1086
|
+
instance = Dummy.new
|
1087
|
+
attachment = Paperclip::Attachment.new(:avatar, instance, :interpolator => Interpolator)
|
1088
|
+
|
1089
|
+
assert_equal "hello", attachment.url
|
1090
|
+
end
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
context "An attached file" do
|
1094
|
+
setup do
|
1095
|
+
rebuild_model
|
1096
|
+
@dummy = Dummy.new
|
1097
|
+
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
|
1098
|
+
@dummy.avatar = @file
|
1099
|
+
@dummy.save!
|
1100
|
+
@attachment = @dummy.avatar
|
1101
|
+
@path = @attachment.path
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
should "not be deleted when the model fails to destroy" do
|
1105
|
+
@dummy.stubs(:destroy).raises(Exception)
|
1106
|
+
|
1107
|
+
assert_raise Exception do
|
1108
|
+
@dummy.destroy
|
1109
|
+
end
|
1110
|
+
|
1111
|
+
assert File.exists?(@path), "#{@path} does not exist."
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
should "be deleted when the model is destroyed" do
|
1115
|
+
@dummy.destroy
|
1116
|
+
assert ! File.exists?(@path), "#{@path} does not exist."
|
1117
|
+
end
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
end
|