paperclip 4.2.2 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.codeclimate.yml +17 -0
- data/.hound.yml +1055 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +17 -15
- data/Appraisals +4 -16
- data/CONTRIBUTING.md +19 -8
- data/Gemfile +5 -9
- data/LICENSE +1 -1
- data/NEWS +148 -31
- data/README.md +327 -191
- data/RELEASING.md +17 -0
- data/Rakefile +2 -2
- data/UPGRADING +12 -9
- data/features/basic_integration.feature +10 -6
- data/features/migration.feature +0 -24
- data/features/step_definitions/attachment_steps.rb +33 -27
- data/features/step_definitions/html_steps.rb +2 -2
- data/features/step_definitions/rails_steps.rb +39 -38
- data/features/step_definitions/s3_steps.rb +2 -2
- data/features/step_definitions/web_steps.rb +1 -103
- data/features/support/env.rb +1 -0
- data/features/support/file_helpers.rb +2 -2
- data/features/support/paths.rb +1 -1
- data/features/support/rails.rb +0 -24
- data/gemfiles/4.2.gemfile +6 -8
- data/gemfiles/5.0.gemfile +17 -0
- data/lib/paperclip/attachment.rb +32 -20
- data/lib/paperclip/attachment_registry.rb +3 -2
- data/lib/paperclip/callbacks.rb +8 -6
- data/lib/paperclip/content_type_detector.rb +27 -11
- data/lib/paperclip/errors.rb +3 -1
- data/lib/paperclip/file_command_content_type_detector.rb +6 -8
- data/lib/paperclip/geometry_parser_factory.rb +1 -1
- data/lib/paperclip/glue.rb +1 -1
- data/lib/paperclip/has_attached_file.rb +9 -2
- data/lib/paperclip/helpers.rb +14 -10
- data/lib/paperclip/interpolations/plural_cache.rb +6 -5
- data/lib/paperclip/interpolations.rb +19 -14
- data/lib/paperclip/io_adapters/abstract_adapter.rb +26 -3
- data/lib/paperclip/io_adapters/attachment_adapter.rb +10 -5
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +8 -8
- data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
- data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +7 -7
- data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
- data/lib/paperclip/io_adapters/registry.rb +6 -2
- data/lib/paperclip/io_adapters/stringio_adapter.rb +9 -6
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
- data/lib/paperclip/io_adapters/uri_adapter.rb +41 -19
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
- data/lib/paperclip/media_type_spoof_detector.rb +2 -2
- data/lib/paperclip/processor.rb +5 -4
- data/lib/paperclip/rails_environment.rb +25 -0
- data/lib/paperclip/schema.rb +3 -9
- data/lib/paperclip/storage/filesystem.rb +13 -2
- data/lib/paperclip/storage/fog.rb +30 -18
- data/lib/paperclip/storage/s3.rb +92 -65
- data/lib/paperclip/thumbnail.rb +16 -7
- data/lib/paperclip/url_generator.rb +16 -13
- data/lib/paperclip/validators/attachment_size_validator.rb +1 -7
- data/lib/paperclip/validators.rb +1 -1
- data/lib/paperclip/version.rb +3 -1
- data/lib/paperclip.rb +25 -12
- data/lib/tasks/paperclip.rake +33 -3
- data/paperclip.gemspec +18 -15
- data/spec/paperclip/attachment_definitions_spec.rb +1 -1
- data/spec/paperclip/attachment_processing_spec.rb +2 -4
- data/spec/paperclip/attachment_registry_spec.rb +84 -13
- data/spec/paperclip/attachment_spec.rb +130 -39
- data/spec/paperclip/content_type_detector_spec.rb +8 -1
- data/spec/paperclip/file_command_content_type_detector_spec.rb +0 -1
- data/spec/paperclip/geometry_spec.rb +1 -1
- data/spec/paperclip/glue_spec.rb +44 -0
- data/spec/paperclip/has_attached_file_spec.rb +24 -8
- data/spec/paperclip/integration_spec.rb +4 -3
- data/spec/paperclip/interpolations_spec.rb +16 -13
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +47 -23
- data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +6 -3
- data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +7 -1
- data/spec/paperclip/io_adapters/file_adapter_spec.rb +6 -3
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +26 -6
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
- data/spec/paperclip/io_adapters/registry_spec.rb +2 -2
- data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +5 -1
- data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +5 -5
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +77 -7
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +10 -0
- data/spec/paperclip/media_type_spoof_detector_spec.rb +34 -11
- data/spec/paperclip/paperclip_spec.rb +4 -29
- data/spec/paperclip/plural_cache_spec.rb +17 -16
- data/spec/paperclip/rails_environment_spec.rb +33 -0
- data/spec/paperclip/storage/fog_spec.rb +58 -3
- data/spec/paperclip/storage/s3_live_spec.rb +20 -14
- data/spec/paperclip/storage/s3_spec.rb +398 -213
- data/spec/paperclip/tempfile_factory_spec.rb +4 -0
- data/spec/paperclip/tempfile_spec.rb +35 -0
- data/spec/paperclip/thumbnail_spec.rb +51 -32
- data/spec/paperclip/url_generator_spec.rb +55 -44
- data/spec/paperclip/validators/attachment_size_validator_spec.rb +26 -20
- data/spec/paperclip/validators_spec.rb +5 -5
- data/spec/spec_helper.rb +8 -1
- data/spec/support/assertions.rb +12 -1
- data/spec/support/conditional_filter_helper.rb +5 -0
- data/spec/support/fake_model.rb +4 -0
- data/spec/support/fixtures/empty.xlsx +0 -0
- data/spec/support/matchers/have_column.rb +11 -2
- data/spec/support/mock_attachment.rb +2 -0
- data/spec/support/mock_url_generator_builder.rb +2 -2
- data/spec/support/model_reconstruction.rb +9 -1
- data/spec/support/reporting.rb +11 -0
- metadata +109 -162
- data/RUNNING_TESTS.md +0 -4
- data/cucumber/paperclip_steps.rb +0 -6
- data/gemfiles/3.2.gemfile +0 -19
- data/gemfiles/4.0.gemfile +0 -19
- data/gemfiles/4.1.gemfile +0 -19
- data/lib/paperclip/locales/de.yml +0 -18
- data/lib/paperclip/locales/es.yml +0 -18
- data/lib/paperclip/locales/ja.yml +0 -18
- data/lib/paperclip/locales/pt-BR.yml +0 -18
- data/lib/paperclip/locales/zh-CN.yml +0 -18
- data/lib/paperclip/locales/zh-HK.yml +0 -18
- data/lib/paperclip/locales/zh-TW.yml +0 -18
- data/spec/support/mock_model.rb +0 -2
- data/spec/support/rails_helpers.rb +0 -7
|
@@ -38,6 +38,15 @@ describe Paperclip::HasAttachedFile do
|
|
|
38
38
|
assert_adding_attachment('avatar').defines_callback('after_commit')
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
context 'when the class does not allow after_commit callbacks' do
|
|
42
|
+
it 'defines an after_destroy callback' do
|
|
43
|
+
assert_adding_attachment(
|
|
44
|
+
'avatar',
|
|
45
|
+
unstub_methods: [:after_commit]
|
|
46
|
+
).defines_callback('after_destroy')
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
41
50
|
it 'defines the Paperclip-specific callbacks' do
|
|
42
51
|
assert_adding_attachment('avatar').defines_callback('define_paperclip_callbacks')
|
|
43
52
|
end
|
|
@@ -53,20 +62,26 @@ describe Paperclip::HasAttachedFile do
|
|
|
53
62
|
|
|
54
63
|
private
|
|
55
64
|
|
|
56
|
-
def assert_adding_attachment(attachment_name)
|
|
57
|
-
AttachmentAdder.new(attachment_name)
|
|
65
|
+
def assert_adding_attachment(attachment_name, options={})
|
|
66
|
+
AttachmentAdder.new(attachment_name, options)
|
|
58
67
|
end
|
|
59
68
|
|
|
60
69
|
class AttachmentAdder
|
|
61
70
|
include Mocha::API
|
|
62
71
|
include RSpec::Matchers
|
|
63
72
|
|
|
64
|
-
def initialize(attachment_name)
|
|
73
|
+
def initialize(attachment_name, options = {})
|
|
65
74
|
@attachment_name = attachment_name
|
|
75
|
+
@stubbed_class = stub_class
|
|
76
|
+
if options.present?
|
|
77
|
+
options[:unstub_methods].each do |method|
|
|
78
|
+
@stubbed_class.unstub(method)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
66
81
|
end
|
|
67
82
|
|
|
68
83
|
def defines_method(method_name)
|
|
69
|
-
a_class =
|
|
84
|
+
a_class = @stubbed_class
|
|
70
85
|
|
|
71
86
|
Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {})
|
|
72
87
|
|
|
@@ -74,7 +89,7 @@ describe Paperclip::HasAttachedFile do
|
|
|
74
89
|
end
|
|
75
90
|
|
|
76
91
|
def defines_class_method(method_name)
|
|
77
|
-
a_class =
|
|
92
|
+
a_class = @stubbed_class
|
|
78
93
|
a_class.class.stubs(:define_method)
|
|
79
94
|
|
|
80
95
|
Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {})
|
|
@@ -83,7 +98,7 @@ describe Paperclip::HasAttachedFile do
|
|
|
83
98
|
end
|
|
84
99
|
|
|
85
100
|
def defines_validation
|
|
86
|
-
a_class =
|
|
101
|
+
a_class = @stubbed_class
|
|
87
102
|
|
|
88
103
|
Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {})
|
|
89
104
|
|
|
@@ -91,7 +106,7 @@ describe Paperclip::HasAttachedFile do
|
|
|
91
106
|
end
|
|
92
107
|
|
|
93
108
|
def registers_attachment
|
|
94
|
-
a_class =
|
|
109
|
+
a_class = @stubbed_class
|
|
95
110
|
Paperclip::AttachmentRegistry.stubs(:register)
|
|
96
111
|
|
|
97
112
|
Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {size: 1})
|
|
@@ -100,7 +115,7 @@ describe Paperclip::HasAttachedFile do
|
|
|
100
115
|
end
|
|
101
116
|
|
|
102
117
|
def defines_callback(callback_name)
|
|
103
|
-
a_class =
|
|
118
|
+
a_class = @stubbed_class
|
|
104
119
|
|
|
105
120
|
Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {})
|
|
106
121
|
|
|
@@ -132,6 +147,7 @@ describe Paperclip::HasAttachedFile do
|
|
|
132
147
|
after_save: nil,
|
|
133
148
|
before_destroy: nil,
|
|
134
149
|
after_commit: nil,
|
|
150
|
+
after_destroy: nil,
|
|
135
151
|
define_paperclip_callbacks: nil,
|
|
136
152
|
extend: nil,
|
|
137
153
|
name: 'Billy',
|
|
@@ -7,9 +7,10 @@ describe 'Paperclip' do
|
|
|
7
7
|
before do
|
|
8
8
|
rebuild_model
|
|
9
9
|
@file = File.new(fixture_file("5k.png"), 'rb')
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
# Deals with `Too many open files` error
|
|
11
|
+
Dummy.import 100.times.map { Dummy.new avatar: @file }
|
|
12
|
+
Dummy.import 100.times.map { Dummy.new avatar: @file }
|
|
13
|
+
Dummy.import 100.times.map { Dummy.new avatar: @file }
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
after { @file.close }
|
|
@@ -24,15 +24,16 @@ describe Paperclip::Interpolations do
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
it "returns the class of the instance" do
|
|
27
|
+
class Thing ; end
|
|
27
28
|
attachment = mock
|
|
28
29
|
attachment.expects(:instance).returns(attachment)
|
|
29
|
-
attachment.expects(:class).returns(
|
|
30
|
+
attachment.expects(:class).returns(Thing)
|
|
30
31
|
assert_equal "things", Paperclip::Interpolations.class(attachment, :style)
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
it "returns the basename of the file" do
|
|
34
35
|
attachment = mock
|
|
35
|
-
attachment.expects(:original_filename).returns("one.jpg").times(
|
|
36
|
+
attachment.expects(:original_filename).returns("one.jpg").times(1)
|
|
36
37
|
assert_equal "one", Paperclip::Interpolations.basename(attachment, :style)
|
|
37
38
|
end
|
|
38
39
|
|
|
@@ -138,14 +139,7 @@ describe Paperclip::Interpolations do
|
|
|
138
139
|
assert_equal "000/000/023", Paperclip::Interpolations.id_partition(attachment, :style)
|
|
139
140
|
end
|
|
140
141
|
|
|
141
|
-
it "returns the partitioned id of the attachment when the id is a
|
|
142
|
-
attachment = mock
|
|
143
|
-
attachment.expects(:id).returns("fnj23")
|
|
144
|
-
attachment.expects(:instance).returns(attachment)
|
|
145
|
-
assert_equal "000/0fn/j23", Paperclip::Interpolations.id_partition(attachment, :style)
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
it "returns the partitioned id of the attachment when the id is a long string" do
|
|
142
|
+
it "returns the partitioned id of the attachment when the id is a string" do
|
|
149
143
|
attachment = mock
|
|
150
144
|
attachment.expects(:id).returns("32fnj23oio2f")
|
|
151
145
|
attachment.expects(:instance).returns(attachment)
|
|
@@ -194,14 +188,14 @@ describe Paperclip::Interpolations do
|
|
|
194
188
|
it "returns the filename as basename.extension" do
|
|
195
189
|
attachment = mock
|
|
196
190
|
attachment.expects(:styles).returns({})
|
|
197
|
-
attachment.expects(:original_filename).returns("one.jpg").times(
|
|
191
|
+
attachment.expects(:original_filename).returns("one.jpg").times(2)
|
|
198
192
|
assert_equal "one.jpg", Paperclip::Interpolations.filename(attachment, :style)
|
|
199
193
|
end
|
|
200
194
|
|
|
201
195
|
it "returns the filename as basename.extension when format supplied" do
|
|
202
196
|
attachment = mock
|
|
203
197
|
attachment.expects(:styles).returns({style: {format: :png}})
|
|
204
|
-
attachment.expects(:original_filename).returns("one.jpg").times(
|
|
198
|
+
attachment.expects(:original_filename).returns("one.jpg").times(1)
|
|
205
199
|
assert_equal "one.png", Paperclip::Interpolations.filename(attachment, :style)
|
|
206
200
|
end
|
|
207
201
|
|
|
@@ -211,7 +205,7 @@ describe Paperclip::Interpolations do
|
|
|
211
205
|
attachment.stubs(:original_filename).returns("one")
|
|
212
206
|
assert_equal "one", Paperclip::Interpolations.filename(attachment, :style)
|
|
213
207
|
end
|
|
214
|
-
|
|
208
|
+
|
|
215
209
|
it "returns the basename when the extension contains regexp special characters" do
|
|
216
210
|
attachment = mock
|
|
217
211
|
attachment.stubs(:styles).returns({})
|
|
@@ -256,4 +250,13 @@ describe Paperclip::Interpolations do
|
|
|
256
250
|
value = Paperclip::Interpolations.interpolate(":notreal/:id/:attachment", :attachment, :style)
|
|
257
251
|
assert_equal ":notreal/1234/attachments", value
|
|
258
252
|
end
|
|
253
|
+
|
|
254
|
+
it "handles question marks" do
|
|
255
|
+
Paperclip.interpolates :foo? do
|
|
256
|
+
"bar"
|
|
257
|
+
end
|
|
258
|
+
Paperclip::Interpolations.expects(:fool).never
|
|
259
|
+
value = Paperclip::Interpolations.interpolate(":fo/:foo?")
|
|
260
|
+
assert_equal ":fo/bar", value
|
|
261
|
+
end
|
|
259
262
|
end
|
|
@@ -9,69 +9,93 @@ describe Paperclip::AbstractAdapter do
|
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
subject { TestAdapter.new(nil) }
|
|
13
|
+
|
|
14
|
+
context "content type from file contents" do
|
|
13
15
|
before do
|
|
14
|
-
|
|
15
|
-
@adapter.stubs(:path).returns("image.png")
|
|
16
|
+
subject.stubs(:path).returns("image.png")
|
|
16
17
|
Paperclip.stubs(:run).returns("image/png\n")
|
|
18
|
+
Paperclip::ContentTypeDetector.any_instance.stubs(:type_from_mime_magic).returns("image/png")
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
it "returns the content type without newline" do
|
|
20
|
-
assert_equal "image/png",
|
|
22
|
+
assert_equal "image/png", subject.content_type
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
context "nil?" do
|
|
25
27
|
it "returns false" do
|
|
26
|
-
assert !
|
|
28
|
+
assert !subject.nil?
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
context "delegation" do
|
|
31
33
|
before do
|
|
32
|
-
|
|
33
|
-
@adapter.tempfile = stub("Tempfile")
|
|
34
|
+
subject.tempfile = stub("Tempfile")
|
|
34
35
|
end
|
|
35
36
|
|
|
36
|
-
[:binmode, :binmode?, :close, :close!, :closed?, :eof?, :path, :rewind, :unlink].each do |method|
|
|
37
|
+
[:binmode, :binmode?, :close, :close!, :closed?, :eof?, :path, :readbyte, :rewind, :unlink].each do |method|
|
|
37
38
|
it "delegates #{method} to @tempfile" do
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
assert_received
|
|
39
|
+
subject.tempfile.stubs(method)
|
|
40
|
+
subject.public_send(method)
|
|
41
|
+
assert_received subject.tempfile, method
|
|
41
42
|
end
|
|
42
43
|
end
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
it 'gets rid of slashes and colons in filenames' do
|
|
46
|
-
|
|
47
|
-
@adapter.original_filename = "awesome/file:name.png"
|
|
47
|
+
subject.original_filename = "awesome/file:name.png"
|
|
48
48
|
|
|
49
|
-
assert_equal "awesome_file_name.png",
|
|
49
|
+
assert_equal "awesome_file_name.png", subject.original_filename
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it 'is an assignment' do
|
|
53
|
-
assert
|
|
53
|
+
assert subject.assignment?
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
it 'is not nil' do
|
|
57
|
-
assert !
|
|
57
|
+
assert !subject.nil?
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
it "generates a destination filename with no original filename" do
|
|
61
|
-
|
|
62
|
-
expect(@adapter.send(:destination).path).to_not be_nil
|
|
61
|
+
expect(subject.send(:destination).path).to_not be_nil
|
|
63
62
|
end
|
|
64
63
|
|
|
65
64
|
it 'uses the original filename to generate the tempfile' do
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
subject.original_filename = "file.png"
|
|
66
|
+
expect(subject.send(:destination).path).to end_with(".png")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "generates a fingerprint" do
|
|
70
|
+
subject { TestAdapter.new(nil, options) }
|
|
71
|
+
|
|
72
|
+
before do
|
|
73
|
+
subject.stubs(:path).returns(fixture_file("50x50.png"))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context "MD5" do
|
|
77
|
+
let(:options) { { hash_digest: Digest::MD5 } }
|
|
78
|
+
|
|
79
|
+
it "returns a fingerprint" do
|
|
80
|
+
expect(subject.fingerprint).to be_a String
|
|
81
|
+
expect(subject.fingerprint).to eq "a790b00c9b5d58a8fd17a1ec5a187129"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context "SHA256" do
|
|
86
|
+
let(:options) { { hash_digest: Digest::SHA256 } }
|
|
87
|
+
|
|
88
|
+
it "returns a fingerprint" do
|
|
89
|
+
expect(subject.fingerprint).to be_a String
|
|
90
|
+
expect(subject.fingerprint).
|
|
91
|
+
to eq "243d7ce1099719df25f600f1c369c629fb979f88d5a01dbe7d0d48c8e6715bb1"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
69
94
|
end
|
|
70
95
|
|
|
71
96
|
context "#original_filename=" do
|
|
72
97
|
it "should not fail with a nil original filename" do
|
|
73
|
-
|
|
74
|
-
expect{ adapter.original_filename = nil }.not_to raise_error
|
|
98
|
+
expect { subject.original_filename = nil }.not_to raise_error
|
|
75
99
|
end
|
|
76
100
|
end
|
|
77
101
|
end
|
|
@@ -13,7 +13,8 @@ describe Paperclip::AttachmentAdapter do
|
|
|
13
13
|
|
|
14
14
|
@attachment.assign(@file)
|
|
15
15
|
@attachment.save
|
|
16
|
-
@subject = Paperclip.io_adapters.for(@attachment
|
|
16
|
+
@subject = Paperclip.io_adapters.for(@attachment,
|
|
17
|
+
hash_digest: Digest::MD5)
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
after do
|
|
@@ -65,7 +66,8 @@ describe Paperclip::AttachmentAdapter do
|
|
|
65
66
|
|
|
66
67
|
@attachment.assign(@file)
|
|
67
68
|
@attachment.save
|
|
68
|
-
@subject = Paperclip.io_adapters.for(@attachment
|
|
69
|
+
@subject = Paperclip.io_adapters.for(@attachment,
|
|
70
|
+
hash_digest: Digest::MD5)
|
|
69
71
|
end
|
|
70
72
|
|
|
71
73
|
after do
|
|
@@ -92,7 +94,8 @@ describe Paperclip::AttachmentAdapter do
|
|
|
92
94
|
FileUtils.cp @attachment.queued_for_write[:thumb].path, @thumb.path
|
|
93
95
|
|
|
94
96
|
@attachment.save
|
|
95
|
-
@subject = Paperclip.io_adapters.for(@attachment.styles[:thumb]
|
|
97
|
+
@subject = Paperclip.io_adapters.for(@attachment.styles[:thumb],
|
|
98
|
+
hash_digest: Digest::MD5)
|
|
96
99
|
end
|
|
97
100
|
|
|
98
101
|
after do
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Paperclip::DataUriAdapter do
|
|
4
|
+
before do
|
|
5
|
+
Paperclip::DataUriAdapter.register
|
|
6
|
+
end
|
|
7
|
+
|
|
4
8
|
after do
|
|
9
|
+
Paperclip.io_adapters.unregister(described_class)
|
|
10
|
+
|
|
5
11
|
if @subject
|
|
6
12
|
@subject.close
|
|
7
13
|
end
|
|
@@ -20,7 +26,7 @@ describe Paperclip::DataUriAdapter do
|
|
|
20
26
|
context "a new instance" do
|
|
21
27
|
before do
|
|
22
28
|
@contents = "data:image/png;base64,#{original_base64_content}"
|
|
23
|
-
@subject = Paperclip.io_adapters.for(@contents)
|
|
29
|
+
@subject = Paperclip.io_adapters.for(@contents, hash_digest: Digest::MD5)
|
|
24
30
|
end
|
|
25
31
|
|
|
26
32
|
it "returns a nondescript file name" do
|
|
@@ -15,7 +15,7 @@ describe Paperclip::FileAdapter do
|
|
|
15
15
|
|
|
16
16
|
context 'doing normal things' do
|
|
17
17
|
before do
|
|
18
|
-
@subject = Paperclip.io_adapters.for(@file)
|
|
18
|
+
@subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
it 'uses the original filename to generate the tempfile' do
|
|
@@ -61,7 +61,7 @@ describe Paperclip::FileAdapter do
|
|
|
61
61
|
context "file with multiple possible content type" do
|
|
62
62
|
before do
|
|
63
63
|
MIME::Types.stubs(:type_for).returns([MIME::Type.new('image/x-png'), MIME::Type.new('image/png')])
|
|
64
|
-
@subject = Paperclip.io_adapters.for(@file)
|
|
64
|
+
@subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
it "prefers officially registered mime type" do
|
|
@@ -73,10 +73,13 @@ describe Paperclip::FileAdapter do
|
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
context "file with content type derived from file
|
|
76
|
+
context "file with content type derived from file contents on *nix" do
|
|
77
77
|
before do
|
|
78
78
|
MIME::Types.stubs(:type_for).returns([])
|
|
79
79
|
Paperclip.stubs(:run).returns("application/vnd.ms-office\n")
|
|
80
|
+
Paperclip::ContentTypeDetector.any_instance
|
|
81
|
+
.stubs(:type_from_mime_magic).returns("application/vnd.ms-office")
|
|
82
|
+
|
|
80
83
|
@subject = Paperclip.io_adapters.for(@file)
|
|
81
84
|
end
|
|
82
85
|
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Paperclip::HttpUrlProxyAdapter do
|
|
4
|
+
before do
|
|
5
|
+
@open_return = StringIO.new("xxx")
|
|
6
|
+
@open_return.stubs(:content_type).returns("image/png")
|
|
7
|
+
@open_return.stubs(:meta).returns({})
|
|
8
|
+
Paperclip::HttpUrlProxyAdapter.any_instance.
|
|
9
|
+
stubs(:download_content).returns(@open_return)
|
|
10
|
+
Paperclip::HttpUrlProxyAdapter.register
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after do
|
|
14
|
+
Paperclip.io_adapters.unregister(described_class)
|
|
15
|
+
end
|
|
16
|
+
|
|
4
17
|
context "a new instance" do
|
|
5
18
|
before do
|
|
6
|
-
@open_return = StringIO.new("xxx")
|
|
7
|
-
@open_return.stubs(:content_type).returns("image/png")
|
|
8
|
-
Paperclip::HttpUrlProxyAdapter.any_instance.stubs(:download_content).returns(@open_return)
|
|
9
19
|
@url = "http://thoughtbot.com/images/thoughtbot-logo.png"
|
|
10
|
-
@subject = Paperclip.io_adapters.for(@url)
|
|
20
|
+
@subject = Paperclip.io_adapters.for(@url, hash_digest: Digest::MD5)
|
|
11
21
|
end
|
|
12
22
|
|
|
13
23
|
after do
|
|
@@ -60,7 +70,6 @@ describe Paperclip::HttpUrlProxyAdapter do
|
|
|
60
70
|
|
|
61
71
|
context "a url with query params" do
|
|
62
72
|
before do
|
|
63
|
-
Paperclip::HttpUrlProxyAdapter.any_instance.stubs(:download_content).returns(StringIO.new("x"))
|
|
64
73
|
@url = "https://github.com/thoughtbot/paperclip?file=test"
|
|
65
74
|
@subject = Paperclip.io_adapters.for(@url)
|
|
66
75
|
end
|
|
@@ -76,7 +85,6 @@ describe Paperclip::HttpUrlProxyAdapter do
|
|
|
76
85
|
|
|
77
86
|
context "a url with restricted characters in the filename" do
|
|
78
87
|
before do
|
|
79
|
-
Paperclip::HttpUrlProxyAdapter.any_instance.stubs(:download_content).returns(StringIO.new("x"))
|
|
80
88
|
@url = "https://github.com/thoughtbot/paper:clip.jpg"
|
|
81
89
|
@subject = Paperclip.io_adapters.for(@url)
|
|
82
90
|
end
|
|
@@ -98,4 +106,16 @@ describe Paperclip::HttpUrlProxyAdapter do
|
|
|
98
106
|
end
|
|
99
107
|
end
|
|
100
108
|
|
|
109
|
+
context "a url with special characters in the filename" do
|
|
110
|
+
it "returns a encoded filename" do
|
|
111
|
+
Paperclip::HttpUrlProxyAdapter.any_instance.stubs(:download_content).
|
|
112
|
+
returns(@open_return)
|
|
113
|
+
url = "https://github.com/thoughtbot/paperclip-öäü字´½♥زÈ.png"
|
|
114
|
+
subject = Paperclip.io_adapters.for(url)
|
|
115
|
+
filename = "paperclip-%C3%B6%C3%A4%C3%BC%E5%AD%97%C2%B4%C2%BD%E2%99%A5"\
|
|
116
|
+
"%C3%98%C2%B2%C3%88.png"
|
|
117
|
+
|
|
118
|
+
assert_equal filename, subject.original_filename
|
|
119
|
+
end
|
|
120
|
+
end
|
|
101
121
|
end
|
|
@@ -4,7 +4,7 @@ describe Paperclip::AttachmentRegistry do
|
|
|
4
4
|
context "for" do
|
|
5
5
|
before do
|
|
6
6
|
class AdapterTest
|
|
7
|
-
def initialize(
|
|
7
|
+
def initialize(_target, _ = {}); end
|
|
8
8
|
end
|
|
9
9
|
@subject = Paperclip::AdapterRegistry.new
|
|
10
10
|
@subject.register(AdapterTest){|t| Symbol === t }
|
|
@@ -18,7 +18,7 @@ describe Paperclip::AttachmentRegistry do
|
|
|
18
18
|
context "registered?" do
|
|
19
19
|
before do
|
|
20
20
|
class AdapterTest
|
|
21
|
-
def initialize(
|
|
21
|
+
def initialize(_target, _ = {}); end
|
|
22
22
|
end
|
|
23
23
|
@subject = Paperclip::AdapterRegistry.new
|
|
24
24
|
@subject.register(AdapterTest){|t| Symbol === t }
|
|
@@ -5,7 +5,7 @@ describe Paperclip::StringioAdapter do
|
|
|
5
5
|
before do
|
|
6
6
|
@contents = "abc123"
|
|
7
7
|
@stringio = StringIO.new(@contents)
|
|
8
|
-
@subject = Paperclip.io_adapters.for(@stringio)
|
|
8
|
+
@subject = Paperclip.io_adapters.for(@stringio, hash_digest: Digest::MD5)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
it "returns a file name" do
|
|
@@ -20,6 +20,10 @@ describe Paperclip::StringioAdapter do
|
|
|
20
20
|
assert_equal 6, @subject.size
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
it "returns the length of the data" do
|
|
24
|
+
assert_equal 6, @subject.length
|
|
25
|
+
end
|
|
26
|
+
|
|
23
27
|
it "generates an MD5 hash of the contents" do
|
|
24
28
|
assert_equal Digest::MD5.hexdigest(@contents), @subject.fingerprint
|
|
25
29
|
end
|
|
@@ -17,7 +17,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
|
17
17
|
tempfile: tempfile,
|
|
18
18
|
path: tempfile.path
|
|
19
19
|
)
|
|
20
|
-
@subject = Paperclip.io_adapters.for(@file)
|
|
20
|
+
@subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it "gets the right filename" do
|
|
@@ -29,7 +29,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
it "gets the content type" do
|
|
32
|
-
assert_equal "image/
|
|
32
|
+
assert_equal "image/png", @subject.content_type
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "gets the file's size" do
|
|
@@ -63,7 +63,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
|
63
63
|
head: "",
|
|
64
64
|
path: fixture_file("5k.png")
|
|
65
65
|
)
|
|
66
|
-
@subject = Paperclip.io_adapters.for(@file)
|
|
66
|
+
@subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
it "does not generate paths that include restricted characters" do
|
|
@@ -86,7 +86,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
|
86
86
|
head: "",
|
|
87
87
|
path: fixture_file("5k.png")
|
|
88
88
|
)
|
|
89
|
-
@subject = Paperclip.io_adapters.for(@file)
|
|
89
|
+
@subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
it "gets the right filename" do
|
|
@@ -98,7 +98,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
it "gets the content type" do
|
|
101
|
-
assert_equal "image/
|
|
101
|
+
assert_equal "image/png", @subject.content_type
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
it "gets the file's size" do
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Paperclip::UriAdapter do
|
|
4
|
+
let(:content_type) { "image/png" }
|
|
5
|
+
let(:meta) { {} }
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
@open_return = StringIO.new("xxx")
|
|
9
|
+
@open_return.stubs(:content_type).returns(content_type)
|
|
10
|
+
@open_return.stubs(:meta).returns(meta)
|
|
11
|
+
Paperclip::UriAdapter.register
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
after do
|
|
15
|
+
Paperclip.io_adapters.unregister(described_class)
|
|
16
|
+
end
|
|
17
|
+
|
|
4
18
|
context "a new instance" do
|
|
5
19
|
before do
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
20
|
+
Paperclip::UriAdapter.any_instance.
|
|
21
|
+
stubs(:download_content).returns(@open_return)
|
|
22
|
+
|
|
9
23
|
@uri = URI.parse("http://thoughtbot.com/images/thoughtbot-logo.png")
|
|
10
|
-
@subject = Paperclip.io_adapters.for(@uri)
|
|
24
|
+
@subject = Paperclip.io_adapters.for(@uri, hash_digest: Digest::MD5)
|
|
11
25
|
end
|
|
12
26
|
|
|
13
27
|
it "returns a file name" do
|
|
@@ -56,8 +70,12 @@ describe Paperclip::UriAdapter do
|
|
|
56
70
|
end
|
|
57
71
|
|
|
58
72
|
context "a directory index url" do
|
|
73
|
+
let(:content_type) { "text/html" }
|
|
74
|
+
|
|
59
75
|
before do
|
|
60
|
-
Paperclip::UriAdapter.any_instance.
|
|
76
|
+
Paperclip::UriAdapter.any_instance.
|
|
77
|
+
stubs(:download_content).returns(@open_return)
|
|
78
|
+
|
|
61
79
|
@uri = URI.parse("http://thoughtbot.com")
|
|
62
80
|
@subject = Paperclip.io_adapters.for(@uri)
|
|
63
81
|
end
|
|
@@ -73,7 +91,9 @@ describe Paperclip::UriAdapter do
|
|
|
73
91
|
|
|
74
92
|
context "a url with query params" do
|
|
75
93
|
before do
|
|
76
|
-
Paperclip::UriAdapter.any_instance.
|
|
94
|
+
Paperclip::UriAdapter.any_instance.
|
|
95
|
+
stubs(:download_content).returns(@open_return)
|
|
96
|
+
|
|
77
97
|
@uri = URI.parse("https://github.com/thoughtbot/paperclip?file=test")
|
|
78
98
|
@subject = Paperclip.io_adapters.for(@uri)
|
|
79
99
|
end
|
|
@@ -83,9 +103,32 @@ describe Paperclip::UriAdapter do
|
|
|
83
103
|
end
|
|
84
104
|
end
|
|
85
105
|
|
|
106
|
+
context "a url with content disposition headers" do
|
|
107
|
+
let(:file_name) { "test_document.pdf" }
|
|
108
|
+
let(:meta) do
|
|
109
|
+
{
|
|
110
|
+
"content-disposition" => "attachment; filename=\"#{file_name}\";",
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
before do
|
|
115
|
+
Paperclip::UriAdapter.any_instance.
|
|
116
|
+
stubs(:download_content).returns(@open_return)
|
|
117
|
+
|
|
118
|
+
@uri = URI.parse("https://github.com/thoughtbot/paperclip?file=test")
|
|
119
|
+
@subject = Paperclip.io_adapters.for(@uri)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "returns a file name" do
|
|
123
|
+
assert_equal file_name, @subject.original_filename
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
86
127
|
context "a url with restricted characters in the filename" do
|
|
87
128
|
before do
|
|
88
|
-
Paperclip::UriAdapter.any_instance.
|
|
129
|
+
Paperclip::UriAdapter.any_instance.
|
|
130
|
+
stubs(:download_content).returns(@open_return)
|
|
131
|
+
|
|
89
132
|
@uri = URI.parse("https://github.com/thoughtbot/paper:clip.jpg")
|
|
90
133
|
@subject = Paperclip.io_adapters.for(@uri)
|
|
91
134
|
end
|
|
@@ -99,4 +142,31 @@ describe Paperclip::UriAdapter do
|
|
|
99
142
|
end
|
|
100
143
|
end
|
|
101
144
|
|
|
145
|
+
describe "#download_content" do
|
|
146
|
+
before do
|
|
147
|
+
Paperclip::UriAdapter.any_instance.stubs(:open).returns(@open_return)
|
|
148
|
+
@uri = URI.parse("https://github.com/thoughtbot/paper:clip.jpg")
|
|
149
|
+
@subject = Paperclip.io_adapters.for(@uri)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
after do
|
|
153
|
+
@subject.send(:download_content)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
context "with default read_timeout" do
|
|
157
|
+
it "calls open without options" do
|
|
158
|
+
@subject.expects(:open).with(@uri, {}).at_least_once
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
context "with custom read_timeout" do
|
|
163
|
+
before do
|
|
164
|
+
Paperclip.options[:read_timeout] = 120
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "calls open with read_timeout option" do
|
|
168
|
+
@subject.expects(:open).with(@uri, read_timeout: 120).at_least_once
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
102
172
|
end
|