jr-paperclip 7.3.0

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.
Files changed (200) hide show
  1. checksums.yaml +7 -0
  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/.github/workflows/reviewdog.yml +23 -0
  7. data/.github/workflows/test.yml +46 -0
  8. data/.gitignore +19 -0
  9. data/.qlty/.gitignore +7 -0
  10. data/.qlty/qlty.toml +89 -0
  11. data/.rubocop.yml +1060 -0
  12. data/Appraisals +29 -0
  13. data/CONTRIBUTING.md +85 -0
  14. data/Gemfile +17 -0
  15. data/LICENSE +25 -0
  16. data/NEWS +567 -0
  17. data/README.md +1083 -0
  18. data/RELEASING.md +17 -0
  19. data/Rakefile +52 -0
  20. data/bin/console +11 -0
  21. data/features/basic_integration.feature +85 -0
  22. data/features/migration.feature +29 -0
  23. data/features/rake_tasks.feature +62 -0
  24. data/features/step_definitions/attachment_steps.rb +121 -0
  25. data/features/step_definitions/html_steps.rb +15 -0
  26. data/features/step_definitions/rails_steps.rb +271 -0
  27. data/features/step_definitions/s3_steps.rb +16 -0
  28. data/features/step_definitions/web_steps.rb +106 -0
  29. data/features/support/env.rb +12 -0
  30. data/features/support/file_helpers.rb +34 -0
  31. data/features/support/fixtures/boot_config.txt +15 -0
  32. data/features/support/fixtures/gemfile.txt +5 -0
  33. data/features/support/fixtures/preinitializer.txt +20 -0
  34. data/features/support/paths.rb +28 -0
  35. data/features/support/rails.rb +39 -0
  36. data/features/support/selectors.rb +19 -0
  37. data/features/support/webmock_setup.rb +8 -0
  38. data/gemfiles/7.0.gemfile +20 -0
  39. data/gemfiles/7.1.gemfile +20 -0
  40. data/gemfiles/7.2.gemfile +20 -0
  41. data/gemfiles/8.0.gemfile +20 -0
  42. data/gemfiles/8.1.gemfile +20 -0
  43. data/lib/generators/paperclip/USAGE +8 -0
  44. data/lib/generators/paperclip/paperclip_generator.rb +36 -0
  45. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +15 -0
  46. data/lib/jr-paperclip.rb +1 -0
  47. data/lib/paperclip/attachment.rb +634 -0
  48. data/lib/paperclip/attachment_registry.rb +60 -0
  49. data/lib/paperclip/callbacks.rb +42 -0
  50. data/lib/paperclip/content_type_detector.rb +85 -0
  51. data/lib/paperclip/errors.rb +34 -0
  52. data/lib/paperclip/file_command_content_type_detector.rb +28 -0
  53. data/lib/paperclip/filename_cleaner.rb +15 -0
  54. data/lib/paperclip/geometry.rb +157 -0
  55. data/lib/paperclip/geometry_detector_factory.rb +45 -0
  56. data/lib/paperclip/geometry_parser_factory.rb +31 -0
  57. data/lib/paperclip/glue.rb +18 -0
  58. data/lib/paperclip/has_attached_file.rb +116 -0
  59. data/lib/paperclip/helpers.rb +60 -0
  60. data/lib/paperclip/interpolations/plural_cache.rb +18 -0
  61. data/lib/paperclip/interpolations.rb +205 -0
  62. data/lib/paperclip/io_adapters/abstract_adapter.rb +75 -0
  63. data/lib/paperclip/io_adapters/attachment_adapter.rb +56 -0
  64. data/lib/paperclip/io_adapters/data_uri_adapter.rb +22 -0
  65. data/lib/paperclip/io_adapters/empty_string_adapter.rb +19 -0
  66. data/lib/paperclip/io_adapters/file_adapter.rb +26 -0
  67. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +16 -0
  68. data/lib/paperclip/io_adapters/identity_adapter.rb +17 -0
  69. data/lib/paperclip/io_adapters/nil_adapter.rb +37 -0
  70. data/lib/paperclip/io_adapters/registry.rb +36 -0
  71. data/lib/paperclip/io_adapters/stringio_adapter.rb +36 -0
  72. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +44 -0
  73. data/lib/paperclip/io_adapters/uri_adapter.rb +78 -0
  74. data/lib/paperclip/locales/en.yml +18 -0
  75. data/lib/paperclip/locales/fr.yml +18 -0
  76. data/lib/paperclip/locales/gd.yml +20 -0
  77. data/lib/paperclip/logger.rb +21 -0
  78. data/lib/paperclip/matchers/have_attached_file_matcher.rb +54 -0
  79. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +101 -0
  80. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +59 -0
  81. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +97 -0
  82. data/lib/paperclip/matchers.rb +64 -0
  83. data/lib/paperclip/media_type_spoof_detector.rb +93 -0
  84. data/lib/paperclip/missing_attachment_styles.rb +84 -0
  85. data/lib/paperclip/processor.rb +56 -0
  86. data/lib/paperclip/processor_helpers.rb +52 -0
  87. data/lib/paperclip/rails_environment.rb +21 -0
  88. data/lib/paperclip/railtie.rb +31 -0
  89. data/lib/paperclip/schema.rb +104 -0
  90. data/lib/paperclip/storage/filesystem.rb +99 -0
  91. data/lib/paperclip/storage/fog.rb +262 -0
  92. data/lib/paperclip/storage/s3.rb +497 -0
  93. data/lib/paperclip/storage.rb +3 -0
  94. data/lib/paperclip/style.rb +106 -0
  95. data/lib/paperclip/tempfile.rb +42 -0
  96. data/lib/paperclip/tempfile_factory.rb +22 -0
  97. data/lib/paperclip/thumbnail.rb +131 -0
  98. data/lib/paperclip/url_generator.rb +83 -0
  99. data/lib/paperclip/validators/attachment_content_type_validator.rb +95 -0
  100. data/lib/paperclip/validators/attachment_file_name_validator.rb +82 -0
  101. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +28 -0
  102. data/lib/paperclip/validators/attachment_presence_validator.rb +28 -0
  103. data/lib/paperclip/validators/attachment_size_validator.rb +126 -0
  104. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +29 -0
  105. data/lib/paperclip/validators.rb +73 -0
  106. data/lib/paperclip/version.rb +3 -0
  107. data/lib/paperclip.rb +215 -0
  108. data/lib/tasks/paperclip.rake +140 -0
  109. data/paperclip.gemspec +51 -0
  110. data/shoulda_macros/paperclip.rb +134 -0
  111. data/spec/database.yml +4 -0
  112. data/spec/paperclip/attachment_definitions_spec.rb +13 -0
  113. data/spec/paperclip/attachment_processing_spec.rb +79 -0
  114. data/spec/paperclip/attachment_registry_spec.rb +158 -0
  115. data/spec/paperclip/attachment_spec.rb +1617 -0
  116. data/spec/paperclip/content_type_detector_spec.rb +58 -0
  117. data/spec/paperclip/file_command_content_type_detector_spec.rb +40 -0
  118. data/spec/paperclip/filename_cleaner_spec.rb +13 -0
  119. data/spec/paperclip/geometry_detector_spec.rb +47 -0
  120. data/spec/paperclip/geometry_parser_spec.rb +73 -0
  121. data/spec/paperclip/geometry_spec.rb +267 -0
  122. data/spec/paperclip/glue_spec.rb +63 -0
  123. data/spec/paperclip/has_attached_file_spec.rb +78 -0
  124. data/spec/paperclip/integration_spec.rb +702 -0
  125. data/spec/paperclip/interpolations_spec.rb +270 -0
  126. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +160 -0
  127. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +167 -0
  128. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +88 -0
  129. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
  130. data/spec/paperclip/io_adapters/file_adapter_spec.rb +134 -0
  131. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +142 -0
  132. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
  133. data/spec/paperclip/io_adapters/nil_adapter_spec.rb +25 -0
  134. data/spec/paperclip/io_adapters/registry_spec.rb +35 -0
  135. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +64 -0
  136. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +146 -0
  137. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +231 -0
  138. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
  139. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +108 -0
  140. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
  141. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
  142. data/spec/paperclip/media_type_spoof_detector_spec.rb +126 -0
  143. data/spec/paperclip/meta_class_spec.rb +30 -0
  144. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +88 -0
  145. data/spec/paperclip/paperclip_spec.rb +196 -0
  146. data/spec/paperclip/plural_cache_spec.rb +37 -0
  147. data/spec/paperclip/processor_helpers_spec.rb +57 -0
  148. data/spec/paperclip/processor_spec.rb +26 -0
  149. data/spec/paperclip/rails_environment_spec.rb +30 -0
  150. data/spec/paperclip/rake_spec.rb +103 -0
  151. data/spec/paperclip/schema_spec.rb +298 -0
  152. data/spec/paperclip/storage/filesystem_spec.rb +102 -0
  153. data/spec/paperclip/storage/fog_spec.rb +606 -0
  154. data/spec/paperclip/storage/s3_live_spec.rb +188 -0
  155. data/spec/paperclip/storage/s3_spec.rb +1974 -0
  156. data/spec/paperclip/style_spec.rb +251 -0
  157. data/spec/paperclip/tempfile_factory_spec.rb +33 -0
  158. data/spec/paperclip/tempfile_spec.rb +35 -0
  159. data/spec/paperclip/thumbnail_spec.rb +504 -0
  160. data/spec/paperclip/url_generator_spec.rb +231 -0
  161. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +410 -0
  162. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +249 -0
  163. data/spec/paperclip/validators/attachment_presence_validator_spec.rb +85 -0
  164. data/spec/paperclip/validators/attachment_size_validator_spec.rb +325 -0
  165. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +48 -0
  166. data/spec/paperclip/validators_spec.rb +179 -0
  167. data/spec/spec_helper.rb +52 -0
  168. data/spec/support/assertions.rb +84 -0
  169. data/spec/support/fake_model.rb +24 -0
  170. data/spec/support/fake_rails.rb +12 -0
  171. data/spec/support/fixtures/12k.png +0 -0
  172. data/spec/support/fixtures/50x50.png +0 -0
  173. data/spec/support/fixtures/5k.png +0 -0
  174. data/spec/support/fixtures/animated +0 -0
  175. data/spec/support/fixtures/animated.gif +0 -0
  176. data/spec/support/fixtures/animated.unknown +0 -0
  177. data/spec/support/fixtures/aws_s3.yml +13 -0
  178. data/spec/support/fixtures/bad.png +1 -0
  179. data/spec/support/fixtures/empty.html +1 -0
  180. data/spec/support/fixtures/empty.xlsx +0 -0
  181. data/spec/support/fixtures/fog.yml +8 -0
  182. data/spec/support/fixtures/rotated.jpg +0 -0
  183. data/spec/support/fixtures/s3.yml +8 -0
  184. data/spec/support/fixtures/sample.xlsm +0 -0
  185. data/spec/support/fixtures/spaced file.jpg +0 -0
  186. data/spec/support/fixtures/spaced file.png +0 -0
  187. data/spec/support/fixtures/text.txt +1 -0
  188. data/spec/support/fixtures/twopage.pdf +0 -0
  189. data/spec/support/fixtures/uppercase.PNG +0 -0
  190. data/spec/support/matchers/accept.rb +5 -0
  191. data/spec/support/matchers/exist.rb +5 -0
  192. data/spec/support/matchers/have_column.rb +23 -0
  193. data/spec/support/mock_attachment.rb +24 -0
  194. data/spec/support/mock_interpolator.rb +24 -0
  195. data/spec/support/mock_url_generator_builder.rb +26 -0
  196. data/spec/support/model_reconstruction.rb +72 -0
  197. data/spec/support/reporting.rb +11 -0
  198. data/spec/support/test_data.rb +13 -0
  199. data/spec/support/version_helper.rb +9 -0
  200. metadata +702 -0
@@ -0,0 +1,134 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::FileAdapter do
4
+ context "a new instance" do
5
+ context "with normal file" do
6
+ before do
7
+ @file = File.new(fixture_file("5k.png"))
8
+ @file.binmode
9
+ end
10
+
11
+ after do
12
+ @file.close
13
+ @subject.close if @subject
14
+ end
15
+
16
+ context "doing normal things" do
17
+ before do
18
+ @subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
19
+ end
20
+
21
+ it "uses the original filename to generate the tempfile" do
22
+ assert @subject.path.ends_with?(".png")
23
+ end
24
+
25
+ it "gets the right filename" do
26
+ assert_equal "5k.png", @subject.original_filename
27
+ end
28
+
29
+ it "forces binmode on tempfile" do
30
+ assert @subject.instance_variable_get("@tempfile").binmode?
31
+ end
32
+
33
+ it "gets the content type" do
34
+ assert_equal "image/png", @subject.content_type
35
+ end
36
+
37
+ it "returns content type as a string" do
38
+ expect(@subject.content_type).to be_a String
39
+ end
40
+
41
+ it "gets the file's size" do
42
+ assert_equal 4456, @subject.size
43
+ end
44
+
45
+ it "returns false for a call to nil?" do
46
+ assert !@subject.nil?
47
+ end
48
+
49
+ it "generates a MD5 hash of the contents" do
50
+ expected = Digest::MD5.file(@file.path).to_s
51
+ assert_equal expected, @subject.fingerprint
52
+ end
53
+
54
+ it "reads the contents of the file" do
55
+ expected = @file.read
56
+ assert !expected.empty?
57
+ assert_equal expected, @subject.read
58
+ end
59
+ end
60
+
61
+ context "file with multiple possible content type" do
62
+ before do
63
+ allow(MIME::Types).to receive(:type_for).and_return([
64
+ MIME::Type.new("content-type" => "image/x-png"),
65
+ MIME::Type.new("content-type" => "image/png"),
66
+ ])
67
+ @subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
68
+ end
69
+
70
+ it "prefers officially registered mime type" do
71
+ assert_equal "image/png", @subject.content_type
72
+ end
73
+
74
+ it "returns content type as a string" do
75
+ expect(@subject.content_type).to be_a String
76
+ end
77
+ end
78
+
79
+ context "file with content type derived from file contents on *nix" do
80
+ before do
81
+ allow(MIME::Types).to receive(:type_for).and_return([])
82
+ allow(Paperclip).to receive(:run).and_return("application/vnd.ms-office\n")
83
+ allow_any_instance_of(Paperclip::ContentTypeDetector).
84
+ to receive(:type_from_marcel).and_return("application/vnd.ms-office")
85
+
86
+ @subject = Paperclip.io_adapters.for(@file)
87
+ end
88
+
89
+ it "returns content type without newline character" do
90
+ assert_equal "application/vnd.ms-office", @subject.content_type
91
+ end
92
+ end
93
+ end
94
+
95
+ context "filename with restricted characters" do
96
+ before do
97
+ @file = File.open(fixture_file("animated.gif")) do |file|
98
+ StringIO.new(file.read)
99
+ end
100
+ allow(@file).to receive(:original_filename).and_return("image:restricted.gif")
101
+ @subject = Paperclip.io_adapters.for(@file)
102
+ end
103
+
104
+ after do
105
+ @file.close
106
+ @subject.close
107
+ end
108
+
109
+ it "does not generate filenames that include restricted characters" do
110
+ assert_equal "image_restricted.gif", @subject.original_filename
111
+ end
112
+
113
+ it "does not generate paths that include restricted characters" do
114
+ expect(@subject.path).to_not match(/:/)
115
+ end
116
+ end
117
+
118
+ context "empty file" do
119
+ before do
120
+ @file = Tempfile.new("file_adapter_test")
121
+ @subject = Paperclip.io_adapters.for(@file)
122
+ end
123
+
124
+ after do
125
+ @file.close
126
+ @subject.close
127
+ end
128
+
129
+ it "provides correct mime-type" do
130
+ assert_match %r{.*/x-empty}, @subject.content_type
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,142 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::HttpUrlProxyAdapter do
4
+ before do
5
+ @open_return = StringIO.new("xxx")
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)
9
+ Paperclip::HttpUrlProxyAdapter.register
10
+ end
11
+
12
+ after do
13
+ Paperclip.io_adapters.unregister(described_class)
14
+ end
15
+
16
+ context "a new instance" do
17
+ before do
18
+ @url = "http://thoughtbot.com/images/thoughtbot-logo.png"
19
+ end
20
+
21
+ subject { Paperclip.io_adapters.for(@url, hash_digest: Digest::MD5) }
22
+
23
+ after do
24
+ subject.close
25
+ end
26
+
27
+ it "returns a file name" do
28
+ expect(subject.original_filename).to(eq("thoughtbot-logo.png"))
29
+ end
30
+
31
+ it "closes open handle after reading" do
32
+ expect { subject }.to(change { @open_return.closed? }.from(false).to(true))
33
+ end
34
+
35
+ it "returns a content type" do
36
+ expect(subject.content_type).to(eq("image/png"))
37
+ end
38
+
39
+ it "returns the size of the data" do
40
+ expect(subject.size).to(eq(@open_return.size))
41
+ end
42
+
43
+ it "generates an MD5 hash of the contents" do
44
+ expect(subject.fingerprint).to(eq(Digest::MD5.hexdigest("xxx")))
45
+ end
46
+
47
+ it "generates correct fingerprint after read" do
48
+ fingerprint = Digest::MD5.hexdigest(subject.read)
49
+ expect(subject.fingerprint).to(eq(fingerprint))
50
+ end
51
+
52
+ it "generates same fingerprint" do
53
+ expect(subject.fingerprint).to(eq(subject.fingerprint))
54
+ end
55
+
56
+ it "returns the data contained in the StringIO" do
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"))
63
+ end
64
+
65
+ it "accepts an original_filename" do
66
+ subject.original_filename = "image.png"
67
+ expect(subject.original_filename).to(eq("image.png"))
68
+ end
69
+
70
+ it "doesn't emit deprecation warnings" do
71
+ expect { subject }.to_not(output(/URI\.(un)?escape is obsolete/).to_stderr)
72
+ end
73
+ end
74
+
75
+ context "a url with query params" do
76
+ subject { Paperclip.io_adapters.for(url) }
77
+
78
+ after { subject.close }
79
+
80
+ let(:url) { "https://github.com/thoughtbot/paperclip?file=test" }
81
+
82
+ it "returns a file name" do
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
88
+ end
89
+ end
90
+
91
+ context "a url with restricted characters in the filename" do
92
+ before do
93
+ @url = "https://github.com/thoughtbot/paper:clip.jpg"
94
+ @subject = Paperclip.io_adapters.for(@url)
95
+ end
96
+
97
+ after do
98
+ begin
99
+ @subject.close
100
+ rescue Exception
101
+ true
102
+ end
103
+ end
104
+
105
+ it "does not generate filenames that include restricted characters" do
106
+ assert_equal "paper_clip.jpg", @subject.original_filename
107
+ end
108
+
109
+ it "does not generate paths that include restricted characters" do
110
+ expect(@subject.path).to_not match(/:/)
111
+ end
112
+ end
113
+
114
+ context "a url with special characters in the filename" do
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"\
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) }
126
+
127
+ it "returns a encoded filename" do
128
+ assert_equal filename, subject.original_filename
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
141
+ end
142
+ end
@@ -0,0 +1,8 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::IdentityAdapter do
4
+ it "responds to #new by returning the argument" do
5
+ adapter = Paperclip::IdentityAdapter.new
6
+ assert_equal :target, adapter.new(:target, nil)
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::NilAdapter do
4
+ context "a new instance" do
5
+ before do
6
+ @subject = Paperclip.io_adapters.for(nil)
7
+ end
8
+
9
+ it "gets the right filename" do
10
+ assert_equal "", @subject.original_filename
11
+ end
12
+
13
+ it "gets the content type" do
14
+ assert_equal "", @subject.content_type
15
+ end
16
+
17
+ it "gets the file's size" do
18
+ assert_equal 0, @subject.size
19
+ end
20
+
21
+ it "returns true for a call to nil?" do
22
+ assert @subject.nil?
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::AttachmentRegistry do
4
+ context "for" do
5
+ before do
6
+ class AdapterTest
7
+ def initialize(_target, _ = {}); end
8
+ end
9
+ @subject = Paperclip::AdapterRegistry.new
10
+ @subject.register(AdapterTest) { |t| Symbol === t }
11
+ end
12
+
13
+ it "returns the class registered for the adapted type" do
14
+ assert_equal AdapterTest, @subject.for(:target).class
15
+ end
16
+ end
17
+
18
+ context "registered?" do
19
+ before do
20
+ class AdapterTest
21
+ def initialize(_target, _ = {}); end
22
+ end
23
+ @subject = Paperclip::AdapterRegistry.new
24
+ @subject.register(AdapterTest) { |t| Symbol === t }
25
+ end
26
+
27
+ it "returns true when the class of this adapter has been registered" do
28
+ assert @subject.registered?(AdapterTest.new(:target))
29
+ end
30
+
31
+ it "returns false when the adapter has not been registered" do
32
+ assert !@subject.registered?(Object)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,64 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::StringioAdapter do
4
+ context "a new instance" do
5
+ before do
6
+ @contents = "abc123"
7
+ @stringio = StringIO.new(@contents)
8
+ @subject = Paperclip.io_adapters.for(@stringio, hash_digest: Digest::MD5)
9
+ end
10
+
11
+ it "returns a file name" do
12
+ assert_equal "data", @subject.original_filename
13
+ end
14
+
15
+ it "returns a content type" do
16
+ assert_equal "text/plain", @subject.content_type
17
+ end
18
+
19
+ it "returns the size of the data" do
20
+ assert_equal 6, @subject.size
21
+ end
22
+
23
+ it "returns the length of the data" do
24
+ assert_equal 6, @subject.length
25
+ end
26
+
27
+ it "generates an MD5 hash of the contents" do
28
+ assert_equal Digest::MD5.hexdigest(@contents), @subject.fingerprint
29
+ end
30
+
31
+ it "generates correct fingerprint after read" do
32
+ fingerprint = Digest::MD5.hexdigest(@subject.read)
33
+ assert_equal fingerprint, @subject.fingerprint
34
+ end
35
+
36
+ it "generates same fingerprint" do
37
+ assert_equal @subject.fingerprint, @subject.fingerprint
38
+ end
39
+
40
+ it "returns the data contained in the StringIO" do
41
+ assert_equal "abc123", @subject.read
42
+ end
43
+
44
+ it "accepts a content_type" do
45
+ @subject.content_type = "image/png"
46
+ assert_equal "image/png", @subject.content_type
47
+ end
48
+
49
+ it "accepts an original_filename" do
50
+ @subject.original_filename = "image.png"
51
+ assert_equal "image.png", @subject.original_filename
52
+ end
53
+
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
57
+ end
58
+
59
+ it "does not generate paths that include restricted characters" do
60
+ @subject.original_filename = "image:restricted.png"
61
+ expect(@subject.path).to_not match(/:/)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,146 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::UploadedFileAdapter do
4
+ context "a new instance" do
5
+ context "with UploadedFile responding to #tempfile" do
6
+ before do
7
+ Paperclip::UploadedFileAdapter.content_type_detector = nil
8
+
9
+ class UploadedFile < OpenStruct; end
10
+ tempfile = File.new(fixture_file("5k.png"))
11
+ tempfile.binmode
12
+
13
+ @file = UploadedFile.new(
14
+ original_filename: "5k.png",
15
+ content_type: "image/x-png-by-browser\r",
16
+ head: "",
17
+ tempfile: tempfile,
18
+ path: tempfile.path
19
+ )
20
+ @subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
21
+ end
22
+
23
+ it "gets the right filename" do
24
+ assert_equal "5k.png", @subject.original_filename
25
+ end
26
+
27
+ it "forces binmode on tempfile" do
28
+ assert @subject.instance_variable_get("@tempfile").binmode?
29
+ end
30
+
31
+ it "gets the content type" do
32
+ assert_equal "image/png", @subject.content_type
33
+ end
34
+
35
+ it "gets the file's size" do
36
+ assert_equal 4456, @subject.size
37
+ end
38
+
39
+ it "returns false for a call to nil?" do
40
+ assert !@subject.nil?
41
+ end
42
+
43
+ it "generates a MD5 hash of the contents" do
44
+ expected = Digest::MD5.file(@file.tempfile.path).to_s
45
+ assert_equal expected, @subject.fingerprint
46
+ end
47
+
48
+ it "reads the contents of the file" do
49
+ expected = @file.tempfile.read
50
+ assert !expected.empty?
51
+ assert_equal expected, @subject.read
52
+ end
53
+ end
54
+
55
+ context "with UploadedFile that has restricted characters" do
56
+ before do
57
+ Paperclip::UploadedFileAdapter.content_type_detector = nil
58
+
59
+ class UploadedFile < OpenStruct; end
60
+ @file = UploadedFile.new(
61
+ original_filename: "image:restricted.gif",
62
+ content_type: "image/x-png-by-browser",
63
+ head: "",
64
+ path: fixture_file("5k.png")
65
+ )
66
+ @subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
67
+ end
68
+
69
+ it "does not generate paths that include restricted characters" do
70
+ expect(@subject.path).to_not match(/:/)
71
+ end
72
+
73
+ it "does not generate filenames that include restricted characters" do
74
+ assert_equal "image_restricted.gif", @subject.original_filename
75
+ end
76
+ end
77
+
78
+ context "with UploadFile responding to #path" do
79
+ before do
80
+ Paperclip::UploadedFileAdapter.content_type_detector = nil
81
+
82
+ class UploadedFile < OpenStruct; end
83
+ @file = UploadedFile.new(
84
+ original_filename: "5k.png",
85
+ content_type: "image/x-png-by-browser",
86
+ head: "",
87
+ path: fixture_file("5k.png")
88
+ )
89
+ @subject = Paperclip.io_adapters.for(@file, hash_digest: Digest::MD5)
90
+ end
91
+
92
+ it "gets the right filename" do
93
+ assert_equal "5k.png", @subject.original_filename
94
+ end
95
+
96
+ it "forces binmode on tempfile" do
97
+ assert @subject.instance_variable_get("@tempfile").binmode?
98
+ end
99
+
100
+ it "gets the content type" do
101
+ assert_equal "image/png", @subject.content_type
102
+ end
103
+
104
+ it "gets the file's size" do
105
+ assert_equal 4456, @subject.size
106
+ end
107
+
108
+ it "returns false for a call to nil?" do
109
+ assert !@subject.nil?
110
+ end
111
+
112
+ it "generates a MD5 hash of the contents" do
113
+ expected = Digest::MD5.file(@file.path).to_s
114
+ assert_equal expected, @subject.fingerprint
115
+ end
116
+
117
+ it "reads the contents of the file" do
118
+ expected_file = File.new(@file.path)
119
+ expected_file.binmode
120
+ expected = expected_file.read
121
+ assert !expected.empty?
122
+ assert_equal expected, @subject.read
123
+ end
124
+
125
+ context "don't trust client-given MIME type" do
126
+ before do
127
+ Paperclip::UploadedFileAdapter.content_type_detector =
128
+ Paperclip::FileCommandContentTypeDetector
129
+
130
+ class UploadedFile < OpenStruct; end
131
+ @file = UploadedFile.new(
132
+ original_filename: "5k.png",
133
+ content_type: "image/x-png-by-browser",
134
+ head: "",
135
+ path: fixture_file("5k.png")
136
+ )
137
+ @subject = Paperclip.io_adapters.for(@file)
138
+ end
139
+
140
+ it "gets the content type" do
141
+ assert_equal "image/png", @subject.content_type
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end