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.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  4. data/.github/ISSUE_TEMPLATE/custom.md +10 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  6. data/.hound.yml +3 -1055
  7. data/.rubocop.yml +1061 -1
  8. data/.travis.yml +23 -4
  9. data/Appraisals +23 -0
  10. data/CONTRIBUTING.md +4 -5
  11. data/Gemfile +10 -7
  12. data/NEWS +52 -0
  13. data/README.md +58 -46
  14. data/Rakefile +29 -21
  15. data/UPGRADING +3 -3
  16. data/features/basic_integration.feature +4 -0
  17. data/features/migration.feature +10 -51
  18. data/features/step_definitions/attachment_steps.rb +23 -13
  19. data/features/step_definitions/html_steps.rb +5 -5
  20. data/features/step_definitions/rails_steps.rb +29 -9
  21. data/features/step_definitions/s3_steps.rb +3 -3
  22. data/features/step_definitions/web_steps.rb +5 -6
  23. data/features/support/env.rb +4 -4
  24. data/features/support/fakeweb.rb +3 -5
  25. data/features/support/file_helpers.rb +2 -2
  26. data/features/support/paths.rb +4 -4
  27. data/features/support/rails.rb +7 -7
  28. data/features/support/selectors.rb +1 -1
  29. data/gemfiles/4.2.gemfile +7 -4
  30. data/gemfiles/5.0.gemfile +7 -4
  31. data/gemfiles/5.1.gemfile +20 -0
  32. data/gemfiles/5.2.gemfile +20 -0
  33. data/gemfiles/6.0.gemfile +20 -0
  34. data/gemfiles/6.1.gemfile +21 -0
  35. data/gemfiles/7.0.gemfile +21 -0
  36. data/lib/generators/paperclip/paperclip_generator.rb +6 -8
  37. data/lib/paperclip/attachment.rb +103 -105
  38. data/lib/paperclip/attachment_registry.rb +2 -2
  39. data/lib/paperclip/content_type_detector.rb +10 -5
  40. data/lib/paperclip/file_command_content_type_detector.rb +1 -3
  41. data/lib/paperclip/filename_cleaner.rb +0 -1
  42. data/lib/paperclip/geometry.rb +18 -19
  43. data/lib/paperclip/geometry_detector_factory.rb +13 -16
  44. data/lib/paperclip/geometry_parser_factory.rb +5 -5
  45. data/lib/paperclip/glue.rb +3 -3
  46. data/lib/paperclip/has_attached_file.rb +5 -4
  47. data/lib/paperclip/helpers.rb +3 -3
  48. data/lib/paperclip/interpolations.rb +42 -38
  49. data/lib/paperclip/io_adapters/abstract_adapter.rb +16 -14
  50. data/lib/paperclip/io_adapters/attachment_adapter.rb +12 -6
  51. data/lib/paperclip/io_adapters/data_uri_adapter.rb +1 -1
  52. data/lib/paperclip/io_adapters/file_adapter.rb +1 -3
  53. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +1 -1
  54. data/lib/paperclip/io_adapters/identity_adapter.rb +1 -2
  55. data/lib/paperclip/io_adapters/registry.rb +1 -1
  56. data/lib/paperclip/io_adapters/stringio_adapter.rb +1 -1
  57. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +6 -8
  58. data/lib/paperclip/io_adapters/uri_adapter.rb +21 -9
  59. data/lib/paperclip/logger.rb +1 -1
  60. data/lib/paperclip/matchers/have_attached_file_matcher.rb +4 -4
  61. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +19 -18
  62. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +4 -4
  63. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +11 -10
  64. data/lib/paperclip/matchers.rb +4 -4
  65. data/lib/paperclip/media_type_spoof_detector.rb +13 -13
  66. data/lib/paperclip/missing_attachment_styles.rb +11 -6
  67. data/lib/paperclip/processor.rb +13 -6
  68. data/lib/paperclip/processor_helpers.rb +3 -1
  69. data/lib/paperclip/rails_environment.rb +1 -5
  70. data/lib/paperclip/railtie.rb +5 -5
  71. data/lib/paperclip/schema.rb +16 -12
  72. data/lib/paperclip/storage/filesystem.rb +6 -8
  73. data/lib/paperclip/storage/fog.rb +36 -32
  74. data/lib/paperclip/storage/s3.rb +68 -76
  75. data/lib/paperclip/style.rb +3 -6
  76. data/lib/paperclip/tempfile.rb +4 -5
  77. data/lib/paperclip/tempfile_factory.rb +0 -1
  78. data/lib/paperclip/thumbnail.rb +11 -11
  79. data/lib/paperclip/url_generator.rb +5 -5
  80. data/lib/paperclip/validators/attachment_content_type_validator.rb +11 -4
  81. data/lib/paperclip/validators/attachment_file_name_validator.rb +14 -12
  82. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +1 -2
  83. data/lib/paperclip/validators/attachment_presence_validator.rb +3 -5
  84. data/lib/paperclip/validators/attachment_size_validator.rb +28 -11
  85. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +3 -1
  86. data/lib/paperclip/validators.rb +16 -17
  87. data/lib/paperclip/version.rb +1 -3
  88. data/lib/paperclip.rb +49 -48
  89. data/lib/tasks/paperclip.rake +23 -24
  90. data/paperclip.gemspec +29 -33
  91. data/shoulda_macros/paperclip.rb +16 -16
  92. data/spec/paperclip/attachment_definitions_spec.rb +5 -5
  93. data/spec/paperclip/attachment_processing_spec.rb +22 -23
  94. data/spec/paperclip/attachment_registry_spec.rb +15 -15
  95. data/spec/paperclip/attachment_spec.rb +238 -196
  96. data/spec/paperclip/content_type_detector_spec.rb +18 -12
  97. data/spec/paperclip/file_command_content_type_detector_spec.rb +10 -10
  98. data/spec/paperclip/filename_cleaner_spec.rb +3 -4
  99. data/spec/paperclip/geometry_detector_spec.rb +7 -8
  100. data/spec/paperclip/geometry_parser_spec.rb +31 -31
  101. data/spec/paperclip/geometry_spec.rb +24 -24
  102. data/spec/paperclip/glue_spec.rb +3 -5
  103. data/spec/paperclip/has_attached_file_spec.rb +46 -126
  104. data/spec/paperclip/integration_spec.rb +111 -77
  105. data/spec/paperclip/interpolations_spec.rb +101 -93
  106. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +41 -13
  107. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +8 -10
  108. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +13 -14
  109. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +4 -4
  110. data/spec/paperclip/io_adapters/file_adapter_spec.rb +12 -12
  111. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +58 -37
  112. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
  113. data/spec/paperclip/io_adapters/nil_adapter_spec.rb +2 -2
  114. data/spec/paperclip/io_adapters/registry_spec.rb +4 -4
  115. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +10 -10
  116. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +6 -6
  117. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +90 -31
  118. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +3 -3
  119. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +4 -5
  120. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +4 -4
  121. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +4 -4
  122. data/spec/paperclip/media_type_spoof_detector_spec.rb +50 -24
  123. data/spec/paperclip/meta_class_spec.rb +3 -3
  124. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +28 -24
  125. data/spec/paperclip/paperclip_spec.rb +15 -11
  126. data/spec/paperclip/plural_cache_spec.rb +8 -8
  127. data/spec/paperclip/processor_helpers_spec.rb +35 -35
  128. data/spec/paperclip/processor_spec.rb +8 -8
  129. data/spec/paperclip/rails_environment_spec.rb +7 -10
  130. data/spec/paperclip/rake_spec.rb +39 -39
  131. data/spec/paperclip/schema_spec.rb +57 -53
  132. data/spec/paperclip/storage/filesystem_spec.rb +29 -6
  133. data/spec/paperclip/storage/fog_spec.rb +122 -82
  134. data/spec/paperclip/storage/s3_live_spec.rb +22 -22
  135. data/spec/paperclip/storage/s3_spec.rb +649 -583
  136. data/spec/paperclip/style_spec.rb +67 -71
  137. data/spec/paperclip/tempfile_factory_spec.rb +5 -5
  138. data/spec/paperclip/thumbnail_spec.rb +68 -67
  139. data/spec/paperclip/url_generator_spec.rb +18 -19
  140. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +115 -27
  141. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +105 -16
  142. data/spec/paperclip/validators/attachment_presence_validator_spec.rb +5 -5
  143. data/spec/paperclip/validators/attachment_size_validator_spec.rb +111 -21
  144. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +9 -13
  145. data/spec/paperclip/validators_spec.rb +61 -46
  146. data/spec/spec_helper.rb +21 -23
  147. data/spec/support/assertions.rb +8 -6
  148. data/spec/support/fake_model.rb +1 -2
  149. data/spec/support/fake_rails.rb +1 -1
  150. data/spec/support/fixtures/aws_s3.yml +13 -0
  151. data/spec/support/fixtures/sample.xlsm +0 -0
  152. data/spec/support/matchers/exist.rb +1 -1
  153. data/spec/support/matchers/have_column.rb +1 -1
  154. data/spec/support/mock_url_generator_builder.rb +2 -3
  155. data/spec/support/model_reconstruction.rb +16 -12
  156. data/spec/support/reporting.rb +1 -1
  157. data/spec/support/test_data.rb +2 -2
  158. metadata +58 -106
  159. data/spec/support/conditional_filter_helper.rb +0 -5
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
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 'doing normal things' do
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 'uses the original filename to generate the tempfile' do
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 ! @subject.nil?
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.length > 0
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.stubs(:type_for).returns([MIME::Type.new('image/x-png'), MIME::Type.new('image/png')])
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.stubs(:type_for).returns([])
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")
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.stubs(:original_filename).returns('image:restricted.gif')
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 'image_restricted.gif', @subject.original_filename
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 'spec_helper'
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.stubs(:content_type).returns("image/png")
7
- @open_return.stubs(:meta).returns({})
8
- Paperclip::HttpUrlProxyAdapter.any_instance.
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
- @subject.close
24
+ subject.close
25
25
  end
26
26
 
27
27
  it "returns a file name" do
28
- assert_equal "thoughtbot-logo.png", @subject.original_filename
28
+ expect(subject.original_filename).to(eq("thoughtbot-logo.png"))
29
29
  end
30
30
 
31
- it 'closes open handle after reading' do
32
- assert_equal true, @open_return.closed?
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
- assert_equal "image/png", @subject.content_type
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
- assert_equal @open_return.size, @subject.size
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
- assert_equal Digest::MD5.hexdigest("xxx"), @subject.fingerprint
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(@subject.read)
49
- assert_equal fingerprint, @subject.fingerprint
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
- assert_equal @subject.fingerprint, @subject.fingerprint
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
- assert_equal "xxx", @subject.read
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 'accepts a content_type' do
61
- @subject.content_type = 'image/png'
62
- assert_equal 'image/png', @subject.content_type
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 'accepts an original_filename' do
66
- @subject.original_filename = 'image.png'
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
- before do
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 do
78
- @subject.close
79
- end
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", @subject.original_filename
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
- 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"\
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 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe Paperclip::IdentityAdapter do
4
4
  it "responds to #new by returning the argument" do
@@ -1,7 +1,7 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe Paperclip::NilAdapter do
4
- context 'a new instance' do
4
+ context "a new instance" do
5
5
  before do
6
6
  @subject = Paperclip.io_adapters.for(nil)
7
7
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
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 ! @subject.registered?(Object)
32
+ assert !@subject.registered?(Object)
33
33
  end
34
34
  end
35
35
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
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 'accepts a content_type' do
45
- @subject.content_type = 'image/png'
46
- assert_equal 'image/png', @subject.content_type
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 'accepts an original_filename' do
50
- @subject.original_filename = 'image.png'
51
- assert_equal 'image.png', @subject.original_filename
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 = 'image:restricted.png'
56
- assert_equal 'image_restricted.png', @subject.original_filename
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 = 'image:restricted.png'
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 'spec_helper'
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 ! @subject.nil?
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.length > 0
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 'image_restricted.gif', @subject.original_filename
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 ! @subject.nil?
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.length > 0
121
+ assert !expected.empty?
122
122
  assert_equal expected, @subject.read
123
123
  end
124
124
 
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
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.stubs(:content_type).returns(content_type)
10
- @open_return.stubs(:meta).returns(meta)
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.any_instance.
21
- stubs(:download_content).returns(@open_return)
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 'closes open handle after reading' do
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 'accepts a content_type' do
61
- @subject.content_type = 'image/png'
62
- assert_equal 'image/png', @subject.content_type
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 'accepts an orgiginal_filename' do
66
- @subject.original_filename = 'image.png'
67
- assert_equal 'image.png', @subject.original_filename
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.any_instance.
77
- stubs(:download_content).returns(@open_return)
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.any_instance.
95
- stubs(:download_content).returns(@open_return)
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(:meta) do
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.any_instance.
116
- stubs(:download_content).returns(@open_return)
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.any_instance.
130
- stubs(:download_content).returns(@open_return)
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
- Paperclip::UriAdapter.any_instance.stubs(:open).returns(@open_return)
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
- @subject.expects(:open).with(@uri, {}).at_least_once
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
- @subject.expects(:open).with(@uri, read_timeout: 120).at_least_once
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 'spec_helper'
2
- require 'paperclip/matchers'
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 'accepts the dummy class if it has an attachment' do
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 'spec_helper'
2
- require 'paperclip/matchers'
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 'rejects a class when the validation fails' do
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/*} , if: :go
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 'spec_helper'
2
- require 'paperclip/matchers'
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: 'image/gif'
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('5k.png')
36
+ dummy.avatar = File.new fixture_file("5k.png")
37
37
 
38
38
  expect(matcher).to accept(dummy)
39
39
  end