kt-paperclip 6.2.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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +17 -0
- data/.github/issue_template.md +3 -0
- data/.gitignore +19 -0
- data/.hound.yml +1050 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +47 -0
- data/Appraisals +24 -0
- data/CONTRIBUTING.md +86 -0
- data/Gemfile +18 -0
- data/LICENSE +24 -0
- data/NEWS +515 -0
- data/README.md +1053 -0
- data/RELEASING.md +17 -0
- data/Rakefile +52 -0
- data/UPGRADING +17 -0
- data/features/basic_integration.feature +85 -0
- data/features/migration.feature +29 -0
- data/features/rake_tasks.feature +62 -0
- data/features/step_definitions/attachment_steps.rb +110 -0
- data/features/step_definitions/html_steps.rb +15 -0
- data/features/step_definitions/rails_steps.rb +257 -0
- data/features/step_definitions/s3_steps.rb +14 -0
- data/features/step_definitions/web_steps.rb +106 -0
- data/features/support/env.rb +12 -0
- data/features/support/fakeweb.rb +11 -0
- data/features/support/file_helpers.rb +34 -0
- data/features/support/fixtures/boot_config.txt +15 -0
- data/features/support/fixtures/gemfile.txt +5 -0
- data/features/support/fixtures/preinitializer.txt +20 -0
- data/features/support/paths.rb +28 -0
- data/features/support/rails.rb +39 -0
- data/features/support/selectors.rb +19 -0
- data/gemfiles/4.2.gemfile +20 -0
- data/gemfiles/5.0.gemfile +20 -0
- data/gemfiles/5.1.gemfile +20 -0
- data/gemfiles/5.2.gemfile +20 -0
- data/gemfiles/6.0.gemfile +20 -0
- data/lib/generators/paperclip/USAGE +8 -0
- data/lib/generators/paperclip/paperclip_generator.rb +36 -0
- data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +15 -0
- data/lib/paperclip.rb +215 -0
- data/lib/paperclip/attachment.rb +617 -0
- data/lib/paperclip/attachment_registry.rb +60 -0
- data/lib/paperclip/callbacks.rb +42 -0
- data/lib/paperclip/content_type_detector.rb +80 -0
- data/lib/paperclip/errors.rb +34 -0
- data/lib/paperclip/file_command_content_type_detector.rb +28 -0
- data/lib/paperclip/filename_cleaner.rb +15 -0
- data/lib/paperclip/geometry.rb +157 -0
- data/lib/paperclip/geometry_detector_factory.rb +45 -0
- data/lib/paperclip/geometry_parser_factory.rb +31 -0
- data/lib/paperclip/glue.rb +17 -0
- data/lib/paperclip/has_attached_file.rb +116 -0
- data/lib/paperclip/helpers.rb +60 -0
- data/lib/paperclip/interpolations.rb +201 -0
- data/lib/paperclip/interpolations/plural_cache.rb +18 -0
- data/lib/paperclip/io_adapters/abstract_adapter.rb +75 -0
- data/lib/paperclip/io_adapters/attachment_adapter.rb +47 -0
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +22 -0
- data/lib/paperclip/io_adapters/empty_string_adapter.rb +19 -0
- data/lib/paperclip/io_adapters/file_adapter.rb +26 -0
- data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +16 -0
- data/lib/paperclip/io_adapters/identity_adapter.rb +17 -0
- data/lib/paperclip/io_adapters/nil_adapter.rb +37 -0
- data/lib/paperclip/io_adapters/registry.rb +36 -0
- data/lib/paperclip/io_adapters/stringio_adapter.rb +36 -0
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +44 -0
- data/lib/paperclip/io_adapters/uri_adapter.rb +68 -0
- data/lib/paperclip/locales/en.yml +18 -0
- data/lib/paperclip/logger.rb +21 -0
- data/lib/paperclip/matchers.rb +64 -0
- data/lib/paperclip/matchers/have_attached_file_matcher.rb +54 -0
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +101 -0
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +59 -0
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +97 -0
- data/lib/paperclip/media_type_spoof_detector.rb +90 -0
- data/lib/paperclip/missing_attachment_styles.rb +84 -0
- data/lib/paperclip/processor.rb +56 -0
- data/lib/paperclip/processor_helpers.rb +52 -0
- data/lib/paperclip/rails_environment.rb +21 -0
- data/lib/paperclip/railtie.rb +31 -0
- data/lib/paperclip/schema.rb +81 -0
- data/lib/paperclip/storage.rb +3 -0
- data/lib/paperclip/storage/filesystem.rb +99 -0
- data/lib/paperclip/storage/fog.rb +252 -0
- data/lib/paperclip/storage/s3.rb +461 -0
- data/lib/paperclip/style.rb +106 -0
- data/lib/paperclip/tempfile.rb +42 -0
- data/lib/paperclip/tempfile_factory.rb +22 -0
- data/lib/paperclip/thumbnail.rb +131 -0
- data/lib/paperclip/url_generator.rb +76 -0
- data/lib/paperclip/validators.rb +73 -0
- data/lib/paperclip/validators/attachment_content_type_validator.rb +88 -0
- data/lib/paperclip/validators/attachment_file_name_validator.rb +75 -0
- data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +28 -0
- data/lib/paperclip/validators/attachment_presence_validator.rb +28 -0
- data/lib/paperclip/validators/attachment_size_validator.rb +109 -0
- data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +29 -0
- data/lib/paperclip/version.rb +3 -0
- data/lib/tasks/paperclip.rake +140 -0
- data/paperclip.gemspec +50 -0
- data/shoulda_macros/paperclip.rb +134 -0
- data/spec/database.yml +4 -0
- data/spec/paperclip/attachment_definitions_spec.rb +13 -0
- data/spec/paperclip/attachment_processing_spec.rb +79 -0
- data/spec/paperclip/attachment_registry_spec.rb +158 -0
- data/spec/paperclip/attachment_spec.rb +1590 -0
- data/spec/paperclip/content_type_detector_spec.rb +47 -0
- data/spec/paperclip/file_command_content_type_detector_spec.rb +40 -0
- data/spec/paperclip/filename_cleaner_spec.rb +13 -0
- data/spec/paperclip/geometry_detector_spec.rb +38 -0
- data/spec/paperclip/geometry_parser_spec.rb +73 -0
- data/spec/paperclip/geometry_spec.rb +255 -0
- data/spec/paperclip/glue_spec.rb +42 -0
- data/spec/paperclip/has_attached_file_spec.rb +78 -0
- data/spec/paperclip/integration_spec.rb +702 -0
- data/spec/paperclip/interpolations_spec.rb +270 -0
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +160 -0
- data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +140 -0
- data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +88 -0
- data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
- data/spec/paperclip/io_adapters/file_adapter_spec.rb +131 -0
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +137 -0
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
- data/spec/paperclip/io_adapters/nil_adapter_spec.rb +25 -0
- data/spec/paperclip/io_adapters/registry_spec.rb +35 -0
- data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +64 -0
- data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +146 -0
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +221 -0
- data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +108 -0
- data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
- data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
- data/spec/paperclip/media_type_spoof_detector_spec.rb +120 -0
- data/spec/paperclip/meta_class_spec.rb +30 -0
- data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +88 -0
- data/spec/paperclip/paperclip_spec.rb +196 -0
- data/spec/paperclip/plural_cache_spec.rb +37 -0
- data/spec/paperclip/processor_helpers_spec.rb +57 -0
- data/spec/paperclip/processor_spec.rb +26 -0
- data/spec/paperclip/rails_environment_spec.rb +30 -0
- data/spec/paperclip/rake_spec.rb +103 -0
- data/spec/paperclip/schema_spec.rb +252 -0
- data/spec/paperclip/storage/filesystem_spec.rb +79 -0
- data/spec/paperclip/storage/fog_spec.rb +560 -0
- data/spec/paperclip/storage/s3_live_spec.rb +188 -0
- data/spec/paperclip/storage/s3_spec.rb +1695 -0
- data/spec/paperclip/style_spec.rb +251 -0
- data/spec/paperclip/tempfile_factory_spec.rb +33 -0
- data/spec/paperclip/tempfile_spec.rb +35 -0
- data/spec/paperclip/thumbnail_spec.rb +504 -0
- data/spec/paperclip/url_generator_spec.rb +221 -0
- data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
- data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +159 -0
- data/spec/paperclip/validators/attachment_presence_validator_spec.rb +85 -0
- data/spec/paperclip/validators/attachment_size_validator_spec.rb +235 -0
- data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +48 -0
- data/spec/paperclip/validators_spec.rb +164 -0
- data/spec/spec_helper.rb +45 -0
- data/spec/support/assertions.rb +84 -0
- data/spec/support/fake_model.rb +24 -0
- data/spec/support/fake_rails.rb +12 -0
- data/spec/support/fixtures/12k.png +0 -0
- data/spec/support/fixtures/50x50.png +0 -0
- data/spec/support/fixtures/5k.png +0 -0
- data/spec/support/fixtures/animated +0 -0
- data/spec/support/fixtures/animated.gif +0 -0
- data/spec/support/fixtures/animated.unknown +0 -0
- data/spec/support/fixtures/bad.png +1 -0
- data/spec/support/fixtures/empty.html +1 -0
- data/spec/support/fixtures/empty.xlsx +0 -0
- data/spec/support/fixtures/fog.yml +8 -0
- data/spec/support/fixtures/rotated.jpg +0 -0
- data/spec/support/fixtures/s3.yml +8 -0
- data/spec/support/fixtures/spaced file.jpg +0 -0
- data/spec/support/fixtures/spaced file.png +0 -0
- data/spec/support/fixtures/text.txt +1 -0
- data/spec/support/fixtures/twopage.pdf +0 -0
- data/spec/support/fixtures/uppercase.PNG +0 -0
- data/spec/support/matchers/accept.rb +5 -0
- data/spec/support/matchers/exist.rb +5 -0
- data/spec/support/matchers/have_column.rb +23 -0
- data/spec/support/mock_attachment.rb +24 -0
- data/spec/support/mock_interpolator.rb +24 -0
- data/spec/support/mock_url_generator_builder.rb +26 -0
- data/spec/support/model_reconstruction.rb +72 -0
- data/spec/support/reporting.rb +11 -0
- data/spec/support/test_data.rb +13 -0
- data/spec/support/version_helper.rb +9 -0
- metadata +586 -0
@@ -0,0 +1,270 @@
|
|
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 = spy
|
29
|
+
expect(attachment).to receive(:instance).and_return(attachment)
|
30
|
+
expect(attachment).to receive(:class).and_return(Thing)
|
31
|
+
assert_equal "things", Paperclip::Interpolations.class(attachment, :style)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns the basename of the file" do
|
35
|
+
attachment = spy
|
36
|
+
expect(attachment).to receive(:original_filename).and_return("one.jpg")
|
37
|
+
assert_equal "one", Paperclip::Interpolations.basename(attachment, :style)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns the extension of the file" do
|
41
|
+
attachment = spy
|
42
|
+
expect(attachment).to receive(:original_filename).and_return("one.jpg")
|
43
|
+
expect(attachment).to receive(:styles).and_return({})
|
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 = spy
|
49
|
+
expect(attachment).to_not receive(:original_filename)
|
50
|
+
expect(attachment).to receive(:styles).at_least(2).times.and_return(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 = spy
|
59
|
+
expect(attachment).to receive(:content_type).and_return("image/png")
|
60
|
+
expect(attachment).to receive(:styles).and_return({})
|
61
|
+
interpolations = Paperclip::Interpolations
|
62
|
+
expect(interpolations).to receive(:extension).and_return("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 = spy
|
68
|
+
expect(attachment).to receive(:content_type).and_return("image/jpeg")
|
69
|
+
expect(attachment).to receive(:styles).and_return({})
|
70
|
+
interpolations = Paperclip::Interpolations
|
71
|
+
expect(interpolations).to receive(:extension).and_return("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 = spy
|
77
|
+
expect(attachment).to receive(:original_filename).and_return("one.jpg")
|
78
|
+
expect(attachment).to receive(:styles).and_return({})
|
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 = spy
|
84
|
+
expect(attachment).to receive(:original_filename).and_return("one")
|
85
|
+
expect(attachment).to receive(:styles).and_return({})
|
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 = spy
|
91
|
+
allow(attachment).to receive(:content_type).at_least(1).times.and_return("not/found")
|
92
|
+
allow(attachment).to receive(:styles).and_return({})
|
93
|
+
interpolations = Paperclip::Interpolations
|
94
|
+
expect(interpolations).to receive(:extension).and_return("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 = spy
|
100
|
+
expect(attachment).to receive(:content_type).and_return("image/jpeg")
|
101
|
+
expect(attachment).to receive(:styles).and_return(style: { format: "png" })
|
102
|
+
interpolations = Paperclip::Interpolations
|
103
|
+
expect(interpolations).to receive(:extension).and_return("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 = spy(
|
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 = spy
|
116
|
+
expect(attachment).to receive(:to_param).and_return("23-awesome")
|
117
|
+
expect(attachment).to receive(:instance).and_return(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 = spy
|
123
|
+
expect(attachment).to receive(:id).and_return(23)
|
124
|
+
expect(attachment).to receive(:instance).and_return(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 = spy
|
130
|
+
expect(attachment).to receive(:id).and_return(nil)
|
131
|
+
expect(attachment).to receive(:instance).and_return(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 = spy
|
137
|
+
expect(attachment).to receive(:id).and_return(23)
|
138
|
+
expect(attachment).to receive(:instance).and_return(attachment)
|
139
|
+
assert_equal "000/000/023", Paperclip::Interpolations.id_partition(attachment, :style)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "returns the partitioned id when the id is above 999_999_999" do
|
143
|
+
attachment = spy
|
144
|
+
expect(attachment).to receive(:id).and_return(Paperclip::Interpolations::ID_PARTITION_LIMIT)
|
145
|
+
expect(attachment).to receive(:instance).and_return(attachment)
|
146
|
+
assert_equal "001/000/000/000",
|
147
|
+
Paperclip::Interpolations.id_partition(attachment, :style)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "returns the partitioned id of the attachment when the id is a string" do
|
151
|
+
attachment = spy
|
152
|
+
expect(attachment).to receive(:id).and_return("32fnj23oio2f")
|
153
|
+
expect(attachment).to receive(:instance).and_return(attachment)
|
154
|
+
assert_equal "32f/nj2/3oi", Paperclip::Interpolations.id_partition(attachment, :style)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "returns nil for the partitioned id of an attachment to a new record (when the id is nil)" do
|
158
|
+
attachment = spy
|
159
|
+
expect(attachment).to receive(:id).and_return(nil)
|
160
|
+
expect(attachment).to receive(:instance).and_return(attachment)
|
161
|
+
assert_nil Paperclip::Interpolations.id_partition(attachment, :style)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "returns the name of the attachment" do
|
165
|
+
attachment = spy
|
166
|
+
expect(attachment).to receive(:name).and_return("file")
|
167
|
+
assert_equal "files", Paperclip::Interpolations.attachment(attachment, :style)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "returns the style" do
|
171
|
+
assert_equal :style, Paperclip::Interpolations.style(:attachment, :style)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "returns the default style" do
|
175
|
+
attachment = spy
|
176
|
+
expect(attachment).to receive(:default_style).and_return(:default_style)
|
177
|
+
assert_equal :default_style, Paperclip::Interpolations.style(attachment, nil)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "reinterpolates :url" do
|
181
|
+
attachment = spy
|
182
|
+
expect(attachment).to receive(:url).with(:style, timestamp: false, escape: false).and_return("1234")
|
183
|
+
assert_equal "1234", Paperclip::Interpolations.url(attachment, :style)
|
184
|
+
end
|
185
|
+
|
186
|
+
it "raises if infinite loop detcted reinterpolating :url" do
|
187
|
+
attachment = Object.new
|
188
|
+
class << attachment
|
189
|
+
def url(*_args)
|
190
|
+
Paperclip::Interpolations.url(self, :style)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
assert_raises(Paperclip::Errors::InfiniteInterpolationError) { Paperclip::Interpolations.url(attachment, :style) }
|
194
|
+
end
|
195
|
+
|
196
|
+
it "returns the filename as basename.extension" do
|
197
|
+
attachment = spy
|
198
|
+
expect(attachment).to receive(:styles).and_return({})
|
199
|
+
expect(attachment).to receive(:original_filename).and_return("one.jpg").twice
|
200
|
+
assert_equal "one.jpg", Paperclip::Interpolations.filename(attachment, :style)
|
201
|
+
end
|
202
|
+
|
203
|
+
it "returns the filename as basename.extension when format supplied" do
|
204
|
+
attachment = spy
|
205
|
+
expect(attachment).to receive(:styles).and_return(style: { format: :png })
|
206
|
+
expect(attachment).to receive(:original_filename).and_return("one.jpg").once
|
207
|
+
assert_equal "one.png", Paperclip::Interpolations.filename(attachment, :style)
|
208
|
+
end
|
209
|
+
|
210
|
+
it "returns the filename as basename when extension is blank" do
|
211
|
+
attachment = spy
|
212
|
+
allow(attachment).to receive(:styles).and_return({})
|
213
|
+
allow(attachment).to receive(:original_filename).and_return("one")
|
214
|
+
assert_equal "one", Paperclip::Interpolations.filename(attachment, :style)
|
215
|
+
end
|
216
|
+
|
217
|
+
it "returns the basename when the extension contains regexp special characters" do
|
218
|
+
attachment = spy
|
219
|
+
allow(attachment).to receive(:styles).and_return({})
|
220
|
+
allow(attachment).to receive(:original_filename).and_return("one.ab)")
|
221
|
+
assert_equal "one", Paperclip::Interpolations.basename(attachment, :style)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "returns the timestamp" do
|
225
|
+
now = Time.now
|
226
|
+
zone = "UTC"
|
227
|
+
attachment = spy
|
228
|
+
expect(attachment).to receive(:instance_read).with(:updated_at).and_return(now)
|
229
|
+
expect(attachment).to receive(:time_zone).and_return(zone)
|
230
|
+
assert_equal now.in_time_zone(zone).to_s, Paperclip::Interpolations.timestamp(attachment, :style)
|
231
|
+
end
|
232
|
+
|
233
|
+
it "returns updated_at" do
|
234
|
+
attachment = spy
|
235
|
+
seconds_since_epoch = 1234567890
|
236
|
+
expect(attachment).to receive(:updated_at).and_return(seconds_since_epoch)
|
237
|
+
assert_equal seconds_since_epoch, Paperclip::Interpolations.updated_at(attachment, :style)
|
238
|
+
end
|
239
|
+
|
240
|
+
it "returns attachment's hash when passing both arguments" do
|
241
|
+
attachment = spy
|
242
|
+
fake_hash = "a_wicked_secure_hash"
|
243
|
+
expect(attachment).to receive(:hash_key).and_return(fake_hash)
|
244
|
+
assert_equal fake_hash, Paperclip::Interpolations.hash(attachment, :style)
|
245
|
+
end
|
246
|
+
|
247
|
+
it "returns Object#hash when passing no argument" do
|
248
|
+
attachment = spy
|
249
|
+
fake_hash = "a_wicked_secure_hash"
|
250
|
+
expect(attachment).to_not receive(:hash_key)
|
251
|
+
assert_not_equal fake_hash, Paperclip::Interpolations.hash
|
252
|
+
end
|
253
|
+
|
254
|
+
it "calls all expected interpolations with the given arguments" do
|
255
|
+
expect(Paperclip::Interpolations).to receive(:id).with(:attachment, :style).and_return(1234)
|
256
|
+
expect(Paperclip::Interpolations).to receive(:attachment).with(:attachment, :style).and_return("attachments")
|
257
|
+
expect(Paperclip::Interpolations).to_not receive(:notreal)
|
258
|
+
value = Paperclip::Interpolations.interpolate(":notreal/:id/:attachment", :attachment, :style)
|
259
|
+
assert_equal ":notreal/1234/attachments", value
|
260
|
+
end
|
261
|
+
|
262
|
+
it "handles question marks" do
|
263
|
+
Paperclip.interpolates :foo? do
|
264
|
+
"bar"
|
265
|
+
end
|
266
|
+
expect(Paperclip::Interpolations).to_not receive(:fool)
|
267
|
+
value = Paperclip::Interpolations.interpolate(":fo/:foo?")
|
268
|
+
assert_equal ":fo/bar", value
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,160 @@
|
|
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
|
+
subject { TestAdapter.new(nil) }
|
13
|
+
|
14
|
+
context "content type from file contents" do
|
15
|
+
before do
|
16
|
+
allow(subject).to receive(:path).and_return("image.png")
|
17
|
+
allow(Paperclip).to receive(:run).and_return("image/png\n")
|
18
|
+
allow_any_instance_of(Paperclip::ContentTypeDetector).to receive(:type_from_mime_magic).and_return("image/png")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns the content type without newline" do
|
22
|
+
assert_equal "image/png", subject.content_type
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "nil?" do
|
27
|
+
it "returns false" do
|
28
|
+
assert !subject.nil?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "delegation" do
|
33
|
+
before do
|
34
|
+
subject.tempfile = double("Tempfile")
|
35
|
+
end
|
36
|
+
|
37
|
+
[:binmode, :binmode?, :close, :close!, :closed?, :eof?, :path, :readbyte, :rewind, :unlink].each do |method|
|
38
|
+
it "delegates #{method} to @tempfile" do
|
39
|
+
allow(subject.tempfile).to receive(method)
|
40
|
+
subject.public_send(method)
|
41
|
+
expect(subject.tempfile).to have_received(method)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "gets rid of slashes and colons in filenames" do
|
47
|
+
subject.original_filename = "awesome/file:name.png"
|
48
|
+
|
49
|
+
assert_equal "awesome_file_name.png", subject.original_filename
|
50
|
+
end
|
51
|
+
|
52
|
+
it "is an assignment" do
|
53
|
+
assert subject.assignment?
|
54
|
+
end
|
55
|
+
|
56
|
+
it "is not nil" do
|
57
|
+
assert !subject.nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
it "generates a destination filename with no original filename" do
|
61
|
+
expect(subject.send(:destination).path).to_not be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it "uses the original filename to generate the tempfile" do
|
65
|
+
subject.original_filename = "file.png"
|
66
|
+
expect(subject.send(:destination).path).to end_with(".png")
|
67
|
+
end
|
68
|
+
|
69
|
+
context "generates a fingerprint" do
|
70
|
+
subject { TestAdapter.new(nil, options) }
|
71
|
+
|
72
|
+
before do
|
73
|
+
allow(subject).to receive(:path).and_return(fixture_file("50x50.png"))
|
74
|
+
end
|
75
|
+
|
76
|
+
context "MD5" do
|
77
|
+
let(:options) { { hash_digest: Digest::MD5 } }
|
78
|
+
|
79
|
+
it "returns a fingerprint" do
|
80
|
+
expect(subject.fingerprint).to be_a String
|
81
|
+
expect(subject.fingerprint).to eq "a790b00c9b5d58a8fd17a1ec5a187129"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "SHA256" do
|
86
|
+
let(:options) { { hash_digest: Digest::SHA256 } }
|
87
|
+
|
88
|
+
it "returns a fingerprint" do
|
89
|
+
expect(subject.fingerprint).to be_a String
|
90
|
+
expect(subject.fingerprint).
|
91
|
+
to eq "243d7ce1099719df25f600f1c369c629fb979f88d5a01dbe7d0d48c8e6715bb1"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "#copy_to_tempfile" do
|
97
|
+
around do |example|
|
98
|
+
FileUtils.module_eval do
|
99
|
+
class << self
|
100
|
+
alias paperclip_ln ln
|
101
|
+
|
102
|
+
def ln(*)
|
103
|
+
raise Errno::EXDEV
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
example.run
|
109
|
+
|
110
|
+
FileUtils.module_eval do
|
111
|
+
class << self
|
112
|
+
alias ln paperclip_ln
|
113
|
+
undef paperclip_ln
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return a readable file even when linking fails" do
|
119
|
+
src = open(fixture_file("5k.png"), "rb")
|
120
|
+
expect(subject.send(:copy_to_tempfile, src).read).to eq src.read
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "#original_filename=" do
|
125
|
+
it "should not fail with a nil original filename" do
|
126
|
+
expect { subject.original_filename = nil }.not_to raise_error
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "#link_or_copy_file" do
|
131
|
+
class TestLinkOrCopyAdapter < Paperclip::AbstractAdapter
|
132
|
+
public :copy_to_tempfile, :destination
|
133
|
+
end
|
134
|
+
|
135
|
+
subject { TestLinkOrCopyAdapter.new(nil) }
|
136
|
+
let(:body) { "body" }
|
137
|
+
|
138
|
+
let(:file) do
|
139
|
+
t = Tempfile.new("destination")
|
140
|
+
t.print(body)
|
141
|
+
t.rewind
|
142
|
+
t
|
143
|
+
end
|
144
|
+
|
145
|
+
after do
|
146
|
+
file.close
|
147
|
+
file.unlink
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should be able to read the file" do
|
151
|
+
expect(subject.copy_to_tempfile(file).read).to eq(body)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should be able to reopen the file after symlink has failed" do
|
155
|
+
expect(FileUtils).to receive(:ln).and_raise(Errno::EXDEV)
|
156
|
+
|
157
|
+
expect(subject.copy_to_tempfile(file).read).to eq(body)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,140 @@
|
|
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
|
+
hash_digest: Digest::MD5)
|
18
|
+
end
|
19
|
+
|
20
|
+
after do
|
21
|
+
@file.close
|
22
|
+
@subject.close
|
23
|
+
end
|
24
|
+
|
25
|
+
it "gets the right filename" do
|
26
|
+
assert_equal "5k.png", @subject.original_filename
|
27
|
+
end
|
28
|
+
|
29
|
+
it "forces binmode on tempfile" do
|
30
|
+
assert @subject.instance_variable_get("@tempfile").binmode?
|
31
|
+
end
|
32
|
+
|
33
|
+
it "gets the content type" do
|
34
|
+
assert_equal "image/png", @subject.content_type
|
35
|
+
end
|
36
|
+
|
37
|
+
it "gets the file's size" do
|
38
|
+
assert_equal 4456, @subject.size
|
39
|
+
end
|
40
|
+
|
41
|
+
it "returns false for a call to nil?" do
|
42
|
+
assert !@subject.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
it "generates a MD5 hash of the contents" do
|
46
|
+
expected = Digest::MD5.file(@file.path).to_s
|
47
|
+
assert_equal expected, @subject.fingerprint
|
48
|
+
end
|
49
|
+
|
50
|
+
it "reads the contents of the file" do
|
51
|
+
expected = @file.read
|
52
|
+
actual = @subject.read
|
53
|
+
assert !expected.empty?
|
54
|
+
assert_equal expected.length, actual.length
|
55
|
+
assert_equal expected, actual
|
56
|
+
end
|
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
|
+
allow(@file).to receive(:original_filename).and_return("image:restricted.gif")
|
64
|
+
@file.binmode
|
65
|
+
|
66
|
+
@attachment.assign(@file)
|
67
|
+
@attachment.save
|
68
|
+
@subject = Paperclip.io_adapters.for(@attachment,
|
69
|
+
hash_digest: Digest::MD5)
|
70
|
+
end
|
71
|
+
|
72
|
+
after do
|
73
|
+
@subject.close
|
74
|
+
end
|
75
|
+
|
76
|
+
it "does not generate paths that include restricted characters" do
|
77
|
+
expect(@subject.path).to_not match(/:/)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "does not generate filenames that include restricted characters" do
|
81
|
+
assert_equal "image_restricted.gif", @subject.original_filename
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "for a style" do
|
86
|
+
before do
|
87
|
+
@file = File.new(fixture_file("5k.png"))
|
88
|
+
@file.binmode
|
89
|
+
|
90
|
+
@attachment.assign(@file)
|
91
|
+
|
92
|
+
@thumb = Tempfile.new("thumbnail").tap(&:binmode)
|
93
|
+
FileUtils.cp @attachment.queued_for_write[:thumb].path, @thumb.path
|
94
|
+
|
95
|
+
@attachment.save
|
96
|
+
@subject = Paperclip.io_adapters.for(@attachment.styles[:thumb],
|
97
|
+
hash_digest: Digest::MD5)
|
98
|
+
end
|
99
|
+
|
100
|
+
after do
|
101
|
+
@file.close
|
102
|
+
@thumb.close
|
103
|
+
@subject.close
|
104
|
+
end
|
105
|
+
|
106
|
+
it "gets the original filename" do
|
107
|
+
assert_equal "5k.png", @subject.original_filename
|
108
|
+
end
|
109
|
+
|
110
|
+
it "forces binmode on tempfile" do
|
111
|
+
assert @subject.instance_variable_get("@tempfile").binmode?
|
112
|
+
end
|
113
|
+
|
114
|
+
it "gets the content type" do
|
115
|
+
assert_equal "image/png", @subject.content_type
|
116
|
+
end
|
117
|
+
|
118
|
+
it "gets the thumbnail's file size" do
|
119
|
+
assert_equal @thumb.size, @subject.size
|
120
|
+
end
|
121
|
+
|
122
|
+
it "returns false for a call to nil?" do
|
123
|
+
assert !@subject.nil?
|
124
|
+
end
|
125
|
+
|
126
|
+
it "generates a MD5 hash of the contents" do
|
127
|
+
expected = Digest::MD5.file(@thumb.path).to_s
|
128
|
+
assert_equal expected, @subject.fingerprint
|
129
|
+
end
|
130
|
+
|
131
|
+
it "reads the contents of the thumbnail" do
|
132
|
+
@thumb.rewind
|
133
|
+
expected = @thumb.read
|
134
|
+
actual = @subject.read
|
135
|
+
assert !expected.empty?
|
136
|
+
assert_equal expected.length, actual.length
|
137
|
+
assert_equal expected, actual
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|