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,262 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::Interpolations do
4
+ it "returns all methods but the infrastructure when sent #all" do
5
+ methods = Paperclip::Interpolations.all
6
+ assert ! methods.include?(:[])
7
+ assert ! methods.include?(:[]=)
8
+ assert ! methods.include?(:all)
9
+ methods.each do |m|
10
+ assert Paperclip::Interpolations.respond_to?(m)
11
+ end
12
+ end
13
+
14
+ it "returns the Rails.root" do
15
+ assert_equal Rails.root, Paperclip::Interpolations.rails_root(:attachment, :style)
16
+ end
17
+
18
+ it "returns the Rails.env" do
19
+ assert_equal Rails.env, Paperclip::Interpolations.rails_env(:attachment, :style)
20
+ end
21
+
22
+ it "returns the class of the Interpolations module when called with no params" do
23
+ assert_equal Module, Paperclip::Interpolations.class
24
+ end
25
+
26
+ it "returns the class of the instance" do
27
+ class Thing ; end
28
+ attachment = mock
29
+ attachment.expects(:instance).returns(attachment)
30
+ attachment.expects(:class).returns(Thing)
31
+ assert_equal "things", Paperclip::Interpolations.class(attachment, :style)
32
+ end
33
+
34
+ it "returns the basename of the file" do
35
+ attachment = mock
36
+ attachment.expects(:original_filename).returns("one.jpg").times(1)
37
+ assert_equal "one", Paperclip::Interpolations.basename(attachment, :style)
38
+ end
39
+
40
+ it "returns the extension of the file" do
41
+ attachment = mock
42
+ attachment.expects(:original_filename).returns("one.jpg")
43
+ attachment.expects(:styles).returns({})
44
+ assert_equal "jpg", Paperclip::Interpolations.extension(attachment, :style)
45
+ end
46
+
47
+ it "returns the extension of the file as the format if defined in the style" do
48
+ attachment = mock
49
+ attachment.expects(:original_filename).never
50
+ attachment.expects(:styles).twice.returns({style: {format: "png"}})
51
+
52
+ [:style, 'style'].each do |style|
53
+ assert_equal "png", Paperclip::Interpolations.extension(attachment, style)
54
+ end
55
+ end
56
+
57
+ it "returns the extension of the file based on the content type" do
58
+ attachment = mock
59
+ attachment.expects(:content_type).returns('image/png')
60
+ attachment.expects(:styles).returns({})
61
+ interpolations = Paperclip::Interpolations
62
+ interpolations.expects(:extension).returns('random')
63
+ assert_equal "png", interpolations.content_type_extension(attachment, :style)
64
+ end
65
+
66
+ it "returns the original extension of the file if it matches a content type extension" do
67
+ attachment = mock
68
+ attachment.expects(:content_type).returns('image/jpeg')
69
+ attachment.expects(:styles).returns({})
70
+ interpolations = Paperclip::Interpolations
71
+ interpolations.expects(:extension).returns('jpe')
72
+ assert_equal "jpe", interpolations.content_type_extension(attachment, :style)
73
+ end
74
+
75
+ it "returns the extension of the file with a dot" do
76
+ attachment = mock
77
+ attachment.expects(:original_filename).returns("one.jpg")
78
+ attachment.expects(:styles).returns({})
79
+ assert_equal ".jpg", Paperclip::Interpolations.dotextension(attachment, :style)
80
+ end
81
+
82
+ it "returns the extension of the file without a dot if the extension is empty" do
83
+ attachment = mock
84
+ attachment.expects(:original_filename).returns("one")
85
+ attachment.expects(:styles).returns({})
86
+ assert_equal "", Paperclip::Interpolations.dotextension(attachment, :style)
87
+ end
88
+
89
+ it "returns the latter half of the content type of the extension if no match found" do
90
+ attachment = mock
91
+ attachment.expects(:content_type).at_least_once().returns('not/found')
92
+ attachment.expects(:styles).returns({})
93
+ interpolations = Paperclip::Interpolations
94
+ interpolations.expects(:extension).returns('random')
95
+ assert_equal "found", interpolations.content_type_extension(attachment, :style)
96
+ end
97
+
98
+ it "returns the format if defined in the style, ignoring the content type" do
99
+ attachment = mock
100
+ attachment.expects(:content_type).returns('image/jpeg')
101
+ attachment.expects(:styles).returns({style: {format: "png"}})
102
+ interpolations = Paperclip::Interpolations
103
+ interpolations.expects(:extension).returns('random')
104
+ assert_equal "png", interpolations.content_type_extension(attachment, :style)
105
+ end
106
+
107
+ it "is able to handle numeric style names" do
108
+ attachment = mock(
109
+ styles: {:"4" => {format: :expected_extension}}
110
+ )
111
+ assert_equal :expected_extension, Paperclip::Interpolations.extension(attachment, 4)
112
+ end
113
+
114
+ it "returns the #to_param of the attachment" do
115
+ attachment = mock
116
+ attachment.expects(:to_param).returns("23-awesome")
117
+ attachment.expects(:instance).returns(attachment)
118
+ assert_equal "23-awesome", Paperclip::Interpolations.param(attachment, :style)
119
+ end
120
+
121
+ it "returns the id of the attachment" do
122
+ attachment = mock
123
+ attachment.expects(:id).returns(23)
124
+ attachment.expects(:instance).returns(attachment)
125
+ assert_equal 23, Paperclip::Interpolations.id(attachment, :style)
126
+ end
127
+
128
+ it "returns nil for attachments to new records" do
129
+ attachment = mock
130
+ attachment.expects(:id).returns(nil)
131
+ attachment.expects(:instance).returns(attachment)
132
+ assert_nil Paperclip::Interpolations.id(attachment, :style)
133
+ end
134
+
135
+ it "returns the partitioned id of the attachment when the id is an integer" do
136
+ attachment = mock
137
+ attachment.expects(:id).returns(23)
138
+ attachment.expects(:instance).returns(attachment)
139
+ assert_equal "000/000/023", Paperclip::Interpolations.id_partition(attachment, :style)
140
+ end
141
+
142
+ it "returns the partitioned id of the attachment when the id is a string" do
143
+ attachment = mock
144
+ attachment.expects(:id).returns("32fnj23oio2f")
145
+ attachment.expects(:instance).returns(attachment)
146
+ assert_equal "32f/nj2/3oi", Paperclip::Interpolations.id_partition(attachment, :style)
147
+ end
148
+
149
+ it "returns nil for the partitioned id of an attachment to a new record (when the id is nil)" do
150
+ attachment = mock
151
+ attachment.expects(:id).returns(nil)
152
+ attachment.expects(:instance).returns(attachment)
153
+ assert_nil Paperclip::Interpolations.id_partition(attachment, :style)
154
+ end
155
+
156
+ it "returns the name of the attachment" do
157
+ attachment = mock
158
+ attachment.expects(:name).returns("file")
159
+ assert_equal "files", Paperclip::Interpolations.attachment(attachment, :style)
160
+ end
161
+
162
+ it "returns the style" do
163
+ assert_equal :style, Paperclip::Interpolations.style(:attachment, :style)
164
+ end
165
+
166
+ it "returns the default style" do
167
+ attachment = mock
168
+ attachment.expects(:default_style).returns(:default_style)
169
+ assert_equal :default_style, Paperclip::Interpolations.style(attachment, nil)
170
+ end
171
+
172
+ it "reinterpolates :url" do
173
+ attachment = mock
174
+ attachment.expects(:url).with(:style, timestamp: false, escape: false).returns("1234")
175
+ assert_equal "1234", Paperclip::Interpolations.url(attachment, :style)
176
+ end
177
+
178
+ it "raises if infinite loop detcted reinterpolating :url" do
179
+ attachment = Object.new
180
+ class << attachment
181
+ def url(*args)
182
+ Paperclip::Interpolations.url(self, :style)
183
+ end
184
+ end
185
+ assert_raises(Paperclip::Errors::InfiniteInterpolationError){ Paperclip::Interpolations.url(attachment, :style) }
186
+ end
187
+
188
+ it "returns the filename as basename.extension" do
189
+ attachment = mock
190
+ attachment.expects(:styles).returns({})
191
+ attachment.expects(:original_filename).returns("one.jpg").times(2)
192
+ assert_equal "one.jpg", Paperclip::Interpolations.filename(attachment, :style)
193
+ end
194
+
195
+ it "returns the filename as basename.extension when format supplied" do
196
+ attachment = mock
197
+ attachment.expects(:styles).returns({style: {format: :png}})
198
+ attachment.expects(:original_filename).returns("one.jpg").times(1)
199
+ assert_equal "one.png", Paperclip::Interpolations.filename(attachment, :style)
200
+ end
201
+
202
+ it "returns the filename as basename when extension is blank" do
203
+ attachment = mock
204
+ attachment.stubs(:styles).returns({})
205
+ attachment.stubs(:original_filename).returns("one")
206
+ assert_equal "one", Paperclip::Interpolations.filename(attachment, :style)
207
+ end
208
+
209
+ it "returns the basename when the extension contains regexp special characters" do
210
+ attachment = mock
211
+ attachment.stubs(:styles).returns({})
212
+ attachment.stubs(:original_filename).returns("one.ab)")
213
+ assert_equal "one", Paperclip::Interpolations.basename(attachment, :style)
214
+ end
215
+
216
+ it "returns the timestamp" do
217
+ now = Time.now
218
+ zone = 'UTC'
219
+ attachment = mock
220
+ attachment.expects(:instance_read).with(:updated_at).returns(now)
221
+ attachment.expects(:time_zone).returns(zone)
222
+ assert_equal now.in_time_zone(zone).to_s, Paperclip::Interpolations.timestamp(attachment, :style)
223
+ end
224
+
225
+ it "returns updated_at" do
226
+ attachment = mock
227
+ seconds_since_epoch = 1234567890
228
+ attachment.expects(:updated_at).returns(seconds_since_epoch)
229
+ assert_equal seconds_since_epoch, Paperclip::Interpolations.updated_at(attachment, :style)
230
+ end
231
+
232
+ it "returns attachment's hash when passing both arguments" do
233
+ attachment = mock
234
+ fake_hash = "a_wicked_secure_hash"
235
+ attachment.expects(:hash_key).returns(fake_hash)
236
+ assert_equal fake_hash, Paperclip::Interpolations.hash(attachment, :style)
237
+ end
238
+
239
+ it "returns Object#hash when passing no argument" do
240
+ attachment = mock
241
+ fake_hash = "a_wicked_secure_hash"
242
+ attachment.expects(:hash_key).never.returns(fake_hash)
243
+ assert_not_equal fake_hash, Paperclip::Interpolations.hash
244
+ end
245
+
246
+ it "calls all expected interpolations with the given arguments" do
247
+ Paperclip::Interpolations.expects(:id).with(:attachment, :style).returns(1234)
248
+ Paperclip::Interpolations.expects(:attachment).with(:attachment, :style).returns("attachments")
249
+ Paperclip::Interpolations.expects(:notreal).never
250
+ value = Paperclip::Interpolations.interpolate(":notreal/:id/:attachment", :attachment, :style)
251
+ assert_equal ":notreal/1234/attachments", value
252
+ end
253
+
254
+ it "handles question marks" do
255
+ Paperclip.interpolates :foo? do
256
+ "bar"
257
+ end
258
+ Paperclip::Interpolations.expects(:fool).never
259
+ value = Paperclip::Interpolations.interpolate(":fo/:foo?")
260
+ assert_equal ":fo/bar", value
261
+ end
262
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::AbstractAdapter do
4
+ class TestAdapter < Paperclip::AbstractAdapter
5
+ attr_accessor :tempfile
6
+
7
+ def content_type
8
+ Paperclip::ContentTypeDetector.new(path).detect
9
+ end
10
+ end
11
+
12
+ context "content type from file contents" do
13
+ before do
14
+ @adapter = TestAdapter.new
15
+ @adapter.stubs(:path).returns("image.png")
16
+ Paperclip.stubs(:run).returns("image/png\n")
17
+ Paperclip::ContentTypeDetector.any_instance.stubs(:type_from_mime_magic).returns("image/png")
18
+ end
19
+
20
+ it "returns the content type without newline" do
21
+ assert_equal "image/png", @adapter.content_type
22
+ end
23
+ end
24
+
25
+ context "nil?" do
26
+ it "returns false" do
27
+ assert !TestAdapter.new.nil?
28
+ end
29
+ end
30
+
31
+ context "delegation" do
32
+ before do
33
+ @adapter = TestAdapter.new
34
+ @adapter.tempfile = stub("Tempfile")
35
+ end
36
+
37
+ [:binmode, :binmode?, :close, :close!, :closed?, :eof?, :path, :rewind, :unlink].each do |method|
38
+ it "delegates #{method} to @tempfile" do
39
+ @adapter.tempfile.stubs(method)
40
+ @adapter.public_send(method)
41
+ assert_received @adapter.tempfile, method
42
+ end
43
+ end
44
+ end
45
+
46
+ it 'gets rid of slashes and colons in filenames' do
47
+ @adapter = TestAdapter.new
48
+ @adapter.original_filename = "awesome/file:name.png"
49
+
50
+ assert_equal "awesome_file_name.png", @adapter.original_filename
51
+ end
52
+
53
+ it 'is an assignment' do
54
+ assert TestAdapter.new.assignment?
55
+ end
56
+
57
+ it 'is not nil' do
58
+ assert !TestAdapter.new.nil?
59
+ end
60
+
61
+ it "generates a destination filename with no original filename" do
62
+ @adapter = TestAdapter.new
63
+ expect(@adapter.send(:destination).path).to_not be_nil
64
+ end
65
+
66
+ it 'uses the original filename to generate the tempfile' do
67
+ @adapter = TestAdapter.new
68
+ @adapter.original_filename = "file.png"
69
+ expect(@adapter.send(:destination).path).to end_with(".png")
70
+ end
71
+
72
+ context "#original_filename=" do
73
+ it "should not fail with a nil original filename" do
74
+ adapter = TestAdapter.new
75
+ expect{ adapter.original_filename = nil }.not_to raise_error
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::AttachmentAdapter do
4
+ before do
5
+ rebuild_model path: "tmp/:class/:attachment/:style/:filename", styles: {thumb: '50x50'}
6
+ @attachment = Dummy.new.avatar
7
+ end
8
+
9
+ context "for an attachment" do
10
+ before do
11
+ @file = File.new(fixture_file("5k.png"))
12
+ @file.binmode
13
+
14
+ @attachment.assign(@file)
15
+ @attachment.save
16
+ @subject = Paperclip.io_adapters.for(@attachment)
17
+ end
18
+
19
+ after do
20
+ @file.close
21
+ @subject.close
22
+ end
23
+
24
+ it "gets the right filename" do
25
+ assert_equal "5k.png", @subject.original_filename
26
+ end
27
+
28
+ it "forces binmode on tempfile" do
29
+ assert @subject.instance_variable_get("@tempfile").binmode?
30
+ end
31
+
32
+ it "gets the content type" do
33
+ assert_equal "image/png", @subject.content_type
34
+ end
35
+
36
+ it "gets the file's size" do
37
+ assert_equal 4456, @subject.size
38
+ end
39
+
40
+ it "returns false for a call to nil?" do
41
+ assert ! @subject.nil?
42
+ end
43
+
44
+ it "generates a MD5 hash of the contents" do
45
+ expected = Digest::MD5.file(@file.path).to_s
46
+ assert_equal expected, @subject.fingerprint
47
+ end
48
+
49
+ it "reads the contents of the file" do
50
+ expected = @file.read
51
+ actual = @subject.read
52
+ assert expected.length > 0
53
+ assert_equal expected.length, actual.length
54
+ assert_equal expected, actual
55
+ end
56
+
57
+ end
58
+
59
+ context "for a file with restricted characters in the name" do
60
+ before do
61
+ file_contents = IO.read(fixture_file("animated.gif"))
62
+ @file = StringIO.new(file_contents)
63
+ @file.stubs(:original_filename).returns('image:restricted.gif')
64
+ @file.binmode
65
+
66
+ @attachment.assign(@file)
67
+ @attachment.save
68
+ @subject = Paperclip.io_adapters.for(@attachment)
69
+ end
70
+
71
+ after do
72
+ @subject.close
73
+ end
74
+
75
+ it "does not generate paths that include restricted characters" do
76
+ expect(@subject.path).to_not match(/:/)
77
+ end
78
+
79
+ it "does not generate filenames that include restricted characters" do
80
+ assert_equal 'image_restricted.gif', @subject.original_filename
81
+ end
82
+ end
83
+
84
+ context "for a style" do
85
+ before do
86
+ @file = File.new(fixture_file("5k.png"))
87
+ @file.binmode
88
+
89
+ @attachment.assign(@file)
90
+
91
+ @thumb = Tempfile.new("thumbnail").tap(&:binmode)
92
+ FileUtils.cp @attachment.queued_for_write[:thumb].path, @thumb.path
93
+
94
+ @attachment.save
95
+ @subject = Paperclip.io_adapters.for(@attachment.styles[:thumb])
96
+ end
97
+
98
+ after do
99
+ @file.close
100
+ @thumb.close
101
+ @subject.close
102
+ end
103
+
104
+ it "gets the original filename" do
105
+ assert_equal "5k.png", @subject.original_filename
106
+ end
107
+
108
+ it "forces binmode on tempfile" do
109
+ assert @subject.instance_variable_get("@tempfile").binmode?
110
+ end
111
+
112
+ it "gets the content type" do
113
+ assert_equal "image/png", @subject.content_type
114
+ end
115
+
116
+ it "gets the thumbnail's file size" do
117
+ assert_equal @thumb.size, @subject.size
118
+ end
119
+
120
+ it "returns false for a call to nil?" do
121
+ assert ! @subject.nil?
122
+ end
123
+
124
+ it "generates a MD5 hash of the contents" do
125
+ expected = Digest::MD5.file(@thumb.path).to_s
126
+ assert_equal expected, @subject.fingerprint
127
+ end
128
+
129
+ it "reads the contents of the thumbnail" do
130
+ @thumb.rewind
131
+ expected = @thumb.read
132
+ actual = @subject.read
133
+ assert expected.length > 0
134
+ assert_equal expected.length, actual.length
135
+ assert_equal expected, actual
136
+ end
137
+
138
+ end
139
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::DataUriAdapter do
4
+ after do
5
+ if @subject
6
+ @subject.close
7
+ end
8
+ end
9
+
10
+ it 'allows a missing mime-type' do
11
+ adapter = Paperclip.io_adapters.for("data:;base64,#{original_base64_content}")
12
+ assert_equal Paperclip::DataUriAdapter, adapter.class
13
+ end
14
+
15
+ it 'alows mime type that has dot in it' do
16
+ adapter = Paperclip.io_adapters.for("data:image/vnd.microsoft.icon;base64,#{original_base64_content}")
17
+ assert_equal Paperclip::DataUriAdapter, adapter.class
18
+ end
19
+
20
+ context "a new instance" do
21
+ before do
22
+ @contents = "data:image/png;base64,#{original_base64_content}"
23
+ @subject = Paperclip.io_adapters.for(@contents)
24
+ end
25
+
26
+ it "returns a nondescript file name" do
27
+ assert_equal "data", @subject.original_filename
28
+ end
29
+
30
+ it "returns a content type" do
31
+ assert_equal "image/png", @subject.content_type
32
+ end
33
+
34
+ it "returns the size of the data" do
35
+ assert_equal 4456, @subject.size
36
+ end
37
+
38
+ it "generates a correct MD5 hash of the contents" do
39
+ assert_equal(
40
+ Digest::MD5.hexdigest(Base64.decode64(original_base64_content)),
41
+ @subject.fingerprint
42
+ )
43
+ end
44
+
45
+ it "generates correct fingerprint after read" do
46
+ fingerprint = Digest::MD5.hexdigest(@subject.read)
47
+ assert_equal fingerprint, @subject.fingerprint
48
+ end
49
+
50
+ it "generates same fingerprint" do
51
+ assert_equal @subject.fingerprint, @subject.fingerprint
52
+ end
53
+
54
+ it 'accepts a content_type' do
55
+ @subject.content_type = 'image/png'
56
+ assert_equal 'image/png', @subject.content_type
57
+ end
58
+
59
+ it 'accepts an original_filename' do
60
+ @subject.original_filename = 'image.png'
61
+ assert_equal 'image.png', @subject.original_filename
62
+ end
63
+
64
+ it "does not generate filenames that include restricted characters" do
65
+ @subject.original_filename = 'image:restricted.png'
66
+ assert_equal 'image_restricted.png', @subject.original_filename
67
+ end
68
+
69
+ it "does not generate paths that include restricted characters" do
70
+ @subject.original_filename = 'image:restricted.png'
71
+ expect(@subject.path).to_not match(/:/)
72
+ end
73
+
74
+ end
75
+
76
+ def original_base64_content
77
+ Base64.encode64(original_file_contents)
78
+ end
79
+
80
+ def original_file_contents
81
+ @original_file_contents ||= File.read(fixture_file('5k.png'))
82
+ end
83
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::EmptyStringAdapter do
4
+ context 'a new instance' do
5
+ before do
6
+ @subject = Paperclip.io_adapters.for('')
7
+ end
8
+
9
+ it "returns false for a call to nil?" do
10
+ assert !@subject.nil?
11
+ end
12
+
13
+ it 'returns false for a call to assignment?' do
14
+ assert !@subject.assignment?
15
+ end
16
+ end
17
+ end