paperclip-fix 4.3.7

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 (197) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.hound.yml +1066 -0
  4. data/.rubocop.yml +1 -0
  5. data/.travis.yml +22 -0
  6. data/Appraisals +11 -0
  7. data/CONTRIBUTING.md +75 -0
  8. data/Gemfile +21 -0
  9. data/LICENSE +24 -0
  10. data/NEWS +420 -0
  11. data/README.md +979 -0
  12. data/RELEASING.md +17 -0
  13. data/Rakefile +44 -0
  14. data/UPGRADING +14 -0
  15. data/cucumber/paperclip_steps.rb +6 -0
  16. data/features/basic_integration.feature +80 -0
  17. data/features/migration.feature +94 -0
  18. data/features/rake_tasks.feature +62 -0
  19. data/features/step_definitions/attachment_steps.rb +110 -0
  20. data/features/step_definitions/html_steps.rb +15 -0
  21. data/features/step_definitions/rails_steps.rb +236 -0
  22. data/features/step_definitions/s3_steps.rb +14 -0
  23. data/features/step_definitions/web_steps.rb +107 -0
  24. data/features/support/env.rb +11 -0
  25. data/features/support/fakeweb.rb +13 -0
  26. data/features/support/file_helpers.rb +34 -0
  27. data/features/support/fixtures/boot_config.txt +15 -0
  28. data/features/support/fixtures/gemfile.txt +5 -0
  29. data/features/support/fixtures/preinitializer.txt +20 -0
  30. data/features/support/paths.rb +28 -0
  31. data/features/support/rails.rb +63 -0
  32. data/features/support/selectors.rb +19 -0
  33. data/gemfiles/3.2.gemfile +19 -0
  34. data/gemfiles/4.1.gemfile +19 -0
  35. data/gemfiles/4.2.gemfile +19 -0
  36. data/lib/generators/paperclip/USAGE +8 -0
  37. data/lib/generators/paperclip/paperclip_generator.rb +30 -0
  38. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +15 -0
  39. data/lib/paperclip/attachment.rb +608 -0
  40. data/lib/paperclip/attachment_registry.rb +59 -0
  41. data/lib/paperclip/callbacks.rb +40 -0
  42. data/lib/paperclip/content_type_detector.rb +79 -0
  43. data/lib/paperclip/deprecations.rb +42 -0
  44. data/lib/paperclip/errors.rb +32 -0
  45. data/lib/paperclip/file_command_content_type_detector.rb +30 -0
  46. data/lib/paperclip/filename_cleaner.rb +16 -0
  47. data/lib/paperclip/geometry.rb +158 -0
  48. data/lib/paperclip/geometry_detector_factory.rb +48 -0
  49. data/lib/paperclip/geometry_parser_factory.rb +31 -0
  50. data/lib/paperclip/glue.rb +17 -0
  51. data/lib/paperclip/has_attached_file.rb +109 -0
  52. data/lib/paperclip/helpers.rb +56 -0
  53. data/lib/paperclip/interpolations/plural_cache.rb +18 -0
  54. data/lib/paperclip/interpolations.rb +197 -0
  55. data/lib/paperclip/io_adapters/abstract_adapter.rb +47 -0
  56. data/lib/paperclip/io_adapters/attachment_adapter.rb +36 -0
  57. data/lib/paperclip/io_adapters/data_uri_adapter.rb +22 -0
  58. data/lib/paperclip/io_adapters/empty_string_adapter.rb +18 -0
  59. data/lib/paperclip/io_adapters/file_adapter.rb +22 -0
  60. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +15 -0
  61. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -0
  62. data/lib/paperclip/io_adapters/nil_adapter.rb +34 -0
  63. data/lib/paperclip/io_adapters/registry.rb +32 -0
  64. data/lib/paperclip/io_adapters/stringio_adapter.rb +33 -0
  65. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +42 -0
  66. data/lib/paperclip/io_adapters/uri_adapter.rb +63 -0
  67. data/lib/paperclip/locales/de.yml +18 -0
  68. data/lib/paperclip/locales/en.yml +18 -0
  69. data/lib/paperclip/locales/es.yml +18 -0
  70. data/lib/paperclip/locales/ja.yml +18 -0
  71. data/lib/paperclip/locales/pt-BR.yml +18 -0
  72. data/lib/paperclip/locales/zh-CN.yml +18 -0
  73. data/lib/paperclip/locales/zh-HK.yml +18 -0
  74. data/lib/paperclip/locales/zh-TW.yml +18 -0
  75. data/lib/paperclip/logger.rb +21 -0
  76. data/lib/paperclip/matchers/have_attached_file_matcher.rb +54 -0
  77. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +100 -0
  78. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +59 -0
  79. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +96 -0
  80. data/lib/paperclip/matchers.rb +64 -0
  81. data/lib/paperclip/media_type_spoof_detector.rb +89 -0
  82. data/lib/paperclip/missing_attachment_styles.rb +79 -0
  83. data/lib/paperclip/processor.rb +48 -0
  84. data/lib/paperclip/processor_helpers.rb +50 -0
  85. data/lib/paperclip/rails_environment.rb +25 -0
  86. data/lib/paperclip/railtie.rb +31 -0
  87. data/lib/paperclip/schema.rb +83 -0
  88. data/lib/paperclip/storage/filesystem.rb +90 -0
  89. data/lib/paperclip/storage/fog.rb +241 -0
  90. data/lib/paperclip/storage/s3.rb +440 -0
  91. data/lib/paperclip/storage.rb +3 -0
  92. data/lib/paperclip/style.rb +109 -0
  93. data/lib/paperclip/tempfile.rb +43 -0
  94. data/lib/paperclip/tempfile_factory.rb +23 -0
  95. data/lib/paperclip/thumbnail.rb +121 -0
  96. data/lib/paperclip/url_generator.rb +72 -0
  97. data/lib/paperclip/validators/attachment_content_type_validator.rb +88 -0
  98. data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
  99. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
  100. data/lib/paperclip/validators/attachment_presence_validator.rb +30 -0
  101. data/lib/paperclip/validators/attachment_size_validator.rb +115 -0
  102. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +27 -0
  103. data/lib/paperclip/validators.rb +74 -0
  104. data/lib/paperclip/version.rb +3 -0
  105. data/lib/paperclip.rb +213 -0
  106. data/lib/tasks/paperclip.rake +127 -0
  107. data/paperclip.gemspec +51 -0
  108. data/shoulda_macros/paperclip.rb +134 -0
  109. data/spec/database.yml +4 -0
  110. data/spec/paperclip/attachment_definitions_spec.rb +13 -0
  111. data/spec/paperclip/attachment_processing_spec.rb +82 -0
  112. data/spec/paperclip/attachment_registry_spec.rb +130 -0
  113. data/spec/paperclip/attachment_spec.rb +1494 -0
  114. data/spec/paperclip/content_type_detector_spec.rb +48 -0
  115. data/spec/paperclip/deprecations_spec.rb +65 -0
  116. data/spec/paperclip/file_command_content_type_detector_spec.rb +26 -0
  117. data/spec/paperclip/filename_cleaner_spec.rb +14 -0
  118. data/spec/paperclip/geometry_detector_spec.rb +39 -0
  119. data/spec/paperclip/geometry_parser_spec.rb +73 -0
  120. data/spec/paperclip/geometry_spec.rb +255 -0
  121. data/spec/paperclip/glue_spec.rb +44 -0
  122. data/spec/paperclip/has_attached_file_spec.rb +142 -0
  123. data/spec/paperclip/integration_spec.rb +667 -0
  124. data/spec/paperclip/interpolations_spec.rb +262 -0
  125. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +78 -0
  126. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +139 -0
  127. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +83 -0
  128. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
  129. data/spec/paperclip/io_adapters/file_adapter_spec.rb +131 -0
  130. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +104 -0
  131. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
  132. data/spec/paperclip/io_adapters/nil_adapter_spec.rb +25 -0
  133. data/spec/paperclip/io_adapters/registry_spec.rb +35 -0
  134. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +64 -0
  135. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +146 -0
  136. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +127 -0
  137. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
  138. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +99 -0
  139. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
  140. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
  141. data/spec/paperclip/media_type_spoof_detector_spec.rb +79 -0
  142. data/spec/paperclip/meta_class_spec.rb +30 -0
  143. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
  144. data/spec/paperclip/paperclip_spec.rb +222 -0
  145. data/spec/paperclip/plural_cache_spec.rb +37 -0
  146. data/spec/paperclip/processor_helpers_spec.rb +57 -0
  147. data/spec/paperclip/processor_spec.rb +26 -0
  148. data/spec/paperclip/rails_environment_spec.rb +33 -0
  149. data/spec/paperclip/rake_spec.rb +103 -0
  150. data/spec/paperclip/schema_spec.rb +248 -0
  151. data/spec/paperclip/storage/filesystem_spec.rb +79 -0
  152. data/spec/paperclip/storage/fog_spec.rb +535 -0
  153. data/spec/paperclip/storage/s3_live_spec.rb +182 -0
  154. data/spec/paperclip/storage/s3_spec.rb +1526 -0
  155. data/spec/paperclip/style_spec.rb +255 -0
  156. data/spec/paperclip/tempfile_factory_spec.rb +33 -0
  157. data/spec/paperclip/thumbnail_spec.rb +500 -0
  158. data/spec/paperclip/url_generator_spec.rb +211 -0
  159. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
  160. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
  161. data/spec/paperclip/validators/attachment_presence_validator_spec.rb +85 -0
  162. data/spec/paperclip/validators/attachment_size_validator_spec.rb +229 -0
  163. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +52 -0
  164. data/spec/paperclip/validators_spec.rb +164 -0
  165. data/spec/spec_helper.rb +43 -0
  166. data/spec/support/assertions.rb +71 -0
  167. data/spec/support/deprecations.rb +9 -0
  168. data/spec/support/fake_model.rb +25 -0
  169. data/spec/support/fake_rails.rb +12 -0
  170. data/spec/support/fixtures/12k.png +0 -0
  171. data/spec/support/fixtures/50x50.png +0 -0
  172. data/spec/support/fixtures/5k.png +0 -0
  173. data/spec/support/fixtures/animated +0 -0
  174. data/spec/support/fixtures/animated.gif +0 -0
  175. data/spec/support/fixtures/animated.unknown +0 -0
  176. data/spec/support/fixtures/bad.png +1 -0
  177. data/spec/support/fixtures/empty.html +1 -0
  178. data/spec/support/fixtures/empty.xlsx +0 -0
  179. data/spec/support/fixtures/fog.yml +8 -0
  180. data/spec/support/fixtures/rotated.jpg +0 -0
  181. data/spec/support/fixtures/s3.yml +8 -0
  182. data/spec/support/fixtures/spaced file.jpg +0 -0
  183. data/spec/support/fixtures/spaced file.png +0 -0
  184. data/spec/support/fixtures/text.txt +1 -0
  185. data/spec/support/fixtures/twopage.pdf +0 -0
  186. data/spec/support/fixtures/uppercase.PNG +0 -0
  187. data/spec/support/matchers/accept.rb +5 -0
  188. data/spec/support/matchers/exist.rb +5 -0
  189. data/spec/support/matchers/have_column.rb +23 -0
  190. data/spec/support/mock_attachment.rb +22 -0
  191. data/spec/support/mock_interpolator.rb +24 -0
  192. data/spec/support/mock_url_generator_builder.rb +27 -0
  193. data/spec/support/model_reconstruction.rb +60 -0
  194. data/spec/support/rails_helpers.rb +7 -0
  195. data/spec/support/test_data.rb +13 -0
  196. data/spec/support/version_helper.rb +9 -0
  197. metadata +606 -0
