paperclip 3.5.4 → 4.3.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of paperclip might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +0 -6
- data/.hound.yml +1066 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +11 -17
- data/Appraisals +6 -14
- data/CONTRIBUTING.md +13 -8
- data/Gemfile +16 -3
- data/LICENSE +1 -3
- data/NEWS +167 -49
- data/README.md +294 -75
- data/RELEASING.md +17 -0
- data/Rakefile +6 -8
- data/features/basic_integration.feature +24 -6
- data/features/step_definitions/attachment_steps.rb +30 -22
- data/features/step_definitions/html_steps.rb +2 -2
- data/features/step_definitions/rails_steps.rb +44 -14
- data/features/step_definitions/web_steps.rb +1 -103
- data/features/support/env.rb +2 -2
- data/features/support/file_helpers.rb +2 -2
- data/features/support/fixtures/gemfile.txt +1 -1
- data/features/support/rails.rb +2 -1
- data/gemfiles/3.2.gemfile +14 -6
- data/gemfiles/4.1.gemfile +19 -0
- data/gemfiles/4.2.gemfile +19 -0
- data/lib/generators/paperclip/paperclip_generator.rb +0 -2
- data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
- data/lib/paperclip/attachment.rb +132 -38
- data/lib/paperclip/attachment_registry.rb +1 -1
- data/lib/paperclip/callbacks.rb +11 -1
- data/lib/paperclip/content_type_detector.rb +25 -22
- data/lib/paperclip/deprecations.rb +42 -0
- data/lib/paperclip/errors.rb +5 -0
- data/lib/paperclip/file_command_content_type_detector.rb +6 -8
- data/lib/paperclip/geometry_detector_factory.rb +3 -1
- data/lib/paperclip/geometry_parser_factory.rb +1 -1
- data/lib/paperclip/has_attached_file.rb +10 -0
- data/lib/paperclip/interpolations/plural_cache.rb +6 -5
- data/lib/paperclip/interpolations.rb +25 -12
- data/lib/paperclip/io_adapters/abstract_adapter.rb +3 -1
- data/lib/paperclip/io_adapters/attachment_adapter.rb +4 -4
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +5 -10
- data/lib/paperclip/io_adapters/stringio_adapter.rb +6 -10
- data/lib/paperclip/io_adapters/uri_adapter.rb +30 -11
- data/lib/paperclip/locales/de.yml +18 -0
- data/lib/paperclip/locales/en.yml +1 -0
- data/lib/paperclip/locales/es.yml +18 -0
- data/lib/paperclip/locales/ja.yml +18 -0
- data/lib/paperclip/locales/pt-BR.yml +18 -0
- data/lib/paperclip/locales/zh-CN.yml +18 -0
- data/lib/paperclip/locales/zh-HK.yml +18 -0
- data/lib/paperclip/locales/zh-TW.yml +18 -0
- data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -1
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -1
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -1
- data/lib/paperclip/media_type_spoof_detector.rb +89 -0
- data/lib/paperclip/processor.rb +0 -37
- data/lib/paperclip/processor_helpers.rb +50 -0
- data/lib/paperclip/rails_environment.rb +25 -0
- data/lib/paperclip/schema.rb +10 -2
- data/lib/paperclip/storage/filesystem.rb +1 -1
- data/lib/paperclip/storage/fog.rb +18 -7
- data/lib/paperclip/storage/s3.rb +53 -22
- data/lib/paperclip/style.rb +8 -2
- data/lib/paperclip/tempfile_factory.rb +5 -1
- data/lib/paperclip/thumbnail.rb +12 -10
- data/lib/paperclip/url_generator.rb +11 -3
- data/lib/paperclip/validators/attachment_content_type_validator.rb +4 -0
- data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
- data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
- data/lib/paperclip/validators/attachment_presence_validator.rb +4 -0
- data/lib/paperclip/validators/attachment_size_validator.rb +11 -3
- data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +27 -0
- data/lib/paperclip/validators.rb +10 -3
- data/lib/paperclip/version.rb +1 -1
- data/lib/paperclip.rb +26 -8
- data/lib/tasks/paperclip.rake +17 -2
- data/paperclip.gemspec +16 -14
- data/shoulda_macros/paperclip.rb +0 -1
- data/spec/paperclip/attachment_definitions_spec.rb +13 -0
- data/{test/attachment_processing_test.rb → spec/paperclip/attachment_processing_spec.rb} +20 -21
- data/spec/paperclip/attachment_registry_spec.rb +130 -0
- data/{test/attachment_test.rb → spec/paperclip/attachment_spec.rb} +438 -397
- data/{test/content_type_detector_test.rb → spec/paperclip/content_type_detector_spec.rb} +16 -19
- data/spec/paperclip/deprecations_spec.rb +65 -0
- data/{test/file_command_content_type_detector_test.rb → spec/paperclip/file_command_content_type_detector_spec.rb} +5 -6
- data/spec/paperclip/filename_cleaner_spec.rb +14 -0
- data/spec/paperclip/geometry_detector_spec.rb +39 -0
- data/{test/geometry_parser_test.rb → spec/paperclip/geometry_parser_spec.rb} +27 -27
- data/{test/geometry_test.rb → spec/paperclip/geometry_spec.rb} +50 -52
- data/spec/paperclip/glue_spec.rb +44 -0
- data/{test/has_attached_file_test.rb → spec/paperclip/has_attached_file_spec.rb} +45 -28
- data/{test/integration_test.rb → spec/paperclip/integration_spec.rb} +134 -126
- data/{test/interpolations_test.rb → spec/paperclip/interpolations_spec.rb} +70 -46
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +78 -0
- data/{test/io_adapters/attachment_adapter_test.rb → spec/paperclip/io_adapters/attachment_adapter_spec.rb} +27 -29
- data/{test/io_adapters/data_uri_adapter_test.rb → spec/paperclip/io_adapters/data_uri_adapter_spec.rb} +26 -17
- data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
- data/{test/io_adapters/file_adapter_test.rb → spec/paperclip/io_adapters/file_adapter_spec.rb} +36 -40
- data/{test/io_adapters/http_url_proxy_adapter_test.rb → spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb} +31 -29
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
- data/{test/io_adapters/nil_adapter_test.rb → spec/paperclip/io_adapters/nil_adapter_spec.rb} +7 -7
- data/{test/io_adapters/registry_test.rb → spec/paperclip/io_adapters/registry_spec.rb} +10 -7
- data/{test/io_adapters/stringio_adapter_test.rb → spec/paperclip/io_adapters/stringio_adapter_spec.rb} +20 -17
- data/{test/io_adapters/uploaded_file_adapter_test.rb → spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb} +41 -41
- data/{test/io_adapters/uri_adapter_test.rb → spec/paperclip/io_adapters/uri_adapter_spec.rb} +53 -28
- data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +99 -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 +79 -0
- data/spec/paperclip/meta_class_spec.rb +30 -0
- data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
- data/{test/paperclip_test.rb → spec/paperclip/paperclip_spec.rb} +53 -48
- data/spec/paperclip/plural_cache_spec.rb +37 -0
- data/spec/paperclip/processor_helpers_spec.rb +57 -0
- data/{test/processor_test.rb → spec/paperclip/processor_spec.rb} +5 -5
- data/spec/paperclip/rails_environment_spec.rb +33 -0
- data/{test/rake_test.rb → spec/paperclip/rake_spec.rb} +15 -15
- data/spec/paperclip/schema_spec.rb +248 -0
- data/{test/storage/filesystem_test.rb → spec/paperclip/storage/filesystem_spec.rb} +18 -18
- data/spec/paperclip/storage/fog_spec.rb +535 -0
- data/spec/paperclip/storage/s3_live_spec.rb +182 -0
- data/spec/paperclip/storage/s3_spec.rb +1526 -0
- data/spec/paperclip/style_spec.rb +255 -0
- data/spec/paperclip/tempfile_factory_spec.rb +33 -0
- data/{test/thumbnail_test.rb → spec/paperclip/thumbnail_spec.rb} +123 -107
- data/spec/paperclip/url_generator_spec.rb +211 -0
- data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
- data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
- data/{test/validators/attachment_presence_validator_test.rb → spec/paperclip/validators/attachment_presence_validator_spec.rb} +20 -20
- data/{test/validators/attachment_size_validator_test.rb → spec/paperclip/validators/attachment_size_validator_spec.rb} +65 -58
- data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +52 -0
- data/spec/paperclip/validators_spec.rb +164 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/support/assertions.rb +71 -0
- data/spec/support/deprecations.rb +9 -0
- data/spec/support/fake_model.rb +25 -0
- data/spec/support/fake_rails.rb +12 -0
- data/spec/support/fixtures/empty.html +1 -0
- data/spec/support/fixtures/empty.xlsx +0 -0
- data/spec/support/fixtures/spaced file.jpg +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/model_reconstruction.rb +60 -0
- data/spec/support/rails_helpers.rb +7 -0
- data/spec/support/test_data.rb +13 -0
- data/spec/support/version_helper.rb +9 -0
- metadata +334 -219
- data/RUNNING_TESTS.md +0 -4
- data/gemfiles/3.0.gemfile +0 -11
- data/gemfiles/3.1.gemfile +0 -11
- data/gemfiles/4.0.gemfile +0 -11
- data/test/attachment_definitions_test.rb +0 -12
- data/test/attachment_registry_test.rb +0 -88
- data/test/filename_cleaner_test.rb +0 -14
- data/test/generator_test.rb +0 -84
- data/test/geometry_detector_test.rb +0 -24
- data/test/helper.rb +0 -232
- data/test/io_adapters/abstract_adapter_test.rb +0 -58
- data/test/io_adapters/empty_string_adapter_test.rb +0 -18
- data/test/io_adapters/identity_adapter_test.rb +0 -8
- data/test/matchers/have_attached_file_matcher_test.rb +0 -24
- data/test/matchers/validate_attachment_content_type_matcher_test.rb +0 -110
- data/test/matchers/validate_attachment_presence_matcher_test.rb +0 -69
- data/test/matchers/validate_attachment_size_matcher_test.rb +0 -86
- data/test/meta_class_test.rb +0 -32
- data/test/paperclip_missing_attachment_styles_test.rb +0 -90
- data/test/plural_cache_test.rb +0 -36
- data/test/schema_test.rb +0 -200
- data/test/storage/fog_test.rb +0 -473
- data/test/storage/s3_live_test.rb +0 -179
- data/test/storage/s3_test.rb +0 -1356
- data/test/style_test.rb +0 -213
- data/test/support/mock_model.rb +0 -2
- data/test/tempfile_factory_test.rb +0 -17
- data/test/url_generator_test.rb +0 -187
- data/test/validators/attachment_content_type_validator_test.rb +0 -324
- data/test/validators_test.rb +0 -61
- /data/{test → spec}/database.yml +0 -0
- /data/{test → spec/support}/fixtures/12k.png +0 -0
- /data/{test → spec/support}/fixtures/50x50.png +0 -0
- /data/{test → spec/support}/fixtures/5k.png +0 -0
- /data/{test → spec/support}/fixtures/animated +0 -0
- /data/{test → spec/support}/fixtures/animated.gif +0 -0
- /data/{test → spec/support}/fixtures/animated.unknown +0 -0
- /data/{test → spec/support}/fixtures/bad.png +0 -0
- /data/{test → spec/support}/fixtures/fog.yml +0 -0
- /data/{test → spec/support}/fixtures/rotated.jpg +0 -0
- /data/{test → spec/support}/fixtures/s3.yml +0 -0
- /data/{test → spec/support}/fixtures/spaced file.png +0 -0
- /data/{test → spec/support}/fixtures/text.txt +0 -0
- /data/{test → spec/support}/fixtures/twopage.pdf +0 -0
- /data/{test → spec/support}/fixtures/uppercase.PNG +0 -0
- /data/{test → spec}/support/mock_attachment.rb +0 -0
- /data/{test → spec}/support/mock_interpolator.rb +0 -0
- /data/{test → spec}/support/mock_url_generator_builder.rb +0 -0
@@ -0,0 +1,535 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fog/aws'
|
3
|
+
require 'fog/local'
|
4
|
+
require 'timecop'
|
5
|
+
|
6
|
+
describe Paperclip::Storage::Fog do
|
7
|
+
context "" do
|
8
|
+
before { Fog.mock! }
|
9
|
+
|
10
|
+
context "with credentials provided in a path string" do
|
11
|
+
before do
|
12
|
+
rebuild_model styles: { medium: "300x300>", thumb: "100x100>" },
|
13
|
+
storage: :fog,
|
14
|
+
url: '/:attachment/:filename',
|
15
|
+
fog_directory: "paperclip",
|
16
|
+
fog_credentials: fixture_file('fog.yml')
|
17
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
18
|
+
@dummy = Dummy.new
|
19
|
+
@dummy.avatar = @file
|
20
|
+
end
|
21
|
+
|
22
|
+
after { @file.close }
|
23
|
+
|
24
|
+
it "has the proper information loading credentials from a file" do
|
25
|
+
assert_equal @dummy.avatar.fog_credentials[:provider], 'AWS'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with credentials provided in a File object" do
|
30
|
+
before do
|
31
|
+
rebuild_model styles: { medium: "300x300>", thumb: "100x100>" },
|
32
|
+
storage: :fog,
|
33
|
+
url: '/:attachment/:filename',
|
34
|
+
fog_directory: "paperclip",
|
35
|
+
fog_credentials: File.open(fixture_file('fog.yml'))
|
36
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
37
|
+
@dummy = Dummy.new
|
38
|
+
@dummy.avatar = @file
|
39
|
+
end
|
40
|
+
|
41
|
+
after { @file.close }
|
42
|
+
|
43
|
+
it "has the proper information loading credentials from a file" do
|
44
|
+
assert_equal @dummy.avatar.fog_credentials[:provider], 'AWS'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "with default values for path and url" do
|
49
|
+
before do
|
50
|
+
rebuild_model styles: { medium: "300x300>", thumb: "100x100>" },
|
51
|
+
storage: :fog,
|
52
|
+
url: '/:attachment/:filename',
|
53
|
+
fog_directory: "paperclip",
|
54
|
+
fog_credentials: {
|
55
|
+
provider: 'AWS',
|
56
|
+
aws_access_key_id: 'AWS_ID',
|
57
|
+
aws_secret_access_key: 'AWS_SECRET'
|
58
|
+
}
|
59
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
60
|
+
@dummy = Dummy.new
|
61
|
+
@dummy.avatar = @file
|
62
|
+
end
|
63
|
+
|
64
|
+
after { @file.close }
|
65
|
+
|
66
|
+
it "is able to interpolate the path without blowing up" do
|
67
|
+
assert_equal File.expand_path(File.join(File.dirname(__FILE__), "../../../tmp/public/avatars/5k.png")),
|
68
|
+
@dummy.avatar.path
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with no path or url given and using defaults" do
|
73
|
+
before do
|
74
|
+
rebuild_model styles: { medium: "300x300>", thumb: "100x100>" },
|
75
|
+
storage: :fog,
|
76
|
+
fog_directory: "paperclip",
|
77
|
+
fog_credentials: {
|
78
|
+
provider: 'AWS',
|
79
|
+
aws_access_key_id: 'AWS_ID',
|
80
|
+
aws_secret_access_key: 'AWS_SECRET'
|
81
|
+
}
|
82
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
83
|
+
@dummy = Dummy.new
|
84
|
+
@dummy.id = 1
|
85
|
+
@dummy.avatar = @file
|
86
|
+
end
|
87
|
+
|
88
|
+
after { @file.close }
|
89
|
+
|
90
|
+
it "has correct path and url from interpolated defaults" do
|
91
|
+
assert_equal "dummies/avatars/000/000/001/original/5k.png", @dummy.avatar.path
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "with file params provided as lambda" do
|
96
|
+
before do
|
97
|
+
fog_file = lambda{ |a| { custom_header: a.instance.custom_method }}
|
98
|
+
klass = rebuild_model storage: :fog,
|
99
|
+
fog_file: fog_file
|
100
|
+
|
101
|
+
klass.class_eval do
|
102
|
+
def custom_method
|
103
|
+
'foobar'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
@dummy = Dummy.new
|
109
|
+
end
|
110
|
+
|
111
|
+
it "is able to evaluate correct values for file headers" do
|
112
|
+
assert_equal @dummy.avatar.send(:fog_file), { custom_header: 'foobar' }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
before do
|
117
|
+
@fog_directory = 'papercliptests'
|
118
|
+
|
119
|
+
@credentials = {
|
120
|
+
provider: 'AWS',
|
121
|
+
aws_access_key_id: 'ID',
|
122
|
+
aws_secret_access_key: 'SECRET'
|
123
|
+
}
|
124
|
+
|
125
|
+
@connection = Fog::Storage.new(@credentials)
|
126
|
+
@connection.directories.create(
|
127
|
+
key: @fog_directory
|
128
|
+
)
|
129
|
+
|
130
|
+
@options = {
|
131
|
+
fog_directory: @fog_directory,
|
132
|
+
fog_credentials: @credentials,
|
133
|
+
fog_host: nil,
|
134
|
+
fog_file: {cache_control: 1234},
|
135
|
+
path: ":attachment/:basename:dotextension",
|
136
|
+
storage: :fog
|
137
|
+
}
|
138
|
+
|
139
|
+
rebuild_model(@options)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "is extended by the Fog module" do
|
143
|
+
assert Dummy.new.avatar.is_a?(Paperclip::Storage::Fog)
|
144
|
+
end
|
145
|
+
|
146
|
+
context "when assigned" do
|
147
|
+
before do
|
148
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
149
|
+
@dummy = Dummy.new
|
150
|
+
@dummy.avatar = @file
|
151
|
+
end
|
152
|
+
|
153
|
+
after do
|
154
|
+
@file.close
|
155
|
+
directory = @connection.directories.new(key: @fog_directory)
|
156
|
+
directory.files.each {|file| file.destroy}
|
157
|
+
directory.destroy
|
158
|
+
end
|
159
|
+
|
160
|
+
it "is rewound after flush_writes" do
|
161
|
+
@dummy.avatar.instance_eval "def after_flush_writes; end"
|
162
|
+
|
163
|
+
files = @dummy.avatar.queued_for_write.values
|
164
|
+
@dummy.save
|
165
|
+
assert files.none?(&:eof?), "Expect all the files to be rewinded."
|
166
|
+
end
|
167
|
+
|
168
|
+
it "is removed after after_flush_writes" do
|
169
|
+
paths = @dummy.avatar.queued_for_write.values.map(&:path)
|
170
|
+
@dummy.save
|
171
|
+
assert paths.none?{ |path| File.exist?(path) },
|
172
|
+
"Expect all the files to be deleted."
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'is able to be copied to a local file' do
|
176
|
+
@dummy.save
|
177
|
+
tempfile = Tempfile.new("known_location")
|
178
|
+
tempfile.binmode
|
179
|
+
@dummy.avatar.copy_to_local_file(:original, tempfile.path)
|
180
|
+
tempfile.rewind
|
181
|
+
assert_equal @connection.directories.get(@fog_directory).files.get(@dummy.avatar.path).body,
|
182
|
+
tempfile.read
|
183
|
+
tempfile.close
|
184
|
+
end
|
185
|
+
|
186
|
+
it "passes the content type to the Fog::Storage::AWS::Files instance" do
|
187
|
+
Fog::Storage::AWS::Files.any_instance.expects(:create).with do |hash|
|
188
|
+
hash[:content_type]
|
189
|
+
end
|
190
|
+
@dummy.save
|
191
|
+
end
|
192
|
+
|
193
|
+
context "without a bucket" do
|
194
|
+
before do
|
195
|
+
@connection.directories.get(@fog_directory).destroy
|
196
|
+
end
|
197
|
+
|
198
|
+
it "creates the bucket" do
|
199
|
+
assert @dummy.save
|
200
|
+
assert @connection.directories.get(@fog_directory)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context "with a bucket" do
|
205
|
+
it "succeeds" do
|
206
|
+
assert @dummy.save
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context "without a fog_host" do
|
211
|
+
before do
|
212
|
+
rebuild_model(@options.merge(fog_host: nil))
|
213
|
+
@dummy = Dummy.new
|
214
|
+
@dummy.avatar = StringIO.new('.')
|
215
|
+
@dummy.save
|
216
|
+
end
|
217
|
+
|
218
|
+
it "provides a public url" do
|
219
|
+
assert !@dummy.avatar.url.nil?
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
context "with a fog_host" do
|
224
|
+
before do
|
225
|
+
rebuild_model(@options.merge(fog_host: 'http://example.com'))
|
226
|
+
@dummy = Dummy.new
|
227
|
+
@dummy.avatar = StringIO.new(".\n")
|
228
|
+
@dummy.save
|
229
|
+
end
|
230
|
+
|
231
|
+
it "provides a public url" do
|
232
|
+
expect(@dummy.avatar.url).to match(/^http:\/\/example\.com\/avatars\/data\?\d*$/)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context "with a fog_host that includes a wildcard placeholder" do
|
237
|
+
before do
|
238
|
+
rebuild_model(
|
239
|
+
fog_directory: @fog_directory,
|
240
|
+
fog_credentials: @credentials,
|
241
|
+
fog_host: 'http://img%d.example.com',
|
242
|
+
path: ":attachment/:basename:dotextension",
|
243
|
+
storage: :fog
|
244
|
+
)
|
245
|
+
@dummy = Dummy.new
|
246
|
+
@dummy.avatar = StringIO.new(".\n")
|
247
|
+
@dummy.save
|
248
|
+
end
|
249
|
+
|
250
|
+
it "provides a public url" do
|
251
|
+
expect(@dummy.avatar.url).to match(/^http:\/\/img[0123]\.example\.com\/avatars\/data\?\d*$/)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
context "with fog_public set to false" do
|
256
|
+
before do
|
257
|
+
rebuild_model(@options.merge(fog_public: false))
|
258
|
+
@dummy = Dummy.new
|
259
|
+
@dummy.avatar = StringIO.new('.')
|
260
|
+
@dummy.save
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'sets the @fog_public instance variable to false' do
|
264
|
+
assert_equal false, @dummy.avatar.instance_variable_get('@options')[:fog_public]
|
265
|
+
assert_equal false, @dummy.avatar.fog_public
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
context "with styles set and fog_public set to false" do
|
270
|
+
before do
|
271
|
+
rebuild_model(@options.merge(fog_public: false, styles: { medium: "300x300>", thumb: "100x100>" }))
|
272
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
273
|
+
@dummy = Dummy.new
|
274
|
+
@dummy.avatar = @file
|
275
|
+
@dummy.save
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'sets the @fog_public for a particular style to false' do
|
279
|
+
assert_equal false, @dummy.avatar.instance_variable_get('@options')[:fog_public]
|
280
|
+
assert_equal false, @dummy.avatar.fog_public(:thumb)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
context "with styles set and fog_public set per-style" do
|
285
|
+
before do
|
286
|
+
rebuild_model(@options.merge(fog_public: { medium: false, thumb: true}, styles: { medium: "300x300>", thumb: "100x100>" }))
|
287
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
288
|
+
@dummy = Dummy.new
|
289
|
+
@dummy.avatar = @file
|
290
|
+
@dummy.save
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'sets the fog_public for a particular style to correct value' do
|
294
|
+
assert_equal false, @dummy.avatar.fog_public(:medium)
|
295
|
+
assert_equal true, @dummy.avatar.fog_public(:thumb)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
context "with fog_public not set" do
|
300
|
+
before do
|
301
|
+
rebuild_model(@options)
|
302
|
+
@dummy = Dummy.new
|
303
|
+
@dummy.avatar = StringIO.new('.')
|
304
|
+
@dummy.save
|
305
|
+
end
|
306
|
+
|
307
|
+
it "defaults fog_public to true" do
|
308
|
+
assert_equal true, @dummy.avatar.fog_public
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context "with scheme set" do
|
313
|
+
before do
|
314
|
+
rebuild_model(@options.merge(:fog_credentials => @credentials.merge(:scheme => 'http')))
|
315
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
316
|
+
@dummy = Dummy.new
|
317
|
+
@dummy.avatar = @file
|
318
|
+
@dummy.save
|
319
|
+
end
|
320
|
+
|
321
|
+
it "honors the scheme in public url" do
|
322
|
+
assert_match(/^http:\/\//, @dummy.avatar.url)
|
323
|
+
end
|
324
|
+
it "honors the scheme in expiring url" do
|
325
|
+
assert_match(/^http:\/\//, @dummy.avatar.expiring_url)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
context "with scheme not set" do
|
330
|
+
before do
|
331
|
+
rebuild_model(@options)
|
332
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
333
|
+
@dummy = Dummy.new
|
334
|
+
@dummy.avatar = @file
|
335
|
+
@dummy.save
|
336
|
+
end
|
337
|
+
|
338
|
+
it "provides HTTPS public url" do
|
339
|
+
assert_match(/^https:\/\//, @dummy.avatar.url)
|
340
|
+
end
|
341
|
+
it "provides HTTPS expiring url" do
|
342
|
+
assert_match(/^https:\/\//, @dummy.avatar.expiring_url)
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
context "with a valid bucket name for a subdomain" do
|
347
|
+
before { @dummy.stubs(:new_record?).returns(false) }
|
348
|
+
|
349
|
+
it "provides an url in subdomain style" do
|
350
|
+
assert_match(/^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png/, @dummy.avatar.url)
|
351
|
+
end
|
352
|
+
|
353
|
+
it "provides an url that expires in subdomain style" do
|
354
|
+
assert_match(/^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
context "generating an expiring url" do
|
359
|
+
it "generates the same url when using Times and Integer offsets" do
|
360
|
+
Timecop.freeze do
|
361
|
+
offset = 1234
|
362
|
+
rebuild_model(@options)
|
363
|
+
dummy = Dummy.new
|
364
|
+
dummy.avatar = StringIO.new('.')
|
365
|
+
|
366
|
+
assert_equal dummy.avatar.expiring_url(offset),
|
367
|
+
dummy.avatar.expiring_url(Time.now + offset )
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'matches the default url if there is no assignment' do
|
372
|
+
dummy = Dummy.new
|
373
|
+
assert_equal dummy.avatar.url, dummy.avatar.expiring_url
|
374
|
+
end
|
375
|
+
|
376
|
+
it 'matches the default url when given a style if there is no assignment' do
|
377
|
+
dummy = Dummy.new
|
378
|
+
assert_equal dummy.avatar.url(:thumb), dummy.avatar.expiring_url(3600, :thumb)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
context "with an invalid bucket name for a subdomain" do
|
383
|
+
before do
|
384
|
+
rebuild_model(@options.merge(fog_directory: "this_is_invalid"))
|
385
|
+
@dummy = Dummy.new
|
386
|
+
@dummy.avatar = @file
|
387
|
+
@dummy.save
|
388
|
+
end
|
389
|
+
|
390
|
+
it "does not match the bucket-subdomain restrictions" do
|
391
|
+
invalid_subdomains = %w(this_is_invalid in iamareallylongbucketnameiamareallylongbucketnameiamareallylongbu invalid- inval..id inval-.id inval.-id -invalid 192.168.10.2)
|
392
|
+
invalid_subdomains.each do |name|
|
393
|
+
assert_no_match Paperclip::Storage::Fog::AWS_BUCKET_SUBDOMAIN_RESTRICTON_REGEX, name
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
it "provides an url in folder style" do
|
398
|
+
assert_match(/^https:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png\?\d*$/, @dummy.avatar.url)
|
399
|
+
end
|
400
|
+
|
401
|
+
it "provides a url that expires in folder style" do
|
402
|
+
assert_match(/^https:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url)
|
403
|
+
end
|
404
|
+
|
405
|
+
end
|
406
|
+
|
407
|
+
context "with a proc for a bucket name evaluating a model method" do
|
408
|
+
before do
|
409
|
+
@dynamic_fog_directory = 'dynamicpaperclip'
|
410
|
+
rebuild_model(@options.merge(fog_directory: lambda { |attachment| attachment.instance.bucket_name }))
|
411
|
+
@dummy = Dummy.new
|
412
|
+
@dummy.stubs(:bucket_name).returns(@dynamic_fog_directory)
|
413
|
+
@dummy.avatar = @file
|
414
|
+
@dummy.save
|
415
|
+
end
|
416
|
+
|
417
|
+
it "has created the bucket" do
|
418
|
+
assert @connection.directories.get(@dynamic_fog_directory).inspect
|
419
|
+
end
|
420
|
+
|
421
|
+
end
|
422
|
+
|
423
|
+
context "with a proc for the fog_host evaluating a model method" do
|
424
|
+
before do
|
425
|
+
rebuild_model(@options.merge(fog_host: lambda { |attachment| attachment.instance.fog_host }))
|
426
|
+
@dummy = Dummy.new
|
427
|
+
@dummy.stubs(:fog_host).returns('http://dynamicfoghost.com')
|
428
|
+
@dummy.avatar = @file
|
429
|
+
@dummy.save
|
430
|
+
end
|
431
|
+
|
432
|
+
it "provides a public url" do
|
433
|
+
assert_match(/http:\/\/dynamicfoghost\.com/, @dummy.avatar.url)
|
434
|
+
end
|
435
|
+
|
436
|
+
end
|
437
|
+
|
438
|
+
context "with a custom fog_host" do
|
439
|
+
before do
|
440
|
+
rebuild_model(@options.merge(fog_host: "http://dynamicfoghost.com"))
|
441
|
+
@dummy = Dummy.new
|
442
|
+
@dummy.avatar = @file
|
443
|
+
@dummy.save
|
444
|
+
end
|
445
|
+
|
446
|
+
it "provides a public url" do
|
447
|
+
assert_match(/http:\/\/dynamicfoghost\.com/, @dummy.avatar.url)
|
448
|
+
end
|
449
|
+
|
450
|
+
it "provides an expiring url" do
|
451
|
+
assert_match(/http:\/\/dynamicfoghost\.com/, @dummy.avatar.expiring_url)
|
452
|
+
end
|
453
|
+
|
454
|
+
context "with an invalid bucket name for a subdomain" do
|
455
|
+
before do
|
456
|
+
rebuild_model(@options.merge({fog_directory: "this_is_invalid", fog_host: "http://dynamicfoghost.com"}))
|
457
|
+
@dummy = Dummy.new
|
458
|
+
@dummy.avatar = @file
|
459
|
+
@dummy.save
|
460
|
+
end
|
461
|
+
|
462
|
+
it "provides an expiring url" do
|
463
|
+
assert_match(/http:\/\/dynamicfoghost\.com/, @dummy.avatar.expiring_url)
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
end
|
468
|
+
|
469
|
+
context "with a proc for the fog_credentials evaluating a model method" do
|
470
|
+
before do
|
471
|
+
@dynamic_fog_credentials = {
|
472
|
+
provider: 'AWS',
|
473
|
+
aws_access_key_id: 'DYNAMIC_ID',
|
474
|
+
aws_secret_access_key: 'DYNAMIC_SECRET'
|
475
|
+
}
|
476
|
+
rebuild_model(@options.merge(fog_credentials: lambda { |attachment| attachment.instance.fog_credentials }))
|
477
|
+
@dummy = Dummy.new
|
478
|
+
@dummy.stubs(:fog_credentials).returns(@dynamic_fog_credentials)
|
479
|
+
@dummy.avatar = @file
|
480
|
+
@dummy.save
|
481
|
+
end
|
482
|
+
|
483
|
+
it "provides a public url" do
|
484
|
+
assert_equal @dummy.avatar.fog_credentials, @dynamic_fog_credentials
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
context "with custom fog_options" do
|
489
|
+
before do
|
490
|
+
rebuild_model(
|
491
|
+
@options.merge(fog_options: { multipart_chunk_size: 104857600 }),
|
492
|
+
)
|
493
|
+
@dummy = Dummy.new
|
494
|
+
@dummy.avatar = @file
|
495
|
+
end
|
496
|
+
|
497
|
+
it "applies the options to the fog #create call" do
|
498
|
+
files = stub
|
499
|
+
@dummy.avatar.stubs(:directory).returns stub(files: files)
|
500
|
+
files.expects(:create).with(
|
501
|
+
has_entries(multipart_chunk_size: 104857600),
|
502
|
+
)
|
503
|
+
@dummy.save
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
end
|
509
|
+
|
510
|
+
context "when using local storage" do
|
511
|
+
before do
|
512
|
+
Fog.unmock!
|
513
|
+
rebuild_model styles: { medium: "300x300>", thumb: "100x100>" },
|
514
|
+
storage: :fog,
|
515
|
+
url: '/:attachment/:filename',
|
516
|
+
fog_directory: "paperclip",
|
517
|
+
fog_credentials: { provider: :local, local_root: "." },
|
518
|
+
fog_host: 'localhost'
|
519
|
+
|
520
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
521
|
+
@dummy = Dummy.new
|
522
|
+
@dummy.avatar = @file
|
523
|
+
@dummy.stubs(:new_record?).returns(false)
|
524
|
+
end
|
525
|
+
|
526
|
+
after do
|
527
|
+
@file.close
|
528
|
+
Fog.mock!
|
529
|
+
end
|
530
|
+
|
531
|
+
it "returns the public url in place of the expiring url" do
|
532
|
+
assert_match @dummy.avatar.public_url, @dummy.avatar.expiring_url
|
533
|
+
end
|
534
|
+
end
|
535
|
+
end
|