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,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Paperclip::FileAdapter do
|
4
4
|
context "a new instance" do
|
@@ -13,12 +13,12 @@ describe Paperclip::FileAdapter do
|
|
13
13
|
@subject.close if @subject
|
14
14
|
end
|
15
15
|
|
16
|
-
context
|
16
|
+
context "doing normal things" do
|
17
17
|
before do
|
18
18
|
@subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
21
|
+
it "uses the original filename to generate the tempfile" do
|
22
22
|
assert @subject.path.ends_with?(".png")
|
23
23
|
end
|
24
24
|
|
@@ -43,7 +43,7 @@ describe Paperclip::FileAdapter do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it "returns false for a call to nil?" do
|
46
|
-
assert
|
46
|
+
assert !@subject.nil?
|
47
47
|
end
|
48
48
|
|
49
49
|
it "generates a MD5 hash of the contents" do
|
@@ -53,14 +53,14 @@ describe Paperclip::FileAdapter do
|
|
53
53
|
|
54
54
|
it "reads the contents of the file" do
|
55
55
|
expected = @file.read
|
56
|
-
assert expected.
|
56
|
+
assert !expected.empty?
|
57
57
|
assert_equal expected, @subject.read
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
context "file with multiple possible content type" do
|
62
62
|
before do
|
63
|
-
MIME::Types.
|
63
|
+
allow(MIME::Types).to receive(:type_for).and_return([MIME::Type.new("image/x-png"), MIME::Type.new("image/png")])
|
64
64
|
@subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
|
65
65
|
end
|
66
66
|
|
@@ -75,10 +75,10 @@ describe Paperclip::FileAdapter do
|
|
75
75
|
|
76
76
|
context "file with content type derived from file contents on *nix" do
|
77
77
|
before do
|
78
|
-
MIME::Types.
|
79
|
-
Paperclip.
|
80
|
-
Paperclip::ContentTypeDetector.
|
81
|
-
|
78
|
+
allow(MIME::Types).to receive(:type_for).and_return([])
|
79
|
+
allow(Paperclip).to receive(:run).and_return("application/vnd.ms-office\n")
|
80
|
+
allow_any_instance_of(Paperclip::ContentTypeDetector).
|
81
|
+
to receive(:type_from_marcel).and_return("application/vnd.ms-office")
|
82
82
|
|
83
83
|
@subject = Paperclip.io_adapters.for(@file)
|
84
84
|
end
|
@@ -94,7 +94,7 @@ describe Paperclip::FileAdapter do
|
|
94
94
|
@file = File.open(fixture_file("animated.gif")) do |file|
|
95
95
|
StringIO.new(file.read)
|
96
96
|
end
|
97
|
-
@file.
|
97
|
+
allow(@file).to receive(:original_filename).and_return("image:restricted.gif")
|
98
98
|
@subject = Paperclip.io_adapters.for(@file)
|
99
99
|
end
|
100
100
|
|
@@ -104,7 +104,7 @@ describe Paperclip::FileAdapter do
|
|
104
104
|
end
|
105
105
|
|
106
106
|
it "does not generate filenames that include restricted characters" do
|
107
|
-
assert_equal
|
107
|
+
assert_equal "image_restricted.gif", @subject.original_filename
|
108
108
|
end
|
109
109
|
|
110
110
|
it "does not generate paths that include restricted characters" do
|
@@ -1,12 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Paperclip::HttpUrlProxyAdapter do
|
4
4
|
before do
|
5
5
|
@open_return = StringIO.new("xxx")
|
6
|
-
@open_return.
|
7
|
-
|
8
|
-
|
9
|
-
stubs(:download_content).returns(@open_return)
|
6
|
+
allow(@open_return).to receive(:meta).and_return("content-type" => "image/png")
|
7
|
+
allow_any_instance_of(Paperclip::HttpUrlProxyAdapter).to receive(:download_content).
|
8
|
+
and_return(@open_return)
|
10
9
|
Paperclip::HttpUrlProxyAdapter.register
|
11
10
|
end
|
12
11
|
|
@@ -17,69 +16,75 @@ describe Paperclip::HttpUrlProxyAdapter do
|
|
17
16
|
context "a new instance" do
|
18
17
|
before do
|
19
18
|
@url = "http://thoughtbot.com/images/thoughtbot-logo.png"
|
20
|
-
@subject = Paperclip.io_adapters.for(@url, hash_digest: Digest::MD5)
|
21
19
|
end
|
22
20
|
|
21
|
+
subject { Paperclip.io_adapters.for(@url, hash_digest: Digest::MD5) }
|
22
|
+
|
23
23
|
after do
|
24
|
-
|
24
|
+
subject.close
|
25
25
|
end
|
26
26
|
|
27
27
|
it "returns a file name" do
|
28
|
-
|
28
|
+
expect(subject.original_filename).to(eq("thoughtbot-logo.png"))
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
32
|
-
|
31
|
+
it "closes open handle after reading" do
|
32
|
+
expect { subject }.to(change { @open_return.closed? }.from(false).to(true))
|
33
33
|
end
|
34
34
|
|
35
35
|
it "returns a content type" do
|
36
|
-
|
36
|
+
expect(subject.content_type).to(eq("image/png"))
|
37
37
|
end
|
38
38
|
|
39
39
|
it "returns the size of the data" do
|
40
|
-
|
40
|
+
expect(subject.size).to(eq(@open_return.size))
|
41
41
|
end
|
42
42
|
|
43
43
|
it "generates an MD5 hash of the contents" do
|
44
|
-
|
44
|
+
expect(subject.fingerprint).to(eq(Digest::MD5.hexdigest("xxx")))
|
45
45
|
end
|
46
46
|
|
47
47
|
it "generates correct fingerprint after read" do
|
48
|
-
fingerprint = Digest::MD5.hexdigest(
|
49
|
-
|
48
|
+
fingerprint = Digest::MD5.hexdigest(subject.read)
|
49
|
+
expect(subject.fingerprint).to(eq(fingerprint))
|
50
50
|
end
|
51
51
|
|
52
52
|
it "generates same fingerprint" do
|
53
|
-
|
53
|
+
expect(subject.fingerprint).to(eq(subject.fingerprint))
|
54
54
|
end
|
55
55
|
|
56
56
|
it "returns the data contained in the StringIO" do
|
57
|
-
|
57
|
+
expect(subject.read).to(eq("xxx"))
|
58
|
+
end
|
59
|
+
|
60
|
+
it "accepts a content_type" do
|
61
|
+
subject.content_type = "image/png"
|
62
|
+
expect(subject.content_type).to(eq("image/png"))
|
58
63
|
end
|
59
64
|
|
60
|
-
it
|
61
|
-
|
62
|
-
|
65
|
+
it "accepts an original_filename" do
|
66
|
+
subject.original_filename = "image.png"
|
67
|
+
expect(subject.original_filename).to(eq("image.png"))
|
63
68
|
end
|
64
69
|
|
65
|
-
it '
|
66
|
-
|
67
|
-
assert_equal 'image.png', @subject.original_filename
|
70
|
+
it "doesn't emit deprecation warnings" do
|
71
|
+
expect { subject }.to_not(output(/URI\.(un)?escape is obsolete/).to_stderr)
|
68
72
|
end
|
69
73
|
end
|
70
74
|
|
71
75
|
context "a url with query params" do
|
72
|
-
|
73
|
-
@url = "https://github.com/thoughtbot/paperclip?file=test"
|
74
|
-
@subject = Paperclip.io_adapters.for(@url)
|
75
|
-
end
|
76
|
+
subject { Paperclip.io_adapters.for(url) }
|
76
77
|
|
77
|
-
after
|
78
|
-
|
79
|
-
|
78
|
+
after { subject.close }
|
79
|
+
|
80
|
+
let(:url) { "https://github.com/thoughtbot/paperclip?file=test" }
|
80
81
|
|
81
82
|
it "returns a file name" do
|
82
|
-
assert_equal "paperclip",
|
83
|
+
assert_equal "paperclip", subject.original_filename
|
84
|
+
end
|
85
|
+
|
86
|
+
it "preserves params" do
|
87
|
+
assert_equal url, subject.instance_variable_get(:@target).to_s
|
83
88
|
end
|
84
89
|
end
|
85
90
|
|
@@ -107,15 +112,31 @@ describe Paperclip::HttpUrlProxyAdapter do
|
|
107
112
|
end
|
108
113
|
|
109
114
|
context "a url with special characters in the filename" do
|
110
|
-
|
111
|
-
Paperclip::HttpUrlProxyAdapter.
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
115
|
+
before do
|
116
|
+
allow_any_instance_of(Paperclip::HttpUrlProxyAdapter).to receive(:download_content).and_return(@open_return)
|
117
|
+
end
|
118
|
+
|
119
|
+
let(:filename) do
|
120
|
+
"paperclip-%C3%B6%C3%A4%C3%BC%E5%AD%97%C2%B4%C2%BD%E2%99%A5"\
|
116
121
|
"%C3%98%C2%B2%C3%88.png"
|
122
|
+
end
|
123
|
+
let(:url) { "https://github.com/thoughtbot/paperclip-öäü字´½♥زÈ.png" }
|
124
|
+
|
125
|
+
subject { Paperclip.io_adapters.for(url) }
|
117
126
|
|
127
|
+
it "returns a encoded filename" do
|
118
128
|
assert_equal filename, subject.original_filename
|
119
129
|
end
|
130
|
+
|
131
|
+
context "when already URI encoded" do
|
132
|
+
let(:url) do
|
133
|
+
"https://github.com/thoughtbot/paperclip-%C3%B6%C3%A4%C3%BC%E5%AD%97"\
|
134
|
+
"%C2%B4%C2%BD%E2%99%A5%C3%98%C2%B2%C3%88.png"
|
135
|
+
end
|
136
|
+
|
137
|
+
it "returns a encoded filename" do
|
138
|
+
assert_equal filename, subject.original_filename
|
139
|
+
end
|
140
|
+
end
|
120
141
|
end
|
121
142
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Paperclip::AttachmentRegistry do
|
4
4
|
context "for" do
|
@@ -7,7 +7,7 @@ describe Paperclip::AttachmentRegistry do
|
|
7
7
|
def initialize(_target, _ = {}); end
|
8
8
|
end
|
9
9
|
@subject = Paperclip::AdapterRegistry.new
|
10
|
-
@subject.register(AdapterTest){|t| Symbol === t }
|
10
|
+
@subject.register(AdapterTest) { |t| Symbol === t }
|
11
11
|
end
|
12
12
|
|
13
13
|
it "returns the class registered for the adapted type" do
|
@@ -21,7 +21,7 @@ describe Paperclip::AttachmentRegistry do
|
|
21
21
|
def initialize(_target, _ = {}); end
|
22
22
|
end
|
23
23
|
@subject = Paperclip::AdapterRegistry.new
|
24
|
-
@subject.register(AdapterTest){|t| Symbol === t }
|
24
|
+
@subject.register(AdapterTest) { |t| Symbol === t }
|
25
25
|
end
|
26
26
|
|
27
27
|
it "returns true when the class of this adapter has been registered" do
|
@@ -29,7 +29,7 @@ describe Paperclip::AttachmentRegistry do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "returns false when the adapter has not been registered" do
|
32
|
-
assert
|
32
|
+
assert !@subject.registered?(Object)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Paperclip::StringioAdapter do
|
4
4
|
context "a new instance" do
|
@@ -41,23 +41,23 @@ describe Paperclip::StringioAdapter do
|
|
41
41
|
assert_equal "abc123", @subject.read
|
42
42
|
end
|
43
43
|
|
44
|
-
it
|
45
|
-
@subject.content_type =
|
46
|
-
assert_equal
|
44
|
+
it "accepts a content_type" do
|
45
|
+
@subject.content_type = "image/png"
|
46
|
+
assert_equal "image/png", @subject.content_type
|
47
47
|
end
|
48
48
|
|
49
|
-
it
|
50
|
-
@subject.original_filename =
|
51
|
-
assert_equal
|
49
|
+
it "accepts an original_filename" do
|
50
|
+
@subject.original_filename = "image.png"
|
51
|
+
assert_equal "image.png", @subject.original_filename
|
52
52
|
end
|
53
53
|
|
54
54
|
it "does not generate filenames that include restricted characters" do
|
55
|
-
@subject.original_filename =
|
56
|
-
assert_equal
|
55
|
+
@subject.original_filename = "image:restricted.png"
|
56
|
+
assert_equal "image_restricted.png", @subject.original_filename
|
57
57
|
end
|
58
58
|
|
59
59
|
it "does not generate paths that include restricted characters" do
|
60
|
-
@subject.original_filename =
|
60
|
+
@subject.original_filename = "image:restricted.png"
|
61
61
|
expect(@subject.path).to_not match(/:/)
|
62
62
|
end
|
63
63
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Paperclip::UploadedFileAdapter do
|
4
4
|
context "a new instance" do
|
@@ -37,7 +37,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "returns false for a call to nil?" do
|
40
|
-
assert
|
40
|
+
assert !@subject.nil?
|
41
41
|
end
|
42
42
|
|
43
43
|
it "generates a MD5 hash of the contents" do
|
@@ -47,7 +47,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
47
47
|
|
48
48
|
it "reads the contents of the file" do
|
49
49
|
expected = @file.tempfile.read
|
50
|
-
assert expected.
|
50
|
+
assert !expected.empty?
|
51
51
|
assert_equal expected, @subject.read
|
52
52
|
end
|
53
53
|
end
|
@@ -71,7 +71,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
it "does not generate filenames that include restricted characters" do
|
74
|
-
assert_equal
|
74
|
+
assert_equal "image_restricted.gif", @subject.original_filename
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -106,7 +106,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
106
106
|
end
|
107
107
|
|
108
108
|
it "returns false for a call to nil?" do
|
109
|
-
assert
|
109
|
+
assert !@subject.nil?
|
110
110
|
end
|
111
111
|
|
112
112
|
it "generates a MD5 hash of the contents" do
|
@@ -118,7 +118,7 @@ describe Paperclip::UploadedFileAdapter do
|
|
118
118
|
expected_file = File.new(@file.path)
|
119
119
|
expected_file.binmode
|
120
120
|
expected = expected_file.read
|
121
|
-
assert expected.
|
121
|
+
assert !expected.empty?
|
122
122
|
assert_equal expected, @subject.read
|
123
123
|
end
|
124
124
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Paperclip::UriAdapter do
|
4
4
|
let(:content_type) { "image/png" }
|
@@ -6,8 +6,8 @@ describe Paperclip::UriAdapter do
|
|
6
6
|
|
7
7
|
before do
|
8
8
|
@open_return = StringIO.new("xxx")
|
9
|
-
@open_return.
|
10
|
-
@open_return.
|
9
|
+
allow(@open_return).to receive(:content_type).and_return(content_type)
|
10
|
+
allow(@open_return).to receive(:meta).and_return(meta)
|
11
11
|
Paperclip::UriAdapter.register
|
12
12
|
end
|
13
13
|
|
@@ -16,9 +16,11 @@ describe Paperclip::UriAdapter do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
context "a new instance" do
|
19
|
+
let(:meta) { { "content-type" => "image/png" } }
|
20
|
+
|
19
21
|
before do
|
20
|
-
Paperclip::UriAdapter.
|
21
|
-
|
22
|
+
allow_any_instance_of(Paperclip::UriAdapter).
|
23
|
+
to receive(:download_content).and_return(@open_return)
|
22
24
|
|
23
25
|
@uri = URI.parse("http://thoughtbot.com/images/thoughtbot-logo.png")
|
24
26
|
@subject = Paperclip.io_adapters.for(@uri, hash_digest: Digest::MD5)
|
@@ -28,7 +30,7 @@ describe Paperclip::UriAdapter do
|
|
28
30
|
assert_equal "thoughtbot-logo.png", @subject.original_filename
|
29
31
|
end
|
30
32
|
|
31
|
-
it
|
33
|
+
it "closes open handle after reading" do
|
32
34
|
assert_equal true, @open_return.closed?
|
33
35
|
end
|
34
36
|
|
@@ -57,24 +59,24 @@ describe Paperclip::UriAdapter do
|
|
57
59
|
assert_equal "xxx", @subject.read
|
58
60
|
end
|
59
61
|
|
60
|
-
it
|
61
|
-
@subject.content_type =
|
62
|
-
assert_equal
|
62
|
+
it "accepts a content_type" do
|
63
|
+
@subject.content_type = "image/png"
|
64
|
+
assert_equal "image/png", @subject.content_type
|
63
65
|
end
|
64
66
|
|
65
|
-
it
|
66
|
-
@subject.original_filename =
|
67
|
-
assert_equal
|
67
|
+
it "accepts an original_filename" do
|
68
|
+
@subject.original_filename = "image.png"
|
69
|
+
assert_equal "image.png", @subject.original_filename
|
68
70
|
end
|
69
|
-
|
70
71
|
end
|
71
72
|
|
72
73
|
context "a directory index url" do
|
73
74
|
let(:content_type) { "text/html" }
|
75
|
+
let(:meta) { { "content-type" => "text/html" } }
|
74
76
|
|
75
77
|
before do
|
76
|
-
Paperclip::UriAdapter.
|
77
|
-
|
78
|
+
allow_any_instance_of(Paperclip::UriAdapter).
|
79
|
+
to receive(:download_content).and_return(@open_return)
|
78
80
|
|
79
81
|
@uri = URI.parse("http://thoughtbot.com")
|
80
82
|
@subject = Paperclip.io_adapters.for(@uri)
|
@@ -91,8 +93,8 @@ describe Paperclip::UriAdapter do
|
|
91
93
|
|
92
94
|
context "a url with query params" do
|
93
95
|
before do
|
94
|
-
Paperclip::UriAdapter.
|
95
|
-
|
96
|
+
allow_any_instance_of(Paperclip::UriAdapter).
|
97
|
+
to receive(:download_content).and_return(@open_return)
|
96
98
|
|
97
99
|
@uri = URI.parse("https://github.com/thoughtbot/paperclip?file=test")
|
98
100
|
@subject = Paperclip.io_adapters.for(@uri)
|
@@ -105,29 +107,76 @@ describe Paperclip::UriAdapter do
|
|
105
107
|
|
106
108
|
context "a url with content disposition headers" do
|
107
109
|
let(:file_name) { "test_document.pdf" }
|
108
|
-
let(:
|
109
|
-
{
|
110
|
-
"content-disposition" => "attachment; filename=\"#{file_name}\";",
|
111
|
-
}
|
112
|
-
end
|
110
|
+
let(:filename_from_path) { "paperclip" }
|
113
111
|
|
114
112
|
before do
|
115
|
-
Paperclip::UriAdapter.
|
116
|
-
|
113
|
+
allow_any_instance_of(Paperclip::UriAdapter).
|
114
|
+
to receive(:download_content).and_return(@open_return)
|
115
|
+
|
116
|
+
@uri = URI.parse(
|
117
|
+
"https://github.com/thoughtbot/#{filename_from_path}?file=test"
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "returns file name from path" do
|
122
|
+
meta["content-disposition"] = "inline;"
|
123
|
+
|
124
|
+
@subject = Paperclip.io_adapters.for(@uri)
|
125
|
+
|
126
|
+
assert_equal filename_from_path, @subject.original_filename
|
127
|
+
end
|
128
|
+
|
129
|
+
it "returns a file name enclosed in double quotes" do
|
130
|
+
file_name = "john's test document.pdf"
|
131
|
+
meta["content-disposition"] = "attachment; filename=\"#{file_name}\";"
|
117
132
|
|
118
|
-
@uri = URI.parse("https://github.com/thoughtbot/paperclip?file=test")
|
119
133
|
@subject = Paperclip.io_adapters.for(@uri)
|
134
|
+
|
135
|
+
assert_equal file_name, @subject.original_filename
|
120
136
|
end
|
121
137
|
|
122
|
-
it "returns a file name" do
|
138
|
+
it "returns a file name not enclosed in double quotes" do
|
139
|
+
meta["content-disposition"] = "ATTACHMENT; FILENAME=#{file_name};"
|
140
|
+
|
141
|
+
@subject = Paperclip.io_adapters.for(@uri)
|
142
|
+
|
143
|
+
assert_equal file_name, @subject.original_filename
|
144
|
+
end
|
145
|
+
|
146
|
+
it "does not crash when an empty filename is given" do
|
147
|
+
meta["content-disposition"] = "ATTACHMENT; FILENAME=\"\";"
|
148
|
+
|
149
|
+
@subject = Paperclip.io_adapters.for(@uri)
|
150
|
+
|
151
|
+
assert_equal "", @subject.original_filename
|
152
|
+
end
|
153
|
+
|
154
|
+
it "returns a file name ignoring RFC 5987 encoding" do
|
155
|
+
meta["content-disposition"] =
|
156
|
+
"attachment; filename=#{file_name}; filename* = utf-8''%e2%82%ac%20rates"
|
157
|
+
|
158
|
+
@subject = Paperclip.io_adapters.for(@uri)
|
159
|
+
|
123
160
|
assert_equal file_name, @subject.original_filename
|
124
161
|
end
|
162
|
+
|
163
|
+
context "when file name has consecutive periods" do
|
164
|
+
let(:file_name) { "test_document..pdf" }
|
165
|
+
|
166
|
+
it "returns a file name" do
|
167
|
+
@uri = URI.parse(
|
168
|
+
"https://github.com/thoughtbot/#{file_name}?file=test"
|
169
|
+
)
|
170
|
+
@subject = Paperclip.io_adapters.for(@uri)
|
171
|
+
assert_equal file_name, @subject.original_filename
|
172
|
+
end
|
173
|
+
end
|
125
174
|
end
|
126
175
|
|
127
176
|
context "a url with restricted characters in the filename" do
|
128
177
|
before do
|
129
|
-
Paperclip::UriAdapter.
|
130
|
-
|
178
|
+
allow_any_instance_of(Paperclip::UriAdapter).
|
179
|
+
to receive(:download_content).and_return(@open_return)
|
131
180
|
|
132
181
|
@uri = URI.parse("https://github.com/thoughtbot/paper:clip.jpg")
|
133
182
|
@subject = Paperclip.io_adapters.for(@uri)
|
@@ -144,9 +193,18 @@ describe Paperclip::UriAdapter do
|
|
144
193
|
|
145
194
|
describe "#download_content" do
|
146
195
|
before do
|
147
|
-
|
196
|
+
allowed_mock =
|
197
|
+
if RUBY_VERSION < '2.5'
|
198
|
+
allow_any_instance_of(Paperclip::UriAdapter)
|
199
|
+
else
|
200
|
+
allow(URI)
|
201
|
+
end
|
202
|
+
|
203
|
+
allowed_mock.to receive(:open).and_return(@open_return)
|
204
|
+
|
148
205
|
@uri = URI.parse("https://github.com/thoughtbot/paper:clip.jpg")
|
149
206
|
@subject = Paperclip.io_adapters.for(@uri)
|
207
|
+
@uri_opener = RUBY_VERSION < '2.5' ? @subject : URI
|
150
208
|
end
|
151
209
|
|
152
210
|
after do
|
@@ -155,7 +213,7 @@ describe Paperclip::UriAdapter do
|
|
155
213
|
|
156
214
|
context "with default read_timeout" do
|
157
215
|
it "calls open without options" do
|
158
|
-
@
|
216
|
+
expect(@uri_opener).to receive(:open).with(@uri, {}).at_least(1).times
|
159
217
|
end
|
160
218
|
end
|
161
219
|
|
@@ -165,7 +223,8 @@ describe Paperclip::UriAdapter do
|
|
165
223
|
end
|
166
224
|
|
167
225
|
it "calls open with read_timeout option" do
|
168
|
-
|
226
|
+
expect(@uri_opener)
|
227
|
+
.to receive(:open).with(@uri, read_timeout: 120).at_least(1).times
|
169
228
|
end
|
170
229
|
end
|
171
230
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "paperclip/matchers"
|
3
3
|
|
4
4
|
describe Paperclip::Shoulda::Matchers::HaveAttachedFileMatcher do
|
5
5
|
extend Paperclip::Shoulda::Matchers
|
@@ -11,7 +11,7 @@ describe Paperclip::Shoulda::Matchers::HaveAttachedFileMatcher do
|
|
11
11
|
expect(matcher).to_not accept(Dummy)
|
12
12
|
end
|
13
13
|
|
14
|
-
it
|
14
|
+
it "accepts the dummy class if it has an attachment" do
|
15
15
|
rebuild_model
|
16
16
|
matcher = self.class.have_attached_file(:avatar)
|
17
17
|
expect(matcher).to accept(Dummy)
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "paperclip/matchers"
|
3
3
|
|
4
4
|
describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
|
5
5
|
extend Paperclip::Shoulda::Matchers
|
@@ -20,7 +20,7 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
|
|
20
20
|
expect { matcher.failure_message }.to_not raise_error
|
21
21
|
end
|
22
22
|
|
23
|
-
it
|
23
|
+
it "rejects a class when the validation fails" do
|
24
24
|
Dummy.validates_attachment_content_type :avatar, content_type: %r{audio/.*}
|
25
25
|
expect(matcher).to_not accept(Dummy)
|
26
26
|
expect { matcher.failure_message }.to_not raise_error
|
@@ -74,7 +74,7 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
|
|
74
74
|
context "using an :if to control the validation" do
|
75
75
|
before do
|
76
76
|
Dummy.class_eval do
|
77
|
-
validates_attachment_content_type :avatar, content_type: %r{image/*}
|
77
|
+
validates_attachment_content_type :avatar, content_type: %r{image/*}, if: :go
|
78
78
|
attr_accessor :go
|
79
79
|
end
|
80
80
|
end
|
@@ -105,5 +105,4 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
|
|
105
105
|
allowing(%w(image/png image/jpeg)).
|
106
106
|
rejecting(%w(audio/mp3 application/octet-stream))
|
107
107
|
end
|
108
|
-
|
109
108
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "paperclip/matchers"
|
3
3
|
|
4
4
|
describe Paperclip::Shoulda::Matchers::ValidateAttachmentPresenceMatcher do
|
5
5
|
extend Paperclip::Shoulda::Matchers
|
@@ -29,11 +29,11 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentPresenceMatcher do
|
|
29
29
|
end
|
30
30
|
Dummy.class_eval do
|
31
31
|
validates_attachment_presence :avatar
|
32
|
-
validates_attachment_content_type :avatar, content_type:
|
32
|
+
validates_attachment_content_type :avatar, content_type: "image/gif"
|
33
33
|
end
|
34
34
|
dummy = Dummy.new
|
35
35
|
|
36
|
-
dummy.avatar = File.new fixture_file(
|
36
|
+
dummy.avatar = File.new fixture_file("5k.png")
|
37
37
|
|
38
38
|
expect(matcher).to accept(dummy)
|
39
39
|
end
|