@@ -0,0 +1,229 @@
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.storage_units
16
+ if defined?(ActiveSupport::NumberHelper) # Rails 4.0+
17
+ { 5120 => '5 KB', 10240 => '10 KB' }
18
+ else
19
+ { 5120 => '5120 Bytes', 10240 => '10240 Bytes' }
20
+ end
21
+ end
22
+
23
+ def self.should_allow_attachment_file_size(size)
24
+ context "when the attachment size is #{size}" do
25
+ it "adds error to dummy object" do
26
+ @dummy.stubs(:avatar_file_size).returns(size)
27
+ @validator.validate(@dummy)
28
+ assert @dummy.errors[:avatar_file_size].blank?,
29
+ "Expect an error message on :avatar_file_size, got none."
30
+ end
31
+
32
+ it "does not add error to the base dummy object" do
33
+ assert @dummy.errors[:avatar].blank?,
34
+ "Error added to base attribute"
35
+ end
36
+ end
37
+ end
38
+
39
+ def self.should_not_allow_attachment_file_size(size, options = {})
40
+ context "when the attachment size is #{size}" do
41
+ before do
42
+ @dummy.stubs(:avatar_file_size).returns(size)
43
+ @validator.validate(@dummy)
44
+ end
45
+
46
+ it "adds error to dummy object" do
47
+ assert @dummy.errors[:avatar_file_size].present?,
48
+ "Unexpected error message on :avatar_file_size"
49
+ end
50
+
51
+ it "adds error to the base dummy object" do
52
+ assert @dummy.errors[:avatar].present?,
53
+ "Error not added to base attribute"
54
+ end
55
+
56
+ it "adds error to base object as a string" do
57
+ expect(@dummy.errors[:avatar].first).to be_a String
58
+ end
59
+
60
+ if options[:message]
61
+ it "returns a correct error message" do
62
+ expect(@dummy.errors[:avatar_file_size]).to include options[:message]
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ context "with :in option" do
69
+ context "as a range" do
70
+ before do
71
+ build_validator in: (5.kilobytes..10.kilobytes)
72
+ end
73
+
74
+ should_allow_attachment_file_size(7.kilobytes)
75
+ should_not_allow_attachment_file_size(4.kilobytes)
76
+ should_not_allow_attachment_file_size(11.kilobytes)
77
+ end
78
+
79
+ context "as a proc" do
80
+ before do
81
+ build_validator in: lambda { |avatar| (5.kilobytes..10.kilobytes) }
82
+ end
83
+
84
+ should_allow_attachment_file_size(7.kilobytes)
85
+ should_not_allow_attachment_file_size(4.kilobytes)
86
+ should_not_allow_attachment_file_size(11.kilobytes)
87
+ end
88
+ end
89
+
90
+ context "with :greater_than option" do
91
+ context "as number" do
92
+ before do
93
+ build_validator greater_than: 10.kilobytes
94
+ end
95
+
96
+ should_allow_attachment_file_size 11.kilobytes
97
+ should_not_allow_attachment_file_size 10.kilobytes
98
+ end
99
+
100
+ context "as a proc" do
101
+ before do
102
+ build_validator greater_than: lambda { |avatar| 10.kilobytes }
103
+ end
104
+
105
+ should_allow_attachment_file_size 11.kilobytes
106
+ should_not_allow_attachment_file_size 10.kilobytes
107
+ end
108
+ end
109
+
110
+ context "with :less_than option" do
111
+ context "as number" do
112
+ before do
113
+ build_validator less_than: 10.kilobytes
114
+ end
115
+
116
+ should_allow_attachment_file_size 9.kilobytes
117
+ should_not_allow_attachment_file_size 10.kilobytes
118
+ end
119
+
120
+ context "as a proc" do
121
+ before do
122
+ build_validator less_than: lambda { |avatar| 10.kilobytes }
123
+ end
124
+
125
+ should_allow_attachment_file_size 9.kilobytes
126
+ should_not_allow_attachment_file_size 10.kilobytes
127
+ end
128
+ end
129
+
130
+ context "with :greater_than and :less_than option" do
131
+ context "as numbers" do
132
+ before do
133
+ build_validator greater_than: 5.kilobytes,
134
+ less_than: 10.kilobytes
135
+ end
136
+
137
+ should_allow_attachment_file_size 7.kilobytes
138
+ should_not_allow_attachment_file_size 5.kilobytes
139
+ should_not_allow_attachment_file_size 10.kilobytes
140
+ end
141
+
142
+ context "as a proc" do
143
+ before do
144
+ build_validator greater_than: lambda { |avatar| 5.kilobytes },
145
+ less_than: lambda { |avatar| 10.kilobytes }
146
+ end
147
+
148
+ should_allow_attachment_file_size 7.kilobytes
149
+ should_not_allow_attachment_file_size 5.kilobytes
150
+ should_not_allow_attachment_file_size 10.kilobytes
151
+ end
152
+ end
153
+
154
+ context "with :message option" do
155
+ context "given a range" do
156
+ before do
157
+ build_validator in: (5.kilobytes..10.kilobytes),
158
+ message: "is invalid. (Between %{min} and %{max} please.)"
159
+ end
160
+
161
+ should_not_allow_attachment_file_size 11.kilobytes,
162
+ message: "is invalid. (Between #{storage_units[5120]} and #{storage_units[10240]} please.)"
163
+ end
164
+
165
+ context "given :less_than and :greater_than" do
166
+ before do
167
+ build_validator less_than: 10.kilobytes,
168
+ greater_than: 5.kilobytes,
169
+ message: "is invalid. (Between %{min} and %{max} please.)"
170
+ end
171
+
172
+ should_not_allow_attachment_file_size 11.kilobytes,
173
+ message: "is invalid. (Between #{storage_units[5120]} and #{storage_units[10240]} please.)"
174
+ end
175
+ end
176
+
177
+ context "default error messages" do
178
+ context "given :less_than and :greater_than" do
179
+ before do
180
+ build_validator greater_than: 5.kilobytes,
181
+ less_than: 10.kilobytes
182
+ end
183
+
184
+ should_not_allow_attachment_file_size 11.kilobytes,
185
+ message: "must be less than #{storage_units[10240]}"
186
+ should_not_allow_attachment_file_size 4.kilobytes,
187
+ message: "must be greater than #{storage_units[5120]}"
188
+ end
189
+
190
+ context "given a size range" do
191
+ before do
192
+ build_validator in: (5.kilobytes..10.kilobytes)
193
+ end
194
+
195
+ should_not_allow_attachment_file_size 11.kilobytes,
196
+ message: "must be in between #{storage_units[5120]} and #{storage_units[10240]}"
197
+ should_not_allow_attachment_file_size 4.kilobytes,
198
+ message: "must be in between #{storage_units[5120]} and #{storage_units[10240]}"
199
+ end
200
+ end
201
+
202
+ context "using the helper" do
203
+ before do
204
+ Dummy.validates_attachment_size :avatar, in: (5.kilobytes..10.kilobytes)
205
+ end
206
+
207
+ it "adds the validator to the class" do
208
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_size }
209
+ end
210
+ end
211
+
212
+ context "given options" do
213
+ it "raises argument error if no required argument was given" do
214
+ assert_raises(ArgumentError) do
215
+ build_validator message: "Some message"
216
+ end
217
+ end
218
+
219
+ (Paperclip::Validators::AttachmentSizeValidator::AVAILABLE_CHECKS).each do |argument|
220
+ it "does not raise arguemnt error if #{argument} was given" do
221
+ build_validator argument => 5.kilobytes
222
+ end
223
+ end
224
+
225
+ it "does not raise argument error if :in was given" do
226
+ build_validator in: (5.kilobytes..10.kilobytes)
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,52 @@
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 = mock("detector", :spoofed? => true)
30
+ Paperclip::MediaTypeSpoofDetector.stubs(:using).returns(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
+ Paperclip::MediaTypeSpoofDetector.stubs(:using).returns(stub(:spoofed? => false))
41
+
42
+ @dummy.valid?
43
+
44
+ assert_received(Paperclip::MediaTypeSpoofDetector, :using){|e| e.once }
45
+ end
46
+
47
+ it "does not run when attachment is not dirty" do
48
+ Paperclip::MediaTypeSpoofDetector.stubs(:using).never
49
+ @dummy.valid?
50
+ assert_received(Paperclip::MediaTypeSpoofDetector, :using){|e| e.never }
51
+ end
52
+ end
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::Validators do
4
+ context "using the helper" do
5
+ before do
6
+ Dummy.validates_attachment :avatar, presence: true, content_type: { content_type: "image/jpeg" }, size: { in: 0..10240 }
7
+ end
8
+
9
+ it "adds the attachment_presence validator to the class" do
10
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_presence }
11
+ end
12
+
13
+ it "adds the attachment_content_type validator to the class" do
14
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_content_type }
15
+ end
16
+
17
+ it "adds the attachment_size validator to the class" do
18
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_size }
19
+ end
20
+
21
+ it 'prevents you from attaching a file that violates that validation' do
22
+ Dummy.class_eval{ validate(:name) { raise "DO NOT RUN THIS" } }
23
+ dummy = Dummy.new(avatar: File.new(fixture_file("12k.png")))
24
+ expect(dummy.errors.keys).to match_array [:avatar_content_type, :avatar, :avatar_file_size]
25
+ assert_raises(RuntimeError){ dummy.valid? }
26
+ end
27
+ end
28
+
29
+ context 'using the helper with array of validations' do
30
+ before do
31
+ rebuild_class
32
+ Dummy.validates_attachment :avatar, file_type_ignorance: true, file_name: [
33
+ { matches: /\A.*\.jpe?g\Z/i, message: :invalid_extension },
34
+ { matches: /\A.{,8}\..+\Z/i, message: [:too_long, count: 8] },
35
+ ]
36
+ end
37
+
38
+ it 'adds the attachment_file_name validator to the class' do
39
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_file_name }
40
+ end
41
+
42
+ it 'adds the attachment_file_name validator with two validations' do
43
+ assert_equal 2, Dummy.validators_on(:avatar).select{ |validator| validator.kind == :attachment_file_name }.size
44
+ end
45
+
46
+ it 'prevents you from attaching a file that violates all of these validations' do
47
+ Dummy.class_eval{ validate(:name) { raise 'DO NOT RUN THIS' } }
48
+ dummy = Dummy.new(avatar: File.new(fixture_file('spaced file.png')))
49
+ expect(dummy.errors.keys).to match_array [:avatar, :avatar_file_name]
50
+ assert_raises(RuntimeError){ dummy.valid? }
51
+ end
52
+
53
+ it 'prevents you from attaching a file that violates only first of these validations' do
54
+ Dummy.class_eval{ validate(:name) { raise 'DO NOT RUN THIS' } }
55
+ dummy = Dummy.new(avatar: File.new(fixture_file('5k.png')))
56
+ expect(dummy.errors.keys).to match_array [:avatar, :avatar_file_name]
57
+ assert_raises(RuntimeError){ dummy.valid? }
58
+ end
59
+
60
+ it 'prevents you from attaching a file that violates only second of these validations' do
61
+ Dummy.class_eval{ validate(:name) { raise 'DO NOT RUN THIS' } }
62
+ dummy = Dummy.new(avatar: File.new(fixture_file('spaced file.jpg')))
63
+ expect(dummy.errors.keys).to match_array [:avatar, :avatar_file_name]
64
+ assert_raises(RuntimeError){ dummy.valid? }
65
+ end
66
+
67
+ it 'allows you to attach a file that does not violates these validations' do
68
+ dummy = Dummy.new(avatar: File.new(fixture_file('rotated.jpg')))
69
+ expect(dummy.errors.keys).to match_array []
70
+ assert dummy.valid?
71
+ end
72
+
73
+ end
74
+
75
+ context "using the helper with a conditional" do
76
+ before do
77
+ rebuild_class
78
+ Dummy.validates_attachment :avatar, presence: true,
79
+ content_type: { content_type: "image/jpeg" },
80
+ size: { in: 0..10240 },
81
+ if: :title_present?
82
+ end
83
+
84
+ it "validates the attachment if title is present" do
85
+ Dummy.class_eval do
86
+ def title_present?
87
+ true
88
+ end
89
+ end
90
+ dummy = Dummy.new(avatar: File.new(fixture_file("12k.png")))
91
+ expect(dummy.errors.keys).to match_array [:avatar_content_type, :avatar, :avatar_file_size]
92
+ end
93
+
94
+ it "does not validate attachment if title is not present" do
95
+ Dummy.class_eval do
96
+ def title_present?
97
+ false
98
+ end
99
+ end
100
+ dummy = Dummy.new(avatar: File.new(fixture_file("12k.png")))
101
+ assert_equal [], dummy.errors.keys
102
+ end
103
+ end
104
+
105
+ context 'with no other validations on the Dummy#avatar attachment' do
106
+ before do
107
+ reset_class("Dummy")
108
+ Dummy.has_attached_file :avatar
109
+ Paperclip.reset_duplicate_clash_check!
110
+ end
111
+
112
+ it 'raises an error when no content_type validation exists' do
113
+ assert_raises(Paperclip::Errors::MissingRequiredValidatorError) do
114
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
115
+ end
116
+ end
117
+
118
+ it 'does not raise an error when a content_type validation exists' do
119
+ Dummy.validates_attachment :avatar, content_type: { content_type: "image/jpeg" }
120
+
121
+ assert_nothing_raised do
122
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
123
+ end
124
+ end
125
+
126
+ it 'does not raise an error when a content_type validation exists using validates_with' do
127
+ Dummy.validates_with Paperclip::Validators::AttachmentContentTypeValidator, attributes: :attachment, content_type: 'images/jpeg'
128
+
129
+ assert_nothing_raised do
130
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
131
+ end
132
+ end
133
+
134
+ it 'does not raise an error when an inherited validator is used' do
135
+ class MyValidator < Paperclip::Validators::AttachmentContentTypeValidator
136
+ def initialize(options)
137
+ options[:content_type] = "images/jpeg" unless options.has_key?(:content_type)
138
+ super
139
+ end
140
+ end
141
+ Dummy.validates_with MyValidator, attributes: :attachment
142
+
143
+ assert_nothing_raised do
144
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
145
+ end
146
+ end
147
+
148
+ it 'does not raise an error when a file_name validation exists' do
149
+ Dummy.validates_attachment :avatar, file_name: { matches: /png$/ }
150
+
151
+ assert_nothing_raised do
152
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
153
+ end
154
+ end
155
+
156
+ it 'does not raise an error when a the validation has been explicitly rejected' do
157
+ Dummy.validates_attachment :avatar, file_type_ignorance: true
158
+
159
+ assert_nothing_raised do
160
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'active_record'
4
+ require 'active_record/version'
5
+ require 'active_support'
6
+ require 'active_support/core_ext'
7
+ require 'mocha/api'
8
+ require 'bourne'
9
+ require 'ostruct'
10
+
11
+ ROOT = Pathname(File.expand_path(File.join(File.dirname(__FILE__), '..')))
12
+
13
+ puts "Testing against version #{ActiveRecord::VERSION::STRING}"
14
+
15
+ $LOAD_PATH << File.join(ROOT, 'lib')
16
+ $LOAD_PATH << File.join(ROOT, 'lib', 'paperclip')
17
+ require File.join(ROOT, 'lib', 'paperclip.rb')
18
+
19
+ FIXTURES_DIR = File.join(File.dirname(__FILE__), "fixtures")
20
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
21
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
22
+ ActiveRecord::Base.establish_connection(config['test'])
23
+ unless ActiveRecord::VERSION::STRING < "4.2"
24
+ ActiveRecord::Base.raise_in_transactional_callbacks = true
25
+ end
26
+ Paperclip.options[:logger] = ActiveRecord::Base.logger
27
+
28
+ Dir[File.join(ROOT, 'spec', 'support', '**', '*.rb')].each{|f| require f }
29
+
30
+ Rails = FakeRails.new('test', Pathname.new(ROOT).join('tmp'))
31
+ ActiveSupport::Deprecation.silenced = true
32
+
33
+ RSpec.configure do |config|
34
+ config.include Assertions
35
+ config.include ModelReconstruction
36
+ config.include TestData
37
+ config.extend VersionHelper
38
+ config.extend RailsHelpers::ClassMethods
39
+ config.mock_framework = :mocha
40
+ config.before(:all) do
41
+ rebuild_model
42
+ end
43
+ end
@@ -0,0 +1,71 @@
1
+ module Assertions
2
+ def assert(truthy, message = nil)
3
+ expect(!!truthy).to(eq(true), message)
4
+ end
5
+
6
+ def assert_equal(expected, actual, message = nil)
7
+ expect(actual).to(eq(expected), message)
8
+ end
9
+
10
+ def assert_not_equal(expected, actual, message = nil)
11
+ expect(actual).to_not(eq(expected), message)
12
+ end
13
+
14
+ def assert_raises(exception_class, message = nil, &block)
15
+ expect(&block).to raise_error(exception_class, message)
16
+ end
17
+
18
+ def assert_nothing_raised(&block)
19
+ expect(&block).to_not raise_error
20
+ end
21
+
22
+ def assert_nil(thing)
23
+ expect(thing).to be_nil
24
+ end
25
+
26
+ def assert_contains(haystack, needle)
27
+ expect(haystack).to include(needle)
28
+ end
29
+
30
+ def assert_match(pattern, value)
31
+ expect(value).to match(pattern)
32
+ end
33
+
34
+ def assert_no_match(pattern, value)
35
+ expect(value).to_not match(pattern)
36
+ end
37
+
38
+ def assert_file_exists(path_to_file)
39
+ expect(path_to_file).to exist
40
+ end
41
+
42
+ def assert_file_not_exists(path_to_file)
43
+ expect(path_to_file).to_not exist
44
+ end
45
+
46
+ def assert_empty(object)
47
+ expect(object).to be_empty
48
+ end
49
+
50
+ def assert_success_response(url)
51
+ Net::HTTP.get_response(URI.parse(url)) do |response|
52
+ assert_equal "200", response.code,
53
+ "Expected HTTP response code 200, got #{response.code}"
54
+ end
55
+ end
56
+
57
+ def assert_not_found_response(url)
58
+ Net::HTTP.get_response(URI.parse(url)) do |response|
59
+ assert_equal "404", response.code,
60
+ "Expected HTTP response code 404, got #{response.code}"
61
+ end
62
+ end
63
+
64
+ def assert_frame_dimensions(range, frames)
65
+ frames.each_with_index do |frame, frame_index|
66
+ frame.split('x').each_with_index do |dimension, dimension_index |
67
+ assert range.include?(dimension.to_i), "Frame #{frame_index}[#{dimension_index}] should have been within #{range.inspect}, but was #{dimension}"
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,9 @@
1
+ RSpec.configure do |config|
2
+ config.before(:all) do
3
+ ActiveSupport::Deprecation.silenced = true
4
+ end
5
+ config.before(:each) do
6
+ Paperclip::Deprecations.stubs(:active_model_version).returns("4.2")
7
+ Paperclip::Deprecations.stubs(:aws_sdk_version).returns("2.0.0")
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ class FakeModel
2
+ attr_accessor(
3
+ :avatar_file_name,
4
+ :avatar_file_size,
5
+ :avatar_updated_at,
6
+ :avatar_content_type,
7
+ :avatar_fingerprint,
8
+ :id
9
+ )
10
+
11
+ def errors
12
+ @errors ||= []
13
+ end
14
+
15
+ def run_paperclip_callbacks name, *args
16
+ end
17
+
18
+ def valid?
19
+ errors.empty?
20
+ end
21
+
22
+ def new_record?
23
+ false
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ class FakeRails
2
+ def initialize(env, root)
3
+ @env = env
4
+ @root = root
5
+ end
6
+
7
+ attr_accessor :env, :root
8
+
9
+ def const_defined?(const)
10
+ false
11
+ end
12
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ This is not an image.
@@ -0,0 +1 @@
1
+ <html></html>
Binary file
@@ -0,0 +1,8 @@
1
+ development:
2
+ provider: AWS
3
+ aws_access_key_id: AWS_ID
4
+ aws_secret_access_key: AWS_SECRET
5
+ test:
6
+ provider: AWS
7
+ aws_access_key_id: AWS_ID
8
+ aws_secret_access_key: AWS_SECRET
Binary file
@@ -0,0 +1,8 @@
1
+ development:
2
+ key: 54321
3
+ production:
4
+ key: 12345
5
+ test:
6
+ bucket: <%= ENV['S3_BUCKET'] %>
7
+ access_key_id: <%= ENV['S3_KEY'] %>
8
+ secret_access_key: <%= ENV['S3_SECRET'] %>
@@ -0,0 +1 @@
1
+ paperclip!
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ RSpec::Matchers.define :accept do |expected|
2
+ match do |actual|
3
+ actual.matches?(expected)
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ RSpec::Matchers.define :exist do |expected|
2
+ match do |actual|
3
+ File.exist?(actual)
4
+ end
5
+ end