kt-paperclip 5.4.0 → 7.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/custom.md +10 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.hound.yml +3 -1055
- data/.rubocop.yml +1061 -1
- data/.travis.yml +23 -4
- data/Appraisals +23 -0
- data/CONTRIBUTING.md +4 -5
- data/Gemfile +10 -7
- data/NEWS +52 -0
- data/README.md +58 -46
- data/Rakefile +29 -21
- data/UPGRADING +3 -3
- data/features/basic_integration.feature +4 -0
- data/features/migration.feature +10 -51
- data/features/step_definitions/attachment_steps.rb +23 -13
- data/features/step_definitions/html_steps.rb +5 -5
- data/features/step_definitions/rails_steps.rb +29 -9
- data/features/step_definitions/s3_steps.rb +3 -3
- data/features/step_definitions/web_steps.rb +5 -6
- data/features/support/env.rb +4 -4
- data/features/support/fakeweb.rb +3 -5
- data/features/support/file_helpers.rb +2 -2
- data/features/support/paths.rb +4 -4
- data/features/support/rails.rb +7 -7
- data/features/support/selectors.rb +1 -1
- data/gemfiles/4.2.gemfile +7 -4
- data/gemfiles/5.0.gemfile +7 -4
- data/gemfiles/5.1.gemfile +20 -0
- data/gemfiles/5.2.gemfile +20 -0
- data/gemfiles/6.0.gemfile +20 -0
- data/gemfiles/6.1.gemfile +21 -0
- data/gemfiles/7.0.gemfile +21 -0
- data/lib/generators/paperclip/paperclip_generator.rb +6 -8
- data/lib/paperclip/attachment.rb +103 -105
- data/lib/paperclip/attachment_registry.rb +2 -2
- data/lib/paperclip/content_type_detector.rb +10 -5
- data/lib/paperclip/file_command_content_type_detector.rb +1 -3
- data/lib/paperclip/filename_cleaner.rb +0 -1
- data/lib/paperclip/geometry.rb +18 -19
- data/lib/paperclip/geometry_detector_factory.rb +13 -16
- data/lib/paperclip/geometry_parser_factory.rb +5 -5
- data/lib/paperclip/glue.rb +3 -3
- data/lib/paperclip/has_attached_file.rb +5 -4
- data/lib/paperclip/helpers.rb +3 -3
- data/lib/paperclip/interpolations.rb +42 -38
- data/lib/paperclip/io_adapters/abstract_adapter.rb +16 -14
- data/lib/paperclip/io_adapters/attachment_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +1 -1
- data/lib/paperclip/io_adapters/file_adapter.rb +1 -3
- data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +1 -1
- data/lib/paperclip/io_adapters/identity_adapter.rb +1 -2
- data/lib/paperclip/io_adapters/registry.rb +1 -1
- data/lib/paperclip/io_adapters/stringio_adapter.rb +1 -1
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +6 -8
- data/lib/paperclip/io_adapters/uri_adapter.rb +21 -9
- data/lib/paperclip/logger.rb +1 -1
- data/lib/paperclip/matchers/have_attached_file_matcher.rb +4 -4
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +19 -18
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +4 -4
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +11 -10
- data/lib/paperclip/matchers.rb +4 -4
- data/lib/paperclip/media_type_spoof_detector.rb +13 -13
- data/lib/paperclip/missing_attachment_styles.rb +11 -6
- data/lib/paperclip/processor.rb +13 -6
- data/lib/paperclip/processor_helpers.rb +3 -1
- data/lib/paperclip/rails_environment.rb +1 -5
- data/lib/paperclip/railtie.rb +5 -5
- data/lib/paperclip/schema.rb +16 -12
- data/lib/paperclip/storage/filesystem.rb +6 -8
- data/lib/paperclip/storage/fog.rb +36 -32
- data/lib/paperclip/storage/s3.rb +68 -76
- data/lib/paperclip/style.rb +3 -6
- data/lib/paperclip/tempfile.rb +4 -5
- data/lib/paperclip/tempfile_factory.rb +0 -1
- data/lib/paperclip/thumbnail.rb +11 -11
- data/lib/paperclip/url_generator.rb +5 -5
- data/lib/paperclip/validators/attachment_content_type_validator.rb +11 -4
- data/lib/paperclip/validators/attachment_file_name_validator.rb +14 -12
- data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +1 -2
- data/lib/paperclip/validators/attachment_presence_validator.rb +3 -5
- data/lib/paperclip/validators/attachment_size_validator.rb +28 -11
- data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +3 -1
- data/lib/paperclip/validators.rb +16 -17
- data/lib/paperclip/version.rb +1 -3
- data/lib/paperclip.rb +49 -48
- data/lib/tasks/paperclip.rake +23 -24
- data/paperclip.gemspec +29 -33
- data/shoulda_macros/paperclip.rb +16 -16
- data/spec/paperclip/attachment_definitions_spec.rb +5 -5
- data/spec/paperclip/attachment_processing_spec.rb +22 -23
- data/spec/paperclip/attachment_registry_spec.rb +15 -15
- data/spec/paperclip/attachment_spec.rb +238 -196
- data/spec/paperclip/content_type_detector_spec.rb +18 -12
- data/spec/paperclip/file_command_content_type_detector_spec.rb +10 -10
- data/spec/paperclip/filename_cleaner_spec.rb +3 -4
- data/spec/paperclip/geometry_detector_spec.rb +7 -8
- data/spec/paperclip/geometry_parser_spec.rb +31 -31
- data/spec/paperclip/geometry_spec.rb +24 -24
- data/spec/paperclip/glue_spec.rb +3 -5
- data/spec/paperclip/has_attached_file_spec.rb +46 -126
- data/spec/paperclip/integration_spec.rb +111 -77
- data/spec/paperclip/interpolations_spec.rb +101 -93
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +41 -13
- data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +8 -10
- data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +13 -14
- data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +4 -4
- data/spec/paperclip/io_adapters/file_adapter_spec.rb +12 -12
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +58 -37
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
- data/spec/paperclip/io_adapters/nil_adapter_spec.rb +2 -2
- data/spec/paperclip/io_adapters/registry_spec.rb +4 -4
- data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +10 -10
- data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +6 -6
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +90 -31
- data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +3 -3
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +4 -5
- data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +4 -4
- data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +4 -4
- data/spec/paperclip/media_type_spoof_detector_spec.rb +50 -24
- data/spec/paperclip/meta_class_spec.rb +3 -3
- data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +28 -24
- data/spec/paperclip/paperclip_spec.rb +15 -11
- data/spec/paperclip/plural_cache_spec.rb +8 -8
- data/spec/paperclip/processor_helpers_spec.rb +35 -35
- data/spec/paperclip/processor_spec.rb +8 -8
- data/spec/paperclip/rails_environment_spec.rb +7 -10
- data/spec/paperclip/rake_spec.rb +39 -39
- data/spec/paperclip/schema_spec.rb +57 -53
- data/spec/paperclip/storage/filesystem_spec.rb +29 -6
- data/spec/paperclip/storage/fog_spec.rb +122 -82
- data/spec/paperclip/storage/s3_live_spec.rb +22 -22
- data/spec/paperclip/storage/s3_spec.rb +649 -583
- data/spec/paperclip/style_spec.rb +67 -71
- data/spec/paperclip/tempfile_factory_spec.rb +5 -5
- data/spec/paperclip/thumbnail_spec.rb +68 -67
- data/spec/paperclip/url_generator_spec.rb +18 -19
- data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +115 -27
- data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +105 -16
- data/spec/paperclip/validators/attachment_presence_validator_spec.rb +5 -5
- data/spec/paperclip/validators/attachment_size_validator_spec.rb +111 -21
- data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +9 -13
- data/spec/paperclip/validators_spec.rb +61 -46
- data/spec/spec_helper.rb +21 -23
- data/spec/support/assertions.rb +8 -6
- data/spec/support/fake_model.rb +1 -2
- data/spec/support/fake_rails.rb +1 -1
- data/spec/support/fixtures/aws_s3.yml +13 -0
- data/spec/support/fixtures/sample.xlsm +0 -0
- data/spec/support/matchers/exist.rb +1 -1
- data/spec/support/matchers/have_column.rb +1 -1
- data/spec/support/mock_url_generator_builder.rb +2 -3
- data/spec/support/model_reconstruction.rb +16 -12
- data/spec/support/reporting.rb +1 -1
- data/spec/support/test_data.rb +2 -2
- metadata +58 -106
- data/spec/support/conditional_filter_helper.rb +0 -5
@@ -1,24 +1,41 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
1
|
+
require "spec_helper"
|
2
|
+
require "open-uri"
|
3
|
+
|
4
|
+
describe "Paperclip" do
|
5
|
+
around do |example|
|
6
|
+
files_before = ObjectSpace.each_object(Tempfile).select do |file|
|
7
|
+
file.path && File.file?(file.path)
|
8
|
+
end
|
9
|
+
|
10
|
+
example.run
|
11
|
+
|
12
|
+
files_after = ObjectSpace.each_object(Tempfile).select do |file|
|
13
|
+
file.path && File.file?(file.path)
|
14
|
+
end
|
15
|
+
|
16
|
+
diff = files_after - files_before
|
17
|
+
expect(diff).to eq([]), "Leaked tempfiles: #{diff.inspect}"
|
18
|
+
end
|
4
19
|
|
5
|
-
describe 'Paperclip' do
|
6
20
|
context "Many models at once" do
|
7
21
|
before do
|
8
22
|
rebuild_model
|
9
|
-
@file = File.new(fixture_file("5k.png"),
|
23
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
10
24
|
# Deals with `Too many open files` error
|
11
|
-
|
12
|
-
Dummy.import
|
13
|
-
|
25
|
+
dummies = Array.new(300) { Dummy.new avatar: @file }
|
26
|
+
Dummy.import dummies
|
27
|
+
# save attachment instances to run after hooks including tempfile cleanup
|
28
|
+
# since activerecord-import does not use our usually hooked-in hooks
|
29
|
+
# (such as after_save)
|
30
|
+
dummies.each { |dummy| dummy.avatar.save }
|
14
31
|
end
|
15
32
|
|
16
33
|
after { @file.close }
|
17
34
|
|
18
35
|
it "does not exceed the open file limit" do
|
19
|
-
|
20
|
-
|
21
|
-
|
36
|
+
assert_nothing_raised do
|
37
|
+
Dummy.all.each(&:avatar)
|
38
|
+
end
|
22
39
|
end
|
23
40
|
end
|
24
41
|
|
@@ -26,7 +43,7 @@ describe 'Paperclip' do
|
|
26
43
|
before do
|
27
44
|
rebuild_model styles: { thumb: "50x50#" }
|
28
45
|
@dummy = Dummy.new
|
29
|
-
@file = File.new(fixture_file("5k.png"),
|
46
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
30
47
|
@dummy.avatar = @file
|
31
48
|
assert @dummy.save
|
32
49
|
end
|
@@ -37,8 +54,8 @@ describe 'Paperclip' do
|
|
37
54
|
assert_match(/\b50x50\b/, `identify "#{@dummy.avatar.path(:thumb)}"`)
|
38
55
|
end
|
39
56
|
|
40
|
-
context
|
41
|
-
before { File.chmod(
|
57
|
+
context "reprocessing with unreadable original" do
|
58
|
+
before { File.chmod(0o000, @dummy.avatar.path) }
|
42
59
|
|
43
60
|
it "does not raise an error" do
|
44
61
|
assert_nothing_raised do
|
@@ -54,13 +71,13 @@ describe 'Paperclip' do
|
|
54
71
|
end
|
55
72
|
end
|
56
73
|
|
57
|
-
after { File.chmod(
|
74
|
+
after { File.chmod(0o644, @dummy.avatar.path) }
|
58
75
|
end
|
59
76
|
|
60
77
|
context "redefining its attachment styles" do
|
61
78
|
before do
|
62
79
|
Dummy.class_eval do
|
63
|
-
has_attached_file :avatar, styles: { thumb: "150x25#", dynamic: lambda { |
|
80
|
+
has_attached_file :avatar, styles: { thumb: "150x25#", dynamic: lambda { |_a| "50x50#" } }
|
64
81
|
end
|
65
82
|
@d2 = Dummy.find(@dummy.id)
|
66
83
|
@original_timestamp = @d2.avatar_updated_at
|
@@ -85,8 +102,7 @@ describe 'Paperclip' do
|
|
85
102
|
File.delete(@thumb_path) if File.exist?(@thumb_path)
|
86
103
|
rebuild_model styles: { thumb: "50x50#" }
|
87
104
|
@dummy = Dummy.new
|
88
|
-
@file = File.new(fixture_file("5k.png"),
|
89
|
-
|
105
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
90
106
|
end
|
91
107
|
|
92
108
|
after { @file.close }
|
@@ -114,7 +130,7 @@ describe 'Paperclip' do
|
|
114
130
|
File.delete(@thumb_large_path) if File.exist?(@thumb_large_path)
|
115
131
|
rebuild_model styles: { thumb_small: "50x50#", thumb_large: "60x60#" }
|
116
132
|
@dummy = Dummy.new
|
117
|
-
@file = File.new(fixture_file("5k.png"),
|
133
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
118
134
|
|
119
135
|
@dummy.avatar.post_processing = false
|
120
136
|
@dummy.avatar = @file
|
@@ -135,6 +151,14 @@ describe 'Paperclip' do
|
|
135
151
|
end
|
136
152
|
|
137
153
|
it "allows us to selectively create each thumbnail" do
|
154
|
+
skip <<-EXPLANATION
|
155
|
+
#reprocess! calls #assign which calls Paperclip.io_adapters.for
|
156
|
+
which creates the tempfile. #assign then calls #post_process_file which
|
157
|
+
calls MediaTypeSpoofDetectionValidator#validate_each which calls
|
158
|
+
Paperclip.io_adapters.for, which creates another tempfile. That first
|
159
|
+
tempfile is the one that leaks.
|
160
|
+
EXPLANATION
|
161
|
+
|
138
162
|
assert_file_not_exists(@thumb_small_path)
|
139
163
|
assert_file_not_exists(@thumb_large_path)
|
140
164
|
|
@@ -151,7 +175,7 @@ describe 'Paperclip' do
|
|
151
175
|
before do
|
152
176
|
rebuild_model styles: { original: "2x2#" }
|
153
177
|
@dummy = Dummy.new
|
154
|
-
@file = File.new(fixture_file("5k.png"),
|
178
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
155
179
|
@dummy.avatar = @file
|
156
180
|
end
|
157
181
|
|
@@ -159,16 +183,20 @@ describe 'Paperclip' do
|
|
159
183
|
assert_not_equal File.size(@file.path), @dummy.avatar.size
|
160
184
|
end
|
161
185
|
|
162
|
-
after
|
186
|
+
after do
|
187
|
+
@file.close
|
188
|
+
# save attachment instance to run after hooks (including tempfile cleanup)
|
189
|
+
@dummy.avatar.save
|
190
|
+
end
|
163
191
|
end
|
164
192
|
|
165
193
|
context "A model with attachments scoped under an id" do
|
166
194
|
before do
|
167
195
|
rebuild_model styles: { large: "100x100",
|
168
|
-
|
196
|
+
medium: "50x50" },
|
169
197
|
path: ":rails_root/tmp/:id/:attachments/:style.:extension"
|
170
198
|
@dummy = Dummy.new
|
171
|
-
@file = File.new(fixture_file("5k.png"),
|
199
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
172
200
|
@dummy.avatar = @file
|
173
201
|
end
|
174
202
|
|
@@ -200,9 +228,9 @@ describe 'Paperclip' do
|
|
200
228
|
end
|
201
229
|
end
|
202
230
|
|
203
|
-
context
|
231
|
+
context "and deleted where the delete fails" do
|
204
232
|
it "does not die if an unexpected SystemCallError happens" do
|
205
|
-
FileUtils.
|
233
|
+
allow(FileUtils).to receive(:rmdir).and_raise(Errno::EPIPE)
|
206
234
|
assert_nothing_raised do
|
207
235
|
@dummy.avatar.clear
|
208
236
|
@dummy.save
|
@@ -212,12 +240,12 @@ describe 'Paperclip' do
|
|
212
240
|
end
|
213
241
|
end
|
214
242
|
|
215
|
-
[
|
243
|
+
[0o00, 0o02, 0o22].each do |umask|
|
216
244
|
context "when the umask is #{umask}" do
|
217
245
|
before do
|
218
246
|
rebuild_model
|
219
247
|
@dummy = Dummy.new
|
220
|
-
@file = File.new(fixture_file("5k.png"),
|
248
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
221
249
|
@umask = File.umask(umask)
|
222
250
|
end
|
223
251
|
|
@@ -229,17 +257,17 @@ describe 'Paperclip' do
|
|
229
257
|
it "respects the current umask" do
|
230
258
|
@dummy.avatar = @file
|
231
259
|
@dummy.save
|
232
|
-
assert_equal
|
260
|
+
assert_equal 0o666 & ~umask, 0o666 & File.stat(@dummy.avatar.path).mode
|
233
261
|
end
|
234
262
|
end
|
235
263
|
end
|
236
264
|
|
237
|
-
[
|
265
|
+
[0o666, 0o664, 0o640].each do |perms|
|
238
266
|
context "when the perms are #{perms}" do
|
239
267
|
before do
|
240
268
|
rebuild_model override_file_permissions: perms
|
241
269
|
@dummy = Dummy.new
|
242
|
-
@file = File.new(fixture_file("5k.png"),
|
270
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
243
271
|
end
|
244
272
|
|
245
273
|
after do
|
@@ -249,13 +277,13 @@ describe 'Paperclip' do
|
|
249
277
|
it "respects the current perms" do
|
250
278
|
@dummy.avatar = @file
|
251
279
|
@dummy.save
|
252
|
-
assert_equal perms, File.stat(@dummy.avatar.path).mode &
|
280
|
+
assert_equal perms, File.stat(@dummy.avatar.path).mode & 0o777
|
253
281
|
end
|
254
282
|
end
|
255
283
|
end
|
256
284
|
|
257
285
|
it "skips chmod operation, when override_file_permissions is set to false (e.g. useful when using CIFS mounts)" do
|
258
|
-
FileUtils.
|
286
|
+
expect(FileUtils).to_not receive(:chmod)
|
259
287
|
|
260
288
|
rebuild_model override_file_permissions: false
|
261
289
|
dummy = Dummy.create!
|
@@ -266,14 +294,14 @@ describe 'Paperclip' do
|
|
266
294
|
context "A model with a filesystem attachment" do
|
267
295
|
before do
|
268
296
|
rebuild_model styles: { large: "300x300>",
|
269
|
-
|
270
|
-
|
297
|
+
medium: "100x100",
|
298
|
+
thumb: ["32x32#", :gif] },
|
271
299
|
default_style: :medium,
|
272
300
|
url: "/:attachment/:class/:style/:id/:basename.:extension",
|
273
301
|
path: ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
|
274
302
|
@dummy = Dummy.new
|
275
|
-
@file = File.new(fixture_file("5k.png"),
|
276
|
-
@bad_file = File.new(fixture_file("bad.png"),
|
303
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
304
|
+
@bad_file = File.new(fixture_file("bad.png"), "rb")
|
277
305
|
|
278
306
|
assert @dummy.avatar = @file
|
279
307
|
assert @dummy.valid?, @dummy.errors.full_messages.join(", ")
|
@@ -287,11 +315,11 @@ describe 'Paperclip' do
|
|
287
315
|
["300x46", :large],
|
288
316
|
["100x15", :medium],
|
289
317
|
["32x32", :thumb]].each do |geo, style|
|
290
|
-
cmd = %
|
318
|
+
cmd = %[identify -format "%wx%h" "#{@dummy.avatar.path(style)}"]
|
291
319
|
assert_equal geo, `#{cmd}`.chomp, cmd
|
292
320
|
end
|
293
321
|
|
294
|
-
saved_paths = [:thumb, :medium, :large, :original].
|
322
|
+
saved_paths = [:thumb, :medium, :large, :original].map { |s| @dummy.avatar.path(s) }
|
295
323
|
|
296
324
|
@d2 = Dummy.find(@dummy.id)
|
297
325
|
assert_equal "100x15", `identify -format "%wx%h" "#{@d2.avatar.path}"`.chomp
|
@@ -328,7 +356,7 @@ describe 'Paperclip' do
|
|
328
356
|
assert_equal @dummy.avatar.path(style), @d2.avatar.path(style)
|
329
357
|
end
|
330
358
|
|
331
|
-
saved_paths = [:thumb, :medium, :large, :original].
|
359
|
+
saved_paths = [:thumb, :medium, :large, :original].map { |s| @dummy.avatar.path(s) }
|
332
360
|
|
333
361
|
@d2.avatar.clear
|
334
362
|
assert @d2.save
|
@@ -346,16 +374,23 @@ describe 'Paperclip' do
|
|
346
374
|
|
347
375
|
it "is not ok with bad files" do
|
348
376
|
@dummy.avatar = @bad_file
|
349
|
-
assert
|
377
|
+
assert !@dummy.valid?
|
378
|
+
# save attachment instance to run after hooks (including tempfile cleanup)
|
379
|
+
@dummy.avatar.save
|
350
380
|
end
|
351
381
|
|
352
382
|
it "knows the difference between good files, bad files, and not files when validating" do
|
353
383
|
Dummy.validates_attachment_presence :avatar
|
354
384
|
@d2 = Dummy.find(@dummy.id)
|
355
385
|
@d2.avatar = @file
|
356
|
-
assert
|
386
|
+
assert @d2.valid?, @d2.errors.full_messages.inspect
|
387
|
+
# save attachment instance to run after hooks (including tempfile cleanup)
|
388
|
+
@d2.avatar.save
|
389
|
+
|
357
390
|
@d2.avatar = @bad_file
|
358
|
-
assert
|
391
|
+
assert !@d2.valid?
|
392
|
+
# save attachment instance to run after hooks (including tempfile cleanup)
|
393
|
+
@d2.avatar.save
|
359
394
|
end
|
360
395
|
|
361
396
|
it "is able to reload without saving and not have the file disappear" do
|
@@ -370,7 +405,7 @@ describe 'Paperclip' do
|
|
370
405
|
context "that is assigned its file from another Paperclip attachment" do
|
371
406
|
before do
|
372
407
|
@dummy2 = Dummy.new
|
373
|
-
@file2 = File.new(fixture_file("12k.png"),
|
408
|
+
@file2 = File.new(fixture_file("12k.png"), "rb")
|
374
409
|
assert @dummy2.avatar = @file2
|
375
410
|
@dummy2.save
|
376
411
|
end
|
@@ -379,25 +414,24 @@ describe 'Paperclip' do
|
|
379
414
|
|
380
415
|
it "works when assigned a file" do
|
381
416
|
assert_not_equal `identify -format "%wx%h" "#{@dummy.avatar.path(:original)}"`,
|
382
|
-
|
417
|
+
`identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
|
383
418
|
|
384
419
|
assert @dummy.avatar = @dummy2.avatar
|
385
420
|
@dummy.save
|
386
421
|
assert_equal @dummy.avatar_file_name, @dummy2.avatar_file_name
|
387
422
|
assert_equal `identify -format "%wx%h" "#{@dummy.avatar.path(:original)}"`,
|
388
|
-
|
423
|
+
`identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
|
389
424
|
end
|
390
425
|
end
|
391
|
-
|
392
426
|
end
|
393
427
|
|
394
428
|
context "A model with an attachments association and a Paperclip attachment" do
|
395
429
|
before do
|
396
430
|
Dummy.class_eval do
|
397
|
-
has_many :attachments, class_name:
|
431
|
+
has_many :attachments, class_name: "Dummy"
|
398
432
|
end
|
399
433
|
|
400
|
-
@file = File.new(fixture_file("5k.png"),
|
434
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
401
435
|
@dummy = Dummy.new
|
402
436
|
@dummy.avatar = @file
|
403
437
|
end
|
@@ -412,13 +446,13 @@ describe 'Paperclip' do
|
|
412
446
|
context "A model with an attachment with hash in file name" do
|
413
447
|
before do
|
414
448
|
@settings = { styles: { thumb: "50x50#" },
|
415
|
-
|
416
|
-
|
417
|
-
|
449
|
+
path: ":rails_root/public/system/:attachment/:id_partition/:style/:hash.:extension",
|
450
|
+
url: "/system/:attachment/:id_partition/:style/:hash.:extension",
|
451
|
+
hash_secret: "somesecret" }
|
418
452
|
|
419
453
|
rebuild_model @settings
|
420
454
|
|
421
|
-
@file = File.new(fixture_file("5k.png"),
|
455
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
422
456
|
@dummy = Dummy.create! avatar: @file
|
423
457
|
end
|
424
458
|
|
@@ -435,7 +469,7 @@ describe 'Paperclip' do
|
|
435
469
|
before do
|
436
470
|
@dummy.avatar.options[:styles][:mini] = "25x25#"
|
437
471
|
@dummy.avatar.instance_variable_set :@normalized_styles, nil
|
438
|
-
Time.
|
472
|
+
allow(Time).to receive(:now).and_return(Time.now + 10)
|
439
473
|
@dummy.avatar.reprocess!
|
440
474
|
@dummy.reload
|
441
475
|
end
|
@@ -448,8 +482,8 @@ describe 'Paperclip' do
|
|
448
482
|
end
|
449
483
|
end
|
450
484
|
|
451
|
-
if ENV[
|
452
|
-
def s3_files_for
|
485
|
+
if ENV["S3_BUCKET"]
|
486
|
+
def s3_files_for(attachment)
|
453
487
|
[:thumb, :medium, :large, :original].inject({}) do |files, style|
|
454
488
|
data = `curl "#{attachment.url(style)}" 2>/dev/null`.chomp
|
455
489
|
t = Tempfile.new("paperclip-test")
|
@@ -461,8 +495,8 @@ describe 'Paperclip' do
|
|
461
495
|
end
|
462
496
|
end
|
463
497
|
|
464
|
-
def s3_headers_for
|
465
|
-
`curl --head "#{attachment.url(style)}" 2>/dev/null`.split("\n").inject({}) do |h,head|
|
498
|
+
def s3_headers_for(attachment, style)
|
499
|
+
`curl --head "#{attachment.url(style)}" 2>/dev/null`.split("\n").inject({}) do |h, head|
|
466
500
|
split_head = head.chomp.split(/\s*:\s*/, 2)
|
467
501
|
h[split_head.first.downcase] = split_head.last unless split_head.empty?
|
468
502
|
h
|
@@ -478,21 +512,21 @@ describe 'Paperclip' do
|
|
478
512
|
thumb: ["32x32#", :gif],
|
479
513
|
custom: {
|
480
514
|
geometry: "32x32#",
|
481
|
-
s3_headers: {
|
482
|
-
s3_metadata: {
|
515
|
+
s3_headers: { "Cache-Control" => "max-age=31557600" },
|
516
|
+
s3_metadata: { "foo" => "bar" }
|
483
517
|
}
|
484
518
|
},
|
485
519
|
storage: :s3,
|
486
|
-
s3_credentials: File.new(fixture_file(
|
520
|
+
s3_credentials: File.new(fixture_file("s3.yml")),
|
487
521
|
s3_options: { logger: Paperclip.logger },
|
488
522
|
default_style: :medium,
|
489
|
-
bucket: ENV[
|
523
|
+
bucket: ENV["S3_BUCKET"],
|
490
524
|
path: ":class/:attachment/:id/:style/:basename.:extension"
|
491
525
|
)
|
492
526
|
|
493
527
|
@dummy = Dummy.new
|
494
|
-
@file = File.new(fixture_file(
|
495
|
-
@bad_file = File.new(fixture_file(
|
528
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
529
|
+
@bad_file = File.new(fixture_file("bad.png"), "rb")
|
496
530
|
|
497
531
|
@dummy.avatar = @file
|
498
532
|
@dummy.valid?
|
@@ -507,7 +541,7 @@ describe 'Paperclip' do
|
|
507
541
|
@files_on_s3.values.each(&:close) if @files_on_s3
|
508
542
|
end
|
509
543
|
|
510
|
-
context
|
544
|
+
context "assigning itself to a new model" do
|
511
545
|
before do
|
512
546
|
@d2 = Dummy.new
|
513
547
|
@d2.avatar = @dummy.avatar
|
@@ -528,7 +562,7 @@ describe 'Paperclip' do
|
|
528
562
|
["300x46", :large],
|
529
563
|
["100x15", :medium],
|
530
564
|
["32x32", :thumb]].each do |geo, style|
|
531
|
-
cmd = %
|
565
|
+
cmd = %[identify -format "%wx%h" "#{@files_on_s3[style].path}"]
|
532
566
|
assert_equal geo, `#{cmd}`.chomp, cmd
|
533
567
|
end
|
534
568
|
|
@@ -538,7 +572,7 @@ describe 'Paperclip' do
|
|
538
572
|
["300x46", :large],
|
539
573
|
["100x15", :medium],
|
540
574
|
["32x32", :thumb]].each do |geo, style|
|
541
|
-
cmd = %
|
575
|
+
cmd = %[identify -format "%wx%h" "#{@d2_files[style].path}"]
|
542
576
|
assert_equal geo, `#{cmd}`.chomp, cmd
|
543
577
|
end
|
544
578
|
|
@@ -548,7 +582,7 @@ describe 'Paperclip' do
|
|
548
582
|
assert @dummy.save
|
549
583
|
|
550
584
|
[:thumb, :medium, :large, :original].each do |style|
|
551
|
-
assert
|
585
|
+
assert !@dummy.avatar.exists?(style)
|
552
586
|
end
|
553
587
|
|
554
588
|
@d2 = Dummy.find(@dummy.id)
|
@@ -575,24 +609,24 @@ describe 'Paperclip' do
|
|
575
609
|
assert @d2.save
|
576
610
|
|
577
611
|
[:thumb, :medium, :large, :original].each do |style|
|
578
|
-
assert
|
612
|
+
assert !@dummy.avatar.exists?(style)
|
579
613
|
end
|
580
614
|
end
|
581
615
|
|
582
616
|
it "knows the difference between good files, bad files, and nil" do
|
583
617
|
@dummy.avatar = @bad_file
|
584
|
-
assert
|
618
|
+
assert !@dummy.valid?
|
585
619
|
@dummy.avatar = nil
|
586
620
|
assert @dummy.valid?
|
587
621
|
|
588
622
|
Dummy.validates_attachment_presence :avatar
|
589
623
|
@d2 = Dummy.find(@dummy.id)
|
590
624
|
@d2.avatar = @file
|
591
|
-
assert
|
625
|
+
assert @d2.valid?
|
592
626
|
@d2.avatar = @bad_file
|
593
|
-
assert
|
627
|
+
assert !@d2.valid?
|
594
628
|
@d2.avatar = nil
|
595
|
-
assert
|
629
|
+
assert !@d2.valid?
|
596
630
|
end
|
597
631
|
|
598
632
|
it "is able to reload without saving and not have the file disappear" do
|
@@ -606,22 +640,22 @@ describe 'Paperclip' do
|
|
606
640
|
|
607
641
|
it "has the right content type" do
|
608
642
|
headers = s3_headers_for(@dummy.avatar, :original)
|
609
|
-
assert_equal
|
643
|
+
assert_equal "image/png", headers["content-type"]
|
610
644
|
end
|
611
645
|
|
612
646
|
it "has the right style-specific headers" do
|
613
647
|
headers = s3_headers_for(@dummy.avatar, :custom)
|
614
|
-
assert_equal
|
648
|
+
assert_equal "max-age=31557600", headers["cache-control"]
|
615
649
|
end
|
616
650
|
|
617
651
|
it "has the right style-specific metadata" do
|
618
652
|
headers = s3_headers_for(@dummy.avatar, :custom)
|
619
|
-
assert_equal
|
653
|
+
assert_equal "bar", headers["x-amz-meta-foo"]
|
620
654
|
end
|
621
655
|
|
622
656
|
context "with non-english character in the file name" do
|
623
657
|
before do
|
624
|
-
@file.
|
658
|
+
allow(@file).to receive(:original_filename).and_return("クリップ.png")
|
625
659
|
@dummy.avatar = @file
|
626
660
|
end
|
627
661
|
|
@@ -635,7 +669,7 @@ describe 'Paperclip' do
|
|
635
669
|
context "Copying attachments between models" do
|
636
670
|
before do
|
637
671
|
rebuild_model
|
638
|
-
@file = File.new(fixture_file("5k.png"),
|
672
|
+
@file = File.new(fixture_file("5k.png"), "rb")
|
639
673
|
end
|
640
674
|
|
641
675
|
after { @file.close }
|