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,249 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::Validators::AttachmentFileNameValidator do
4
+ before do
5
+ rebuild_model
6
+ @dummy = Dummy.new
7
+ end
8
+
9
+ def build_validator(options)
10
+ @validator = Paperclip::Validators::AttachmentFileNameValidator.new(options.merge(
11
+ attributes: :avatar
12
+ ))
13
+ end
14
+
15
+ context "with a failing validation" do
16
+ before do
17
+ build_validator matches: /.*\.png$/, allow_nil: false
18
+ allow(@dummy).to receive_messages(avatar_file_name: "data.txt")
19
+ @validator.validate(@dummy)
20
+ end
21
+
22
+ it "adds error to the base object" do
23
+ assert @dummy.errors[:avatar].present?,
24
+ "Error not added to base attribute"
25
+ end
26
+
27
+ it "adds error to base object as a string" do
28
+ expect(@dummy.errors[:avatar].first).to be_a String
29
+ end
30
+ end
31
+
32
+ context "with add_validation_errors_to not set (implicitly :both)" do
33
+ it "adds error to both attribute and base" do
34
+ build_validator matches: /.*\.png$/, allow_nil: false
35
+ allow(@dummy).to receive_messages(avatar_file_name: "data.txt")
36
+ @validator.validate(@dummy)
37
+
38
+ assert @dummy.errors[:avatar_file_name].present?,
39
+ "Error not added to attribute"
40
+
41
+ assert @dummy.errors[:avatar].present?,
42
+ "Error not added to base attribute"
43
+ end
44
+ end
45
+
46
+ context "with add_validation_errors_to set to :attribute globally" do
47
+ before do
48
+ Paperclip.options[:add_validation_errors_to] = :attribute
49
+ end
50
+
51
+ after do
52
+ Paperclip.options[:add_validation_errors_to] = :both
53
+ end
54
+
55
+ it "only adds error to attribute not base" do
56
+ build_validator matches: /.*\.png$/, allow_nil: false
57
+ allow(@dummy).to receive_messages(avatar_file_name: "data.txt")
58
+ @validator.validate(@dummy)
59
+
60
+ assert @dummy.errors[:avatar_file_name].present?,
61
+ "Error not added to attribute"
62
+
63
+ assert @dummy.errors[:avatar].blank?,
64
+ "Error added to base attribute"
65
+ end
66
+ end
67
+
68
+ context "with add_validation_errors_to set to :base globally" do
69
+ before do
70
+ Paperclip.options[:add_validation_errors_to] = :base
71
+ end
72
+
73
+ after do
74
+ Paperclip.options[:add_validation_errors_to] = :both
75
+ end
76
+
77
+ it "only adds error to base not attribute" do
78
+ build_validator matches: /.*\.png$/, allow_nil: false
79
+ allow(@dummy).to receive_messages(avatar_file_name: "data.txt")
80
+ @validator.validate(@dummy)
81
+
82
+ assert @dummy.errors[:avatar].present?,
83
+ "Error not added to base attribute"
84
+
85
+ assert @dummy.errors[:avatar_file_name].blank?,
86
+ "Error added to attribute"
87
+ end
88
+ end
89
+
90
+ context "with add_validation_errors_to set to :attribute" do
91
+ it "only adds error to attribute not base" do
92
+ build_validator matches: /.*\.png$/, allow_nil: false,
93
+ add_validation_errors_to: :attribute
94
+
95
+ allow(@dummy).to receive_messages(avatar_file_name: "data.txt")
96
+ @validator.validate(@dummy)
97
+
98
+ assert @dummy.errors[:avatar_file_name].present?,
99
+ "Error not added to attribute"
100
+
101
+ assert @dummy.errors[:avatar].blank?,
102
+ "Error added to base attribute"
103
+ end
104
+ end
105
+
106
+ context "with add_validation_errors_to set to :base" do
107
+ it "only adds error to base not attribute" do
108
+ build_validator matches: /.*\.png$/, allow_nil: false,
109
+ add_validation_errors_to: :base
110
+
111
+ allow(@dummy).to receive_messages(avatar_file_name: "data.txt")
112
+ @validator.validate(@dummy)
113
+
114
+ assert @dummy.errors[:avatar].present?,
115
+ "Error not added to base attribute"
116
+
117
+ assert @dummy.errors[:avatar_file_name].blank?,
118
+ "Error added to attribute"
119
+ end
120
+ end
121
+
122
+ it "does not add error to the base object with a successful validation" do
123
+ build_validator matches: /.*\.png$/, allow_nil: false
124
+ allow(@dummy).to receive_messages(avatar_file_name: "image.png")
125
+ @validator.validate(@dummy)
126
+
127
+ assert @dummy.errors[:avatar].blank?, "Error was added to base attribute"
128
+ end
129
+
130
+ context "whitelist format" do
131
+ context "with an allowed type" do
132
+ context "as a single regexp" do
133
+ before do
134
+ build_validator matches: /.*\.jpg$/
135
+ allow(@dummy).to receive_messages(avatar_file_name: "image.jpg")
136
+ @validator.validate(@dummy)
137
+ end
138
+
139
+ it "does not set an error message" do
140
+ assert @dummy.errors[:avatar_file_name].blank?
141
+ end
142
+ end
143
+
144
+ context "as a list" do
145
+ before do
146
+ build_validator matches: [/.*\.png$/, /.*\.jpe?g$/]
147
+ allow(@dummy).to receive_messages(avatar_file_name: "image.jpg")
148
+ @validator.validate(@dummy)
149
+ end
150
+
151
+ it "does not set an error message" do
152
+ assert @dummy.errors[:avatar_file_name].blank?
153
+ end
154
+ end
155
+ end
156
+
157
+ context "with a disallowed type" do
158
+ it "sets a correct default error message" do
159
+ build_validator matches: /^text\/.*/
160
+ allow(@dummy).to receive_messages(avatar_file_name: "image.jpg")
161
+ @validator.validate(@dummy)
162
+
163
+ assert @dummy.errors[:avatar_file_name].present?
164
+ expect(@dummy.errors[:avatar_file_name]).to include "is invalid"
165
+ end
166
+
167
+ it "sets a correct custom error message" do
168
+ build_validator matches: /.*\.png$/, message: "should be a PNG image"
169
+ allow(@dummy).to receive_messages(avatar_file_name: "image.jpg")
170
+ @validator.validate(@dummy)
171
+
172
+ expect(@dummy.errors[:avatar_file_name]).to include "should be a PNG image"
173
+ end
174
+ end
175
+ end
176
+
177
+ context "blacklist format" do
178
+ context "with an allowed type" do
179
+ context "as a single regexp" do
180
+ before do
181
+ build_validator not: /^text\/.*/
182
+ allow(@dummy).to receive_messages(avatar_file_name: "image.jpg")
183
+ @validator.validate(@dummy)
184
+ end
185
+
186
+ it "does not set an error message" do
187
+ assert @dummy.errors[:avatar_file_name].blank?
188
+ end
189
+ end
190
+
191
+ context "as a list" do
192
+ before do
193
+ build_validator not: [/.*\.png$/, /.*\.jpe?g$/]
194
+ allow(@dummy).to receive_messages(avatar_file_name: "image.gif")
195
+ @validator.validate(@dummy)
196
+ end
197
+
198
+ it "does not set an error message" do
199
+ assert @dummy.errors[:avatar_file_name].blank?
200
+ end
201
+ end
202
+ end
203
+
204
+ context "with a disallowed type" do
205
+ it "sets a correct default error message" do
206
+ build_validator not: /data.*/
207
+ allow(@dummy).to receive_messages(avatar_file_name: "data.txt")
208
+ @validator.validate(@dummy)
209
+
210
+ assert @dummy.errors[:avatar_file_name].present?
211
+ expect(@dummy.errors[:avatar_file_name]).to include "is invalid"
212
+ end
213
+
214
+ it "sets a correct custom error message" do
215
+ build_validator not: /.*\.png$/, message: "should not be a PNG image"
216
+ allow(@dummy).to receive_messages(avatar_file_name: "image.png")
217
+ @validator.validate(@dummy)
218
+
219
+ expect(@dummy.errors[:avatar_file_name]).to include "should not be a PNG image"
220
+ end
221
+ end
222
+ end
223
+
224
+ context "using the helper" do
225
+ before do
226
+ Dummy.validates_attachment_file_name :avatar, matches: /.*\.jpg$/
227
+ end
228
+
229
+ it "adds the validator to the class" do
230
+ assert Dummy.validators_on(:avatar).any? { |validator| validator.kind == :attachment_file_name }
231
+ end
232
+ end
233
+
234
+ context "given options" do
235
+ it "raises argument error if no required argument was given" do
236
+ assert_raises(ArgumentError) do
237
+ build_validator message: "Some message"
238
+ end
239
+ end
240
+
241
+ it "does not raise argument error if :matches was given" do
242
+ build_validator matches: /.*\.jpg$/
243
+ end
244
+
245
+ it "does not raise argument error if :not was given" do
246
+ build_validator not: /.*\.jpg$/
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,85 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::Validators::AttachmentPresenceValidator do
4
+ before do
5
+ rebuild_model
6
+ @dummy = Dummy.new
7
+ end
8
+
9
+ def build_validator(options = {})
10
+ @validator = Paperclip::Validators::AttachmentPresenceValidator.new(options.merge(
11
+ attributes: :avatar
12
+ ))
13
+ end
14
+
15
+ context "nil attachment" do
16
+ before do
17
+ @dummy.avatar = nil
18
+ end
19
+
20
+ context "with default options" do
21
+ before do
22
+ build_validator
23
+ @validator.validate(@dummy)
24
+ end
25
+
26
+ it "adds error on the attachment" do
27
+ assert @dummy.errors[:avatar].present?
28
+ end
29
+
30
+ it "does not add an error on the file_name attribute" do
31
+ assert @dummy.errors[:avatar_file_name].blank?
32
+ end
33
+ end
34
+
35
+ context "with :if option" do
36
+ context "returning true" do
37
+ before do
38
+ build_validator if: true
39
+ @validator.validate(@dummy)
40
+ end
41
+
42
+ it "performs a validation" do
43
+ assert @dummy.errors[:avatar].present?
44
+ end
45
+ end
46
+
47
+ context "returning false" do
48
+ before do
49
+ build_validator if: false
50
+ @validator.validate(@dummy)
51
+ end
52
+
53
+ it "performs a validation" do
54
+ assert @dummy.errors[:avatar].present?
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ context "with attachment" do
61
+ before do
62
+ build_validator
63
+ @dummy.avatar = StringIO.new('.\n')
64
+ @validator.validate(@dummy)
65
+ end
66
+
67
+ it "does not add error on the attachment" do
68
+ assert @dummy.errors[:avatar].blank?
69
+ end
70
+
71
+ it "does not add an error on the file_name attribute" do
72
+ assert @dummy.errors[:avatar_file_name].blank?
73
+ end
74
+ end
75
+
76
+ context "using the helper" do
77
+ before do
78
+ Dummy.validates_attachment_presence :avatar
79
+ end
80
+
81
+ it "adds the validator to the class" do
82
+ assert Dummy.validators_on(:avatar).any? { |validator| validator.kind == :attachment_presence }
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,325 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::Validators::AttachmentSizeValidator do
4
+ before do
5
+ rebuild_model
6
+ @dummy = Dummy.new
7
+ end
8
+
9
+ def build_validator(options)
10
+ @validator = Paperclip::Validators::AttachmentSizeValidator.new(options.merge(
11
+ attributes: :avatar
12
+ ))
13
+ end
14
+
15
+ def self.should_allow_attachment_file_size(size)
16
+ context "when the attachment size is #{size}" do
17
+ it "adds error to dummy object" do
18
+ allow(@dummy).to receive(:avatar_content_type).and_return(size)
19
+ @validator.validate(@dummy)
20
+ assert @dummy.errors[:avatar_file_size].blank?,
21
+ "Expect an error message on :avatar_file_size, got none."
22
+ end
23
+
24
+ it "does not add error to the base dummy object" do
25
+ assert @dummy.errors[:avatar].blank?,
26
+ "Error added to base attribute"
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.should_not_allow_attachment_file_size(size, options = {})
32
+ context "when the attachment size is #{size}" do
33
+ before do
34
+ allow(@dummy).to receive(:avatar_file_size).and_return(size)
35
+ @validator.validate(@dummy)
36
+ end
37
+
38
+ it "adds error to dummy object" do
39
+ assert @dummy.errors[:avatar_file_size].present?,
40
+ "Unexpected error message on :avatar_file_size"
41
+ end
42
+
43
+ it "adds error to the base dummy object" do
44
+ assert @dummy.errors[:avatar].present?,
45
+ "Error not added to base attribute"
46
+ end
47
+
48
+ it "adds error to base object as a string" do
49
+ expect(@dummy.errors[:avatar].first).to be_a String
50
+ end
51
+
52
+ if options[:message]
53
+ it "returns a correct error message" do
54
+ expect(@dummy.errors[:avatar_file_size]).to include options[:message]
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ context "with :in option" do
61
+ context "as a range" do
62
+ before do
63
+ build_validator in: (5.kilobytes..10.kilobytes)
64
+ end
65
+
66
+ should_allow_attachment_file_size(7.kilobytes)
67
+ should_not_allow_attachment_file_size(4.kilobytes)
68
+ should_not_allow_attachment_file_size(11.kilobytes)
69
+ end
70
+
71
+ context "as a proc" do
72
+ before do
73
+ build_validator in: lambda { |_avatar| (5.kilobytes..10.kilobytes) }
74
+ end
75
+
76
+ should_allow_attachment_file_size(7.kilobytes)
77
+ should_not_allow_attachment_file_size(4.kilobytes)
78
+ should_not_allow_attachment_file_size(11.kilobytes)
79
+ end
80
+ end
81
+
82
+ context "with :greater_than option" do
83
+ context "as number" do
84
+ before do
85
+ build_validator greater_than: 10.kilobytes
86
+ end
87
+
88
+ should_allow_attachment_file_size 11.kilobytes
89
+ should_not_allow_attachment_file_size 10.kilobytes
90
+ end
91
+
92
+ context "as a proc" do
93
+ before do
94
+ build_validator greater_than: lambda { |_avatar| 10.kilobytes }
95
+ end
96
+
97
+ should_allow_attachment_file_size 11.kilobytes
98
+ should_not_allow_attachment_file_size 10.kilobytes
99
+ end
100
+ end
101
+
102
+ context "with :less_than option" do
103
+ context "as number" do
104
+ before do
105
+ build_validator less_than: 10.kilobytes
106
+ end
107
+
108
+ should_allow_attachment_file_size 9.kilobytes
109
+ should_not_allow_attachment_file_size 10.kilobytes
110
+ end
111
+
112
+ context "as a proc" do
113
+ before do
114
+ build_validator less_than: lambda { |_avatar| 10.kilobytes }
115
+ end
116
+
117
+ should_allow_attachment_file_size 9.kilobytes
118
+ should_not_allow_attachment_file_size 10.kilobytes
119
+ end
120
+ end
121
+
122
+ context "with :greater_than and :less_than option" do
123
+ context "as numbers" do
124
+ before do
125
+ build_validator greater_than: 5.kilobytes,
126
+ less_than: 10.kilobytes
127
+ end
128
+
129
+ should_allow_attachment_file_size 7.kilobytes
130
+ should_not_allow_attachment_file_size 5.kilobytes
131
+ should_not_allow_attachment_file_size 10.kilobytes
132
+ end
133
+
134
+ context "as a proc" do
135
+ before do
136
+ build_validator greater_than: lambda { |_avatar| 5.kilobytes },
137
+ less_than: lambda { |_avatar| 10.kilobytes }
138
+ end
139
+
140
+ should_allow_attachment_file_size 7.kilobytes
141
+ should_not_allow_attachment_file_size 5.kilobytes
142
+ should_not_allow_attachment_file_size 10.kilobytes
143
+ end
144
+ end
145
+
146
+ context "with :message option" do
147
+ context "given a range" do
148
+ before do
149
+ build_validator in: (5.kilobytes..10.kilobytes),
150
+ message: "is invalid. (Between %{min} and %{max} please.)"
151
+ end
152
+
153
+ should_not_allow_attachment_file_size(
154
+ 11.kilobytes,
155
+ message: "is invalid. (Between 5 KB and 10 KB please.)"
156
+ )
157
+ end
158
+
159
+ context "given :less_than and :greater_than" do
160
+ before do
161
+ build_validator less_than: 10.kilobytes,
162
+ greater_than: 5.kilobytes,
163
+ message: "is invalid. (Between %{min} and %{max} please.)"
164
+ end
165
+
166
+ should_not_allow_attachment_file_size(
167
+ 11.kilobytes,
168
+ message: "is invalid. (Between 5 KB and 10 KB please.)"
169
+ )
170
+ end
171
+ end
172
+
173
+ context "default error messages" do
174
+ context "given :less_than and :greater_than" do
175
+ before do
176
+ build_validator greater_than: 5.kilobytes,
177
+ less_than: 10.kilobytes
178
+ end
179
+
180
+ should_not_allow_attachment_file_size(
181
+ 11.kilobytes,
182
+ message: "must be less than 10 KB"
183
+ )
184
+
185
+ should_not_allow_attachment_file_size(
186
+ 4.kilobytes,
187
+ message: "must be greater than 5 KB"
188
+ )
189
+ end
190
+
191
+ context "given a size range" do
192
+ before do
193
+ build_validator in: (5.kilobytes..10.kilobytes)
194
+ end
195
+
196
+ should_not_allow_attachment_file_size(
197
+ 11.kilobytes,
198
+ message: "must be in between 5 KB and 10 KB"
199
+ )
200
+
201
+ should_not_allow_attachment_file_size(
202
+ 4.kilobytes,
203
+ message: "must be in between 5 KB and 10 KB"
204
+ )
205
+ end
206
+ end
207
+
208
+ context "with add_validation_errors_to not set (implicitly :both)" do
209
+ it "adds error to both attribute and base" do
210
+ build_validator in: (5.kilobytes..10.kilobytes)
211
+ allow(@dummy).to receive(:avatar_file_size).and_return(11.kilobytes)
212
+ @validator.validate(@dummy)
213
+
214
+ assert @dummy.errors[:avatar_file_size].present?,
215
+ "Error not added to attribute"
216
+
217
+ assert @dummy.errors[:avatar].present?,
218
+ "Error not added to base attribute"
219
+ end
220
+ end
221
+
222
+ context "with add_validation_errors_to set to :attribute globally" do
223
+ before do
224
+ Paperclip.options[:add_validation_errors_to] = :attribute
225
+ end
226
+
227
+ after do
228
+ Paperclip.options[:add_validation_errors_to] = :both
229
+ end
230
+
231
+ it "only adds error to attribute not base" do
232
+ build_validator in: (5.kilobytes..10.kilobytes)
233
+ allow(@dummy).to receive(:avatar_file_size).and_return(11.kilobytes)
234
+ @validator.validate(@dummy)
235
+
236
+ assert @dummy.errors[:avatar_file_size].present?,
237
+ "Error not added to attribute"
238
+
239
+ assert @dummy.errors[:avatar].blank?,
240
+ "Error added to base attribute"
241
+ end
242
+ end
243
+
244
+ context "with add_validation_errors_to set to :base globally" do
245
+ before do
246
+ Paperclip.options[:add_validation_errors_to] = :base
247
+ end
248
+
249
+ after do
250
+ Paperclip.options[:add_validation_errors_to] = :both
251
+ end
252
+
253
+ it "only adds error to base not attribute" do
254
+ build_validator in: (5.kilobytes..10.kilobytes)
255
+ allow(@dummy).to receive(:avatar_file_size).and_return(11.kilobytes)
256
+ @validator.validate(@dummy)
257
+
258
+ assert @dummy.errors[:avatar].present?,
259
+ "Error not added to base attribute"
260
+
261
+ assert @dummy.errors[:avatar_file_size].blank?,
262
+ "Error added to attribute"
263
+ end
264
+ end
265
+
266
+ context "with add_validation_errors_to set to :attribute" do
267
+ it "only adds error to attribute not base" do
268
+ build_validator in: (5.kilobytes..10.kilobytes),
269
+ add_validation_errors_to: :attribute
270
+
271
+ allow(@dummy).to receive(:avatar_file_size).and_return(11.kilobytes)
272
+ @validator.validate(@dummy)
273
+
274
+ assert @dummy.errors[:avatar_file_size].present?,
275
+ "Error not added to attribute"
276
+
277
+ assert @dummy.errors[:avatar].blank?,
278
+ "Error added to base attribute"
279
+ end
280
+ end
281
+
282
+ context "with add_validation_errors_to set to :base" do
283
+ it "only adds error to base not attribute" do
284
+ build_validator in: (5.kilobytes..10.kilobytes),
285
+ add_validation_errors_to: :base
286
+
287
+ allow(@dummy).to receive(:avatar_file_size).and_return(11.kilobytes)
288
+ @validator.validate(@dummy)
289
+
290
+ assert @dummy.errors[:avatar].present?,
291
+ "Error not added to base attribute"
292
+
293
+ assert @dummy.errors[:avatar_file_size].blank?,
294
+ "Error added to attribute"
295
+ end
296
+ end
297
+
298
+ context "using the helper" do
299
+ before do
300
+ Dummy.validates_attachment_size :avatar, in: (5.kilobytes..10.kilobytes)
301
+ end
302
+
303
+ it "adds the validator to the class" do
304
+ assert Dummy.validators_on(:avatar).any? { |validator| validator.kind == :attachment_size }
305
+ end
306
+ end
307
+
308
+ context "given options" do
309
+ it "raises argument error if no required argument was given" do
310
+ assert_raises(ArgumentError) do
311
+ build_validator message: "Some message"
312
+ end
313
+ end
314
+
315
+ Paperclip::Validators::AttachmentSizeValidator::AVAILABLE_CHECKS.each do |argument|
316
+ it "does not raise arguemnt error if #{argument} was given" do
317
+ build_validator argument => 5.kilobytes
318
+ end
319
+ end
320
+
321
+ it "does not raise argument error if :in was given" do
322
+ build_validator in: (5.kilobytes..10.kilobytes)
323
+ end
324
+ end
325
+ end
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::Validators::MediaTypeSpoofDetectionValidator do
4
+ before do
5
+ rebuild_model
6
+ @dummy = Dummy.new
7
+ end
8
+
9
+ def build_validator(options = {})
10
+ @validator = Paperclip::Validators::MediaTypeSpoofDetectionValidator.new(options.merge(
11
+ attributes: :avatar
12
+ ))
13
+ end
14
+
15
+ it "is on the attachment without being explicitly added" do
16
+ assert Dummy.validators_on(:avatar).any? { |validator| validator.kind == :media_type_spoof_detection }
17
+ end
18
+
19
+ it "is not on the attachment when explicitly rejected" do
20
+ rebuild_model validate_media_type: false
21
+ assert Dummy.validators_on(:avatar).none? { |validator| validator.kind == :media_type_spoof_detection }
22
+ end
23
+
24
+ it "returns default error message for spoofed media type" do
25
+ build_validator
26
+ file = File.new(fixture_file("5k.png"), "rb")
27
+ @dummy.avatar.assign(file)
28
+
29
+ detector = double("detector", spoofed?: true)
30
+ allow(Paperclip::MediaTypeSpoofDetector).to receive(:using).and_return(detector)
31
+ @validator.validate(@dummy)
32
+
33
+ assert_equal I18n.t("errors.messages.spoofed_media_type"), @dummy.errors[:avatar].first
34
+ end
35
+
36
+ it "runs when attachment is dirty" do
37
+ build_validator
38
+ file = File.new(fixture_file("5k.png"), "rb")
39
+ @dummy.avatar.assign(file)
40
+ expect(Paperclip::MediaTypeSpoofDetector).to receive(:using).once.and_return(double("detector", spoofed?: false))
41
+ @dummy.valid?
42
+ end
43
+
44
+ it "does not run when attachment is not dirty" do
45
+ expect(Paperclip::MediaTypeSpoofDetector).to_not receive(:using)
46
+ @dummy.valid?
47
+ end
48
+ end