kt-paperclip 7.2.2 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +24 -56
  4. data/lib/generators/paperclip/paperclip_generator.rb +3 -1
  5. data/lib/kt-paperclip.rb +2 -0
  6. data/lib/paperclip/attachment.rb +49 -30
  7. data/lib/paperclip/attachment_registry.rb +2 -0
  8. data/lib/paperclip/callbacks.rb +7 -4
  9. data/lib/paperclip/commands/imagemagick/geometry_parser.rb +63 -0
  10. data/lib/paperclip/commands/imagemagick/version_detector.rb +41 -0
  11. data/lib/paperclip/commands/imagemagick.rb +44 -0
  12. data/lib/paperclip/commands/runner.rb +38 -0
  13. data/lib/paperclip/commands/unix_file.rb +28 -0
  14. data/lib/paperclip/content_type_detector.rb +31 -32
  15. data/lib/paperclip/errors.rb +2 -0
  16. data/lib/paperclip/file_command_content_type_detector.rb +11 -12
  17. data/lib/paperclip/filename_cleaner.rb +2 -0
  18. data/lib/paperclip/geometry.rb +22 -7
  19. data/lib/paperclip/geometry_detector_factory.rb +11 -31
  20. data/lib/paperclip/geometry_parser_factory.rb +13 -17
  21. data/lib/paperclip/glue.rb +2 -0
  22. data/lib/paperclip/has_attached_file.rb +2 -0
  23. data/lib/paperclip/helpers.rb +5 -25
  24. data/lib/paperclip/interpolations/plural_cache.rb +2 -0
  25. data/lib/paperclip/interpolations.rb +2 -0
  26. data/lib/paperclip/io_adapters/abstract_adapter.rb +3 -1
  27. data/lib/paperclip/io_adapters/attachment_adapter.rb +11 -0
  28. data/lib/paperclip/io_adapters/data_uri_adapter.rb +2 -0
  29. data/lib/paperclip/io_adapters/empty_string_adapter.rb +2 -0
  30. data/lib/paperclip/io_adapters/file_adapter.rb +2 -0
  31. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +2 -0
  32. data/lib/paperclip/io_adapters/identity_adapter.rb +2 -0
  33. data/lib/paperclip/io_adapters/nil_adapter.rb +2 -0
  34. data/lib/paperclip/io_adapters/registry.rb +2 -0
  35. data/lib/paperclip/io_adapters/stringio_adapter.rb +2 -0
  36. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +2 -0
  37. data/lib/paperclip/io_adapters/uri_adapter.rb +5 -13
  38. data/lib/paperclip/locales/fr.yml +18 -0
  39. data/lib/paperclip/locales/gd.yml +1 -1
  40. data/lib/paperclip/logger.rb +2 -0
  41. data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -0
  42. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +5 -3
  43. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -0
  44. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -0
  45. data/lib/paperclip/matchers.rb +2 -0
  46. data/lib/paperclip/media_type_spoof_detector.rb +3 -10
  47. data/lib/paperclip/missing_attachment_styles.rb +2 -0
  48. data/lib/paperclip/processor.rb +6 -19
  49. data/lib/paperclip/processor_helpers.rb +2 -0
  50. data/lib/paperclip/rails_environment.rb +2 -0
  51. data/lib/paperclip/railtie.rb +2 -0
  52. data/lib/paperclip/schema.rb +6 -4
  53. data/lib/paperclip/storage/filesystem.rb +2 -0
  54. data/lib/paperclip/storage/fog.rb +13 -4
  55. data/lib/paperclip/storage/s3.rb +27 -5
  56. data/lib/paperclip/storage.rb +2 -0
  57. data/lib/paperclip/style.rb +2 -0
  58. data/lib/paperclip/tempfile.rb +2 -0
  59. data/lib/paperclip/tempfile_factory.rb +2 -0
  60. data/lib/paperclip/thumbnail.rb +9 -10
  61. data/lib/paperclip/url_generator.rb +2 -0
  62. data/lib/paperclip/validators/attachment_content_type_validator.rb +2 -0
  63. data/lib/paperclip/validators/attachment_file_name_validator.rb +2 -0
  64. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +2 -0
  65. data/lib/paperclip/validators/attachment_presence_validator.rb +2 -0
  66. data/lib/paperclip/validators/attachment_size_validator.rb +2 -0
  67. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +2 -0
  68. data/lib/paperclip/validators.rb +2 -0
  69. data/lib/paperclip/version.rb +3 -1
  70. data/lib/paperclip.rb +25 -4
  71. data/lib/tasks/paperclip.rake +9 -4
  72. data/shoulda_macros/paperclip.rb +2 -0
  73. metadata +19 -538
  74. data/.codeclimate.yml +0 -17
  75. data/.github/FUNDING.yml +0 -3
  76. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  77. data/.github/ISSUE_TEMPLATE/custom.md +0 -10
  78. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  79. data/.gitignore +0 -19
  80. data/.hound.yml +0 -3
  81. data/.rubocop.yml +0 -1061
  82. data/.travis.yml +0 -45
  83. data/Appraisals +0 -30
  84. data/CONTRIBUTING.md +0 -85
  85. data/Gemfile +0 -19
  86. data/NEWS +0 -554
  87. data/RELEASING.md +0 -17
  88. data/Rakefile +0 -52
  89. data/UPGRADING +0 -17
  90. data/features/basic_integration.feature +0 -85
  91. data/features/migration.feature +0 -29
  92. data/features/rake_tasks.feature +0 -62
  93. data/features/step_definitions/attachment_steps.rb +0 -120
  94. data/features/step_definitions/html_steps.rb +0 -15
  95. data/features/step_definitions/rails_steps.rb +0 -257
  96. data/features/step_definitions/s3_steps.rb +0 -14
  97. data/features/step_definitions/web_steps.rb +0 -106
  98. data/features/support/env.rb +0 -12
  99. data/features/support/fakeweb.rb +0 -11
  100. data/features/support/file_helpers.rb +0 -34
  101. data/features/support/fixtures/boot_config.txt +0 -15
  102. data/features/support/fixtures/gemfile.txt +0 -5
  103. data/features/support/fixtures/preinitializer.txt +0 -20
  104. data/features/support/paths.rb +0 -28
  105. data/features/support/rails.rb +0 -39
  106. data/features/support/selectors.rb +0 -19
  107. data/gemfiles/4.2.gemfile +0 -20
  108. data/gemfiles/5.0.gemfile +0 -20
  109. data/gemfiles/5.1.gemfile +0 -20
  110. data/gemfiles/5.2.gemfile +0 -20
  111. data/gemfiles/6.0.gemfile +0 -20
  112. data/gemfiles/6.1.gemfile +0 -21
  113. data/gemfiles/7.0.gemfile +0 -21
  114. data/paperclip.gemspec +0 -50
  115. data/spec/database.yml +0 -4
  116. data/spec/paperclip/attachment_definitions_spec.rb +0 -13
  117. data/spec/paperclip/attachment_processing_spec.rb +0 -79
  118. data/spec/paperclip/attachment_registry_spec.rb +0 -158
  119. data/spec/paperclip/attachment_spec.rb +0 -1590
  120. data/spec/paperclip/content_type_detector_spec.rb +0 -54
  121. data/spec/paperclip/file_command_content_type_detector_spec.rb +0 -40
  122. data/spec/paperclip/filename_cleaner_spec.rb +0 -13
  123. data/spec/paperclip/geometry_detector_spec.rb +0 -47
  124. data/spec/paperclip/geometry_parser_spec.rb +0 -73
  125. data/spec/paperclip/geometry_spec.rb +0 -267
  126. data/spec/paperclip/glue_spec.rb +0 -63
  127. data/spec/paperclip/has_attached_file_spec.rb +0 -78
  128. data/spec/paperclip/integration_spec.rb +0 -702
  129. data/spec/paperclip/interpolations_spec.rb +0 -270
  130. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +0 -160
  131. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +0 -140
  132. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +0 -88
  133. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +0 -17
  134. data/spec/paperclip/io_adapters/file_adapter_spec.rb +0 -131
  135. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +0 -142
  136. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +0 -8
  137. data/spec/paperclip/io_adapters/nil_adapter_spec.rb +0 -25
  138. data/spec/paperclip/io_adapters/registry_spec.rb +0 -35
  139. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +0 -64
  140. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +0 -146
  141. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +0 -231
  142. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +0 -19
  143. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +0 -108
  144. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +0 -69
  145. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +0 -88
  146. data/spec/paperclip/media_type_spoof_detector_spec.rb +0 -126
  147. data/spec/paperclip/meta_class_spec.rb +0 -30
  148. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +0 -88
  149. data/spec/paperclip/paperclip_spec.rb +0 -196
  150. data/spec/paperclip/plural_cache_spec.rb +0 -37
  151. data/spec/paperclip/processor_helpers_spec.rb +0 -57
  152. data/spec/paperclip/processor_spec.rb +0 -26
  153. data/spec/paperclip/rails_environment_spec.rb +0 -30
  154. data/spec/paperclip/rake_spec.rb +0 -103
  155. data/spec/paperclip/schema_spec.rb +0 -252
  156. data/spec/paperclip/storage/filesystem_spec.rb +0 -102
  157. data/spec/paperclip/storage/fog_spec.rb +0 -606
  158. data/spec/paperclip/storage/s3_live_spec.rb +0 -188
  159. data/spec/paperclip/storage/s3_spec.rb +0 -1878
  160. data/spec/paperclip/style_spec.rb +0 -251
  161. data/spec/paperclip/tempfile_factory_spec.rb +0 -33
  162. data/spec/paperclip/tempfile_spec.rb +0 -35
  163. data/spec/paperclip/thumbnail_spec.rb +0 -504
  164. data/spec/paperclip/url_generator_spec.rb +0 -231
  165. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +0 -410
  166. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +0 -249
  167. data/spec/paperclip/validators/attachment_presence_validator_spec.rb +0 -85
  168. data/spec/paperclip/validators/attachment_size_validator_spec.rb +0 -325
  169. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +0 -48
  170. data/spec/paperclip/validators_spec.rb +0 -179
  171. data/spec/spec_helper.rb +0 -46
  172. data/spec/support/assertions.rb +0 -84
  173. data/spec/support/fake_model.rb +0 -24
  174. data/spec/support/fake_rails.rb +0 -12
  175. data/spec/support/fixtures/12k.png +0 -0
  176. data/spec/support/fixtures/50x50.png +0 -0
  177. data/spec/support/fixtures/5k.png +0 -0
  178. data/spec/support/fixtures/animated +0 -0
  179. data/spec/support/fixtures/animated.gif +0 -0
  180. data/spec/support/fixtures/animated.unknown +0 -0
  181. data/spec/support/fixtures/aws_s3.yml +0 -13
  182. data/spec/support/fixtures/bad.png +0 -1
  183. data/spec/support/fixtures/empty.html +0 -1
  184. data/spec/support/fixtures/empty.xlsx +0 -0
  185. data/spec/support/fixtures/fog.yml +0 -8
  186. data/spec/support/fixtures/rotated.jpg +0 -0
  187. data/spec/support/fixtures/s3.yml +0 -8
  188. data/spec/support/fixtures/sample.xlsm +0 -0
  189. data/spec/support/fixtures/spaced file.jpg +0 -0
  190. data/spec/support/fixtures/spaced file.png +0 -0
  191. data/spec/support/fixtures/text.txt +0 -1
  192. data/spec/support/fixtures/twopage.pdf +0 -0
  193. data/spec/support/fixtures/uppercase.PNG +0 -0
  194. data/spec/support/matchers/accept.rb +0 -5
  195. data/spec/support/matchers/exist.rb +0 -5
  196. data/spec/support/matchers/have_column.rb +0 -23
  197. data/spec/support/mock_attachment.rb +0 -24
  198. data/spec/support/mock_interpolator.rb +0 -24
  199. data/spec/support/mock_url_generator_builder.rb +0 -26
  200. data/spec/support/model_reconstruction.rb +0 -72
  201. data/spec/support/reporting.rb +0 -11
  202. data/spec/support/test_data.rb +0 -13
  203. data/spec/support/version_helper.rb +0 -9
@@ -1,1878 +0,0 @@
1
- require "spec_helper"
2
- require "aws-sdk-s3"
3
-
4
- describe Paperclip::Storage::S3 do
5
- before do
6
- Aws.config[:stub_responses] = true
7
- end
8
-
9
- def aws2_add_region
10
- { s3_region: "us-east-1" }
11
- end
12
-
13
- context "Parsing S3 credentials" do
14
- before do
15
- @proxy_settings = { host: "127.0.0.1", port: 8888, user: "foo", password: "bar" }
16
- rebuild_model aws2_add_region.merge storage: :s3,
17
- bucket: "testing",
18
- http_proxy: @proxy_settings,
19
- s3_credentials: { not: :important }
20
- @dummy = Dummy.new
21
- @avatar = @dummy.avatar
22
- end
23
-
24
- it "gets the correct credentials when RAILS_ENV is production" do
25
- rails_env("production") do
26
- assert_equal({ key: "12345" },
27
- @avatar.parse_credentials("production" => { key: "12345" },
28
- development: { key: "54321" }))
29
- end
30
- end
31
-
32
- it "gets the correct credentials when RAILS_ENV is development" do
33
- rails_env("development") do
34
- assert_equal({ key: "54321" },
35
- @avatar.parse_credentials("production" => { key: "12345" },
36
- development: { key: "54321" }))
37
- end
38
- end
39
-
40
- it "returns the argument if the key does not exist" do
41
- rails_env("not really an env") do
42
- assert_equal({ test: "12345" }, @avatar.parse_credentials(test: "12345"))
43
- end
44
- end
45
-
46
- it "supports HTTP proxy settings" do
47
- rails_env("development") do
48
- assert_equal(true, @avatar.using_http_proxy?)
49
- assert_equal(@proxy_settings[:host], @avatar.http_proxy_host)
50
- assert_equal(@proxy_settings[:port], @avatar.http_proxy_port)
51
- assert_equal(@proxy_settings[:user], @avatar.http_proxy_user)
52
- assert_equal(@proxy_settings[:password], @avatar.http_proxy_password)
53
- end
54
- end
55
- end
56
-
57
- context ":bucket option via :s3_credentials" do
58
- before do
59
- rebuild_model aws2_add_region.merge storage: :s3,
60
- s3_credentials: { bucket: "testing" }
61
- @dummy = Dummy.new
62
- end
63
-
64
- it "populates #bucket_name" do
65
- assert_equal @dummy.avatar.bucket_name, "testing"
66
- end
67
- end
68
-
69
- context ":bucket option" do
70
- before do
71
- rebuild_model aws2_add_region.merge storage: :s3,
72
- bucket: "testing", s3_credentials: {}
73
- @dummy = Dummy.new
74
- end
75
-
76
- it "populates #bucket_name" do
77
- assert_equal @dummy.avatar.bucket_name, "testing"
78
- end
79
- end
80
-
81
- context "missing :bucket option" do
82
- before do
83
- rebuild_model aws2_add_region.merge storage: :s3,
84
- http_proxy: @proxy_settings,
85
- s3_credentials: { not: :important }
86
-
87
- @dummy = Dummy.new
88
- @dummy.avatar = stringy_file
89
- end
90
-
91
- it "raises an argument error" do
92
- expect { @dummy.save }.to raise_error(ArgumentError, /missing required :bucket option/)
93
- end
94
- end
95
-
96
- context "" do
97
- before do
98
- rebuild_model aws2_add_region.merge storage: :s3,
99
- s3_credentials: {},
100
- bucket: "bucket",
101
- path: ":attachment/:basename:dotextension",
102
- url: ":s3_path_url"
103
- @dummy = Dummy.new
104
- @dummy.avatar = stringy_file
105
- allow(@dummy).to receive(:new_record?).and_return(false)
106
- end
107
-
108
- it "returns a url based on an S3 path" do
109
- assert_match %r{^//s3.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
110
- end
111
-
112
- it "uses the correct bucket" do
113
- assert_equal "bucket", @dummy.avatar.s3_bucket.name
114
- end
115
-
116
- it "uses the correct key" do
117
- assert_equal "avatars/data", @dummy.avatar.s3_object.key
118
- end
119
- end
120
-
121
- context "s3_protocol" do
122
- ["http", :http, ""].each do |protocol|
123
- context "as #{protocol.inspect}" do
124
- before do
125
- rebuild_model aws2_add_region.merge storage: :s3,
126
- s3_protocol: protocol
127
- @dummy = Dummy.new
128
- end
129
-
130
- it "returns the s3_protocol in string" do
131
- assert_equal protocol.to_s, @dummy.avatar.s3_protocol
132
- end
133
- end
134
- end
135
- end
136
-
137
- context "s3_protocol: 'https'" do
138
- before do
139
- rebuild_model aws2_add_region.merge storage: :s3,
140
- s3_credentials: {},
141
- s3_protocol: "https",
142
- bucket: "bucket",
143
- path: ":attachment/:basename:dotextension"
144
- @dummy = Dummy.new
145
- @dummy.avatar = stringy_file
146
- allow(@dummy).to receive(:new_record?).and_return(false)
147
- end
148
-
149
- it "returns a url based on an S3 path" do
150
- assert_match %r{^https://s3.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
151
- end
152
- end
153
-
154
- context "s3_protocol: ''" do
155
- before do
156
- rebuild_model aws2_add_region.merge storage: :s3,
157
- s3_credentials: {},
158
- s3_protocol: "",
159
- bucket: "bucket",
160
- path: ":attachment/:basename:dotextension"
161
- @dummy = Dummy.new
162
- @dummy.avatar = stringy_file
163
- allow(@dummy).to receive(:new_record?).and_return(false)
164
- end
165
-
166
- it "returns a protocol-relative URL" do
167
- assert_match %r{^//s3.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
168
- end
169
- end
170
-
171
- context "s3_protocol: :https" do
172
- before do
173
- rebuild_model aws2_add_region.merge storage: :s3,
174
- s3_credentials: {},
175
- s3_protocol: :https,
176
- bucket: "bucket",
177
- path: ":attachment/:basename:dotextension"
178
- @dummy = Dummy.new
179
- @dummy.avatar = stringy_file
180
- allow(@dummy).to receive(:new_record?).and_return(false)
181
- end
182
-
183
- it "returns a url based on an S3 path" do
184
- assert_match %r{^https://s3.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
185
- end
186
- end
187
-
188
- context "s3_protocol: ''" do
189
- before do
190
- rebuild_model aws2_add_region.merge storage: :s3,
191
- s3_credentials: {},
192
- s3_protocol: "",
193
- bucket: "bucket",
194
- path: ":attachment/:basename:dotextension"
195
- @dummy = Dummy.new
196
- @dummy.avatar = stringy_file
197
- allow(@dummy).to receive(:new_record?).and_return(false)
198
- end
199
-
200
- it "returns a url based on an S3 path" do
201
- assert_match %r{^//s3.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
202
- end
203
- end
204
-
205
- context "An attachment that uses S3 for storage and has the style in the path" do
206
- before do
207
- rebuild_model aws2_add_region.merge storage: :s3,
208
- bucket: "testing",
209
- path: ":attachment/:style/:basename:dotextension",
210
- styles: {
211
- thumb: "80x80>"
212
- },
213
- s3_credentials: {
214
- "access_key_id" => "12345",
215
- "secret_access_key" => "54321"
216
- }
217
-
218
- @dummy = Dummy.new
219
- @dummy.avatar = stringy_file
220
- @avatar = @dummy.avatar
221
- end
222
-
223
- it "uses an S3 object based on the correct path for the default style" do
224
- assert_equal("avatars/original/data", @dummy.avatar.s3_object.key)
225
- end
226
-
227
- it "uses an S3 object based on the correct path for the custom style" do
228
- assert_equal("avatars/thumb/data", @dummy.avatar.s3_object(:thumb).key)
229
- end
230
- end
231
-
232
- # the s3_host_name will be defined by the s3_region
233
- context "s3_host_name" do
234
- before do
235
- rebuild_model storage: :s3,
236
- s3_credentials: {},
237
- bucket: "bucket",
238
- path: ":attachment/:basename:dotextension",
239
- s3_host_name: "s3-ap-northeast-1.amazonaws.com",
240
- s3_region: "ap-northeast-1"
241
- @dummy = Dummy.new
242
- @dummy.avatar = stringy_file
243
- allow(@dummy).to receive(:new_record?).and_return(false)
244
- end
245
-
246
- it "returns a url based on an :s3_host_name path" do
247
- assert_match %r{^//s3-ap-northeast-1.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
248
- end
249
-
250
- it "uses the S3 bucket with the correct host name" do
251
- assert_equal "s3.ap-northeast-1.amazonaws.com",
252
- @dummy.avatar.s3_bucket.client.config.endpoint.host
253
- end
254
- end
255
-
256
- context "dynamic s3_host_name" do
257
- before do
258
- rebuild_model aws2_add_region.merge storage: :s3,
259
- s3_credentials: {},
260
- bucket: "bucket",
261
- path: ":attachment/:basename:dotextension",
262
- s3_host_name: lambda { |a| a.instance.value }
263
- @dummy = Dummy.new
264
- class << @dummy
265
- attr_accessor :value
266
- end
267
- @dummy.avatar = stringy_file
268
- allow(@dummy).to receive(:new_record?).and_return(false)
269
- end
270
-
271
- it "uses s3_host_name as a proc if available" do
272
- @dummy.value = "s3.something.com"
273
- assert_equal "//s3.something.com/bucket/avatars/data", @dummy.avatar.url(:original, timestamp: false)
274
- end
275
- end
276
-
277
- context "use_accelerate_endpoint" do
278
- context "defaults to false" do
279
- before do
280
- rebuild_model(
281
- storage: :s3,
282
- s3_credentials: {},
283
- bucket: "bucket",
284
- path: ":attachment/:basename:dotextension",
285
- s3_host_name: "s3-ap-northeast-1.amazonaws.com",
286
- s3_region: "ap-northeast-1"
287
- )
288
- @dummy = Dummy.new
289
- @dummy.avatar = stringy_file
290
- allow(@dummy).to receive(:new_record?).and_return(false)
291
- end
292
-
293
- it "returns a url based on an :s3_host_name path" do
294
- assert_match %r{^//s3-ap-northeast-1.amazonaws.com/bucket/avatars/data[^\.]},
295
- @dummy.avatar.url
296
- end
297
-
298
- it "uses the S3 client with the use_accelerate_endpoint config is false" do
299
- expect(@dummy.avatar.s3_bucket.client.config.use_accelerate_endpoint).to be(false)
300
- end
301
- end
302
-
303
- context "set to true" do
304
- before do
305
- rebuild_model(
306
- storage: :s3,
307
- s3_credentials: {},
308
- bucket: "bucket",
309
- path: ":attachment/:basename:dotextension",
310
- s3_host_name: "s3-accelerate.amazonaws.com",
311
- s3_region: "ap-northeast-1",
312
- use_accelerate_endpoint: true
313
- )
314
- @dummy = Dummy.new
315
- @dummy.avatar = stringy_file
316
- allow(@dummy).to receive(:new_record?).and_return(false)
317
- end
318
-
319
- it "returns a url based on an :s3_host_name path" do
320
- assert_match %r{^//s3-accelerate.amazonaws.com/bucket/avatars/data[^\.]},
321
- @dummy.avatar.url
322
- end
323
-
324
- it "uses the S3 client with the use_accelerate_endpoint config is true" do
325
- expect(@dummy.avatar.s3_bucket.client.config.use_accelerate_endpoint).to be(true)
326
- end
327
- end
328
- end
329
-
330
- context "An attachment that uses S3 for storage and has styles that return different file types" do
331
- before do
332
- rebuild_model aws2_add_region.merge storage: :s3,
333
- styles: { large: ["500x500#", :jpg] },
334
- bucket: "bucket",
335
- path: ":attachment/:basename:dotextension",
336
- s3_credentials: {
337
- "access_key_id" => "12345",
338
- "secret_access_key" => "54321"
339
- }
340
-
341
- File.open(fixture_file("5k.png"), "rb") do |file|
342
- @dummy = Dummy.new
343
- @dummy.avatar = file
344
- allow(@dummy).to receive(:new_record?).and_return(false)
345
- end
346
- end
347
-
348
- it "returns a url containing the correct original file mime type" do
349
- assert_match /.+\/5k.png/, @dummy.avatar.url
350
- end
351
-
352
- it "uses the correct key for the original file mime type" do
353
- assert_match /.+\/5k.png/, @dummy.avatar.s3_object.key
354
- end
355
-
356
- it "returns a url containing the correct processed file mime type" do
357
- assert_match /.+\/5k.jpg/, @dummy.avatar.url(:large)
358
- end
359
-
360
- it "uses the correct key for the processed file mime type" do
361
- assert_match /.+\/5k.jpg/, @dummy.avatar.s3_object(:large).key
362
- end
363
- end
364
-
365
- context "An attachment that uses S3 for storage and has a proc for styles" do
366
- before do
367
- rebuild_model aws2_add_region.merge storage: :s3,
368
- styles: lambda { |attachment|
369
- attachment.instance.counter
370
- { thumbnail: { geometry: "50x50#",
371
- s3_headers: { "Cache-Control" => "max-age=31557600" } } }
372
- },
373
- bucket: "bucket",
374
- path: ":attachment/:style/:basename:dotextension",
375
- s3_credentials: {
376
- "access_key_id" => "12345",
377
- "secret_access_key" => "54321"
378
- }
379
-
380
- @file = File.new(fixture_file("5k.png"), "rb")
381
-
382
- Dummy.class_eval do
383
- def counter
384
- @counter ||= 0
385
- @counter += 1
386
- @counter
387
- end
388
- end
389
-
390
- @dummy = Dummy.new
391
- @dummy.avatar = @file
392
-
393
- object = double
394
- allow(@dummy.avatar).to receive(:s3_object).with(:original).and_return(object)
395
- allow(@dummy.avatar).to receive(:s3_object).with(:thumbnail).and_return(object)
396
-
397
- expect(object).to receive(:upload_file).
398
- with(
399
- anything,
400
- {
401
- content_type: "image/png",
402
- acl: :"public-read",
403
- },
404
- )
405
- expect(object).to receive(:upload_file).
406
- with(
407
- anything,
408
- {
409
- content_type: "image/png",
410
- acl: :"public-read",
411
- cache_control: "max-age=31557600",
412
- },
413
- )
414
- @dummy.save
415
- end
416
-
417
- after { @file.close }
418
-
419
- it "succeeds" do
420
- assert_equal @dummy.counter, 7
421
- end
422
- end
423
-
424
- context "An attachment that uses S3 for storage with acl disabled" do
425
- before do
426
- rebuild_model(
427
- aws2_add_region.merge(
428
- storage: :s3,
429
- styles: { thumb: ["90x90#", :jpg] },
430
- bucket: "bucket",
431
- s3_acl_enabled: false,
432
- s3_credentials: {
433
- "access_key_id" => "12345",
434
- "secret_access_key" => "54321"
435
- }
436
- )
437
- )
438
-
439
- @file = File.new(fixture_file("5k.png"), "rb")
440
- @dummy = Dummy.new
441
- @dummy.avatar = @file
442
- @dummy.save
443
- end
444
-
445
- context "reprocess" do
446
- before do
447
- @object = double
448
- allow(@dummy.avatar).to receive(:s3_object).with(:original).and_return(@object)
449
- allow(@dummy.avatar).to receive(:s3_object).with(:thumb).and_return(@object)
450
- allow(@object).to receive(:get).and_yield(@file.read)
451
- allow(@object).to receive(:exists?).and_return(true)
452
- allow(@object).to receive(:download_file).with(anything)
453
- end
454
-
455
- it "uploads original" do
456
- expect(@object).to receive(:upload_file).with(
457
- anything,
458
- { content_type: "image/png" },
459
- ).and_return(true)
460
- @dummy.avatar.reprocess!
461
- expect(@object).to receive(:upload_file).with(
462
- anything,
463
- { content_type: "image/png" },
464
- ).and_return(true)
465
- @dummy.avatar.reprocess!
466
- end
467
-
468
- it "doesn't upload original" do
469
- expect(@object).to receive(:upload_file).with(
470
- anything,
471
- { content_type: "image/png" },
472
- ).and_return(true)
473
- @dummy.avatar.reprocess!
474
- end
475
- end
476
-
477
- after { @file.close }
478
- end
479
-
480
- context "An attachment that uses S3 for storage and has styles" do
481
- before do
482
- rebuild_model(
483
- aws2_add_region.merge(
484
- storage: :s3,
485
- styles: { thumb: ["90x90#", :jpg] },
486
- bucket: "bucket",
487
- s3_credentials: {
488
- "access_key_id" => "12345",
489
- "secret_access_key" => "54321"
490
- }
491
- )
492
- )
493
-
494
- @file = File.new(fixture_file("5k.png"), "rb")
495
- @dummy = Dummy.new
496
- @dummy.avatar = @file
497
- @dummy.save
498
- end
499
-
500
- context "reprocess" do
501
- before do
502
- @object = double
503
- allow(@dummy.avatar).to receive(:s3_object).with(:original).and_return(@object)
504
- allow(@dummy.avatar).to receive(:s3_object).with(:thumb).and_return(@object)
505
- allow(@object).to receive(:get).and_yield(@file.read)
506
- allow(@object).to receive(:exists?).and_return(true)
507
- allow(@object).to receive(:download_file).with(anything)
508
- end
509
-
510
- it "uploads original" do
511
- expect(@object).to receive(:upload_file).with(
512
- anything,
513
- {
514
- content_type: "image/png",
515
- acl: :"public-read",
516
- },
517
- ).and_return(true)
518
- @dummy.avatar.reprocess!
519
- expect(@object).to receive(:upload_file).with(
520
- anything,
521
- {
522
- content_type: "image/png",
523
- acl: :"public-read",
524
- },
525
- ).and_return(true)
526
- @dummy.avatar.reprocess!
527
- end
528
-
529
- it "doesn't upload original" do
530
- expect(@object).to receive(:upload_file).with(
531
- anything,
532
- {
533
- content_type: "image/png",
534
- acl: :"public-read",
535
- },
536
- ).and_return(true)
537
- @dummy.avatar.reprocess!
538
- end
539
- end
540
-
541
- after { @file.close }
542
- end
543
-
544
- context "An attachment that uses S3 for storage and has spaces in file name" do
545
- before do
546
- rebuild_model(
547
- aws2_add_region.merge(storage: :s3,
548
- styles: { large: ["500x500#", :jpg] },
549
- bucket: "bucket",
550
- s3_credentials: { "access_key_id" => "12345",
551
- "secret_access_key" => "54321" })
552
- )
553
-
554
- File.open(fixture_file("spaced file.png"), "rb") do |file|
555
- @dummy = Dummy.new
556
- @dummy.avatar = file
557
- allow(@dummy).to receive(:new_record?).and_return(false)
558
- end
559
- end
560
-
561
- it "returns a replaced version for path" do
562
- assert_match /.+\/spaced_file\.png/, @dummy.avatar.path
563
- end
564
-
565
- it "returns a replaced version for url" do
566
- assert_match /.+\/spaced_file\.png/, @dummy.avatar.url
567
- end
568
- end
569
-
570
- context "An attachment that uses S3 for storage and has a question mark in file name" do
571
- before do
572
- rebuild_model aws2_add_region.merge storage: :s3,
573
- styles: { large: ["500x500#", :jpg] },
574
- bucket: "bucket",
575
- s3_credentials: {
576
- "access_key_id" => "12345",
577
- "secret_access_key" => "54321"
578
- }
579
-
580
- stringio = stringy_file
581
- class << stringio
582
- def original_filename
583
- "question?mark.png"
584
- end
585
- end
586
- file = Paperclip.io_adapters.for(stringio, hash_digest: Digest::MD5)
587
- @dummy = Dummy.new
588
- @dummy.avatar = file
589
- @dummy.save
590
- allow(@dummy).to receive(:new_record?).and_return(false)
591
- end
592
-
593
- it "returns a replaced version for path" do
594
- assert_match /.+\/question_mark\.png/, @dummy.avatar.path
595
- end
596
-
597
- it "returns a replaced version for url" do
598
- assert_match /.+\/question_mark\.png/, @dummy.avatar.url
599
- end
600
- end
601
-
602
- context "" do
603
- before do
604
- rebuild_model aws2_add_region.merge storage: :s3,
605
- s3_credentials: {},
606
- bucket: "bucket",
607
- path: ":attachment/:basename:dotextension",
608
- url: ":s3_domain_url"
609
- @dummy = Dummy.new
610
- @dummy.avatar = stringy_file
611
- allow(@dummy).to receive(:new_record?).and_return(false)
612
- end
613
-
614
- it "returns a url based on an S3 subdomain" do
615
- assert_match %r{^//bucket.s3.amazonaws.com/avatars/data[^\.]}, @dummy.avatar.url
616
- end
617
- end
618
-
619
- context "" do
620
- before do
621
- rebuild_model(
622
- aws2_add_region.merge(storage: :s3,
623
- s3_credentials: {
624
- production: { bucket: "prod_bucket" },
625
- development: { bucket: "dev_bucket" }
626
- },
627
- bucket: "bucket",
628
- s3_host_alias: "something.something.com",
629
- path: ":attachment/:basename:dotextension",
630
- url: ":s3_alias_url")
631
- )
632
- @dummy = Dummy.new
633
- @dummy.avatar = stringy_file
634
- allow(@dummy).to receive(:new_record?).and_return(false)
635
- end
636
-
637
- it "returns a url based on the host_alias" do
638
- assert_match %r{^//something.something.com/avatars/data[^\.]}, @dummy.avatar.url
639
- end
640
- end
641
-
642
- context "generating a url with a prefixed host alias" do
643
- before do
644
- rebuild_model(
645
- aws2_add_region.merge(
646
- storage: :s3,
647
- s3_credentials: {
648
- production: { bucket: "prod_bucket" },
649
- development: { bucket: "dev_bucket" },
650
- },
651
- bucket: "bucket",
652
- s3_host_alias: "something.something.com",
653
- s3_prefixes_in_alias: 2,
654
- path: "prefix1/prefix2/:attachment/:basename:dotextension",
655
- url: ":s3_alias_url"
656
- )
657
- )
658
- @dummy = Dummy.new
659
- @dummy.avatar = stringy_file
660
- allow(@dummy).to receive(:new_record?).and_return(false)
661
- end
662
-
663
- it "returns a url with the prefixes removed" do
664
- assert_match %r{^//something.something.com/avatars/data[^\.]},
665
- @dummy.avatar.url
666
- end
667
- end
668
-
669
- context "generating a url with a proc as the host alias" do
670
- before do
671
- rebuild_model aws2_add_region.merge storage: :s3,
672
- s3_credentials: { bucket: "prod_bucket" },
673
- s3_host_alias: Proc.new { |atch| "cdn#{atch.instance.counter % 4}.example.com" },
674
- path: ":attachment/:basename:dotextension",
675
- url: ":s3_alias_url"
676
- Dummy.class_eval do
677
- def counter
678
- @counter ||= 0
679
- @counter += 1
680
- @counter
681
- end
682
- end
683
- @dummy = Dummy.new
684
- @dummy.avatar = stringy_file
685
- allow(@dummy).to receive(:new_record?).and_return(false)
686
- end
687
-
688
- it "returns a url based on the host_alias" do
689
- assert_match %r{^//cdn1.example.com/avatars/data[^\.]}, @dummy.avatar.url
690
- assert_match %r{^//cdn2.example.com/avatars/data[^\.]}, @dummy.avatar.url
691
- end
692
-
693
- it "still returns the bucket name" do
694
- assert_equal "prod_bucket", @dummy.avatar.bucket_name
695
- end
696
- end
697
-
698
- context "" do
699
- before do
700
- rebuild_model aws2_add_region.merge storage: :s3,
701
- s3_credentials: {},
702
- bucket: "bucket",
703
- path: ":attachment/:basename:dotextension",
704
- url: ":asset_host"
705
- @dummy = Dummy.new
706
- @dummy.avatar = stringy_file
707
- allow(@dummy).to receive(:new_record?).and_return(false)
708
- end
709
-
710
- it "returns a relative URL for Rails to calculate assets host" do
711
- assert_match %r{^avatars/data[^\.]}, @dummy.avatar.url
712
- end
713
- end
714
-
715
- context "Generating a secure url with an expiration" do
716
- before do
717
- @build_model_with_options = lambda { |options|
718
- base_options = {
719
- storage: :s3,
720
- s3_credentials: {
721
- production: { bucket: "prod_bucket" },
722
- development: { bucket: "dev_bucket" }
723
- },
724
- s3_host_alias: "something.something.com",
725
- s3_permissions: "private",
726
- path: ":attachment/:basename:dotextension",
727
- url: ":s3_alias_url"
728
- }
729
-
730
- rebuild_model aws2_add_region.merge base_options.merge(options)
731
- }
732
- end
733
-
734
- it "uses default options" do
735
- @build_model_with_options[{}]
736
-
737
- rails_env("production") do
738
- @dummy = Dummy.new
739
- @dummy.avatar = stringy_file
740
-
741
- object = double
742
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
743
-
744
- expect(object).to receive(:presigned_url).with(:get, { expires_in: 3600 })
745
- @dummy.avatar.expiring_url
746
- end
747
- end
748
-
749
- it "allows overriding s3_url_options" do
750
- @build_model_with_options[s3_url_options: { response_content_disposition: "inline" }]
751
-
752
- rails_env("production") do
753
- @dummy = Dummy.new
754
- @dummy.avatar = stringy_file
755
-
756
- object = double
757
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
758
- expect(object).to receive(:presigned_url).
759
- with(
760
- :get,
761
- {
762
- expires_in: 3600,
763
- response_content_disposition: "inline",
764
- },
765
- )
766
- @dummy.avatar.expiring_url
767
- end
768
- end
769
-
770
- it "allows overriding s3_object options with a proc" do
771
- @build_model_with_options[s3_url_options: lambda { |attachment| { response_content_type: attachment.avatar_content_type } }]
772
-
773
- rails_env("production") do
774
- @dummy = Dummy.new
775
-
776
- @file = stringy_file
777
- allow(@file).to receive(:original_filename).and_return("5k.png\n\n")
778
- allow(Paperclip).to receive(:run).and_return("image/png")
779
- allow(@file).to receive(:content_type).and_return("image/png\n\n")
780
- allow(@file).to receive(:to_tempfile).and_return(@file)
781
-
782
- @dummy.avatar = @file
783
-
784
- object = double
785
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
786
- expect(object).to receive(:presigned_url).
787
- with(
788
- :get,
789
- {
790
- expires_in: 3600,
791
- response_content_type: "image/png",
792
- },
793
- )
794
- @dummy.avatar.expiring_url
795
- end
796
- end
797
- end
798
-
799
- context "#expiring_url" do
800
- before { @dummy = Dummy.new }
801
-
802
- context "with no attachment" do
803
- before { assert(!@dummy.avatar.exists?) }
804
-
805
- it "returns the default URL" do
806
- assert_equal(@dummy.avatar.url, @dummy.avatar.expiring_url)
807
- end
808
-
809
- it "generates a url for a style when a file does not exist" do
810
- assert_equal(@dummy.avatar.url(:thumb), @dummy.avatar.expiring_url(3600, :thumb))
811
- end
812
- end
813
-
814
- it "generates the same url when using Times and Integer offsets" do
815
- assert_equal @dummy.avatar.expiring_url(1234), @dummy.avatar.expiring_url(Time.now + 1234)
816
- end
817
- end
818
-
819
- context "Generating a url with an expiration for each style" do
820
- before do
821
- rebuild_model aws2_add_region.merge storage: :s3,
822
- s3_credentials: {
823
- production: { bucket: "prod_bucket" },
824
- development: { bucket: "dev_bucket" }
825
- },
826
- s3_permissions: :private,
827
- s3_host_alias: "something.something.com",
828
- path: ":attachment/:style/:basename:dotextension",
829
- url: ":s3_alias_url"
830
-
831
- rails_env("production") do
832
- @dummy = Dummy.new
833
- @dummy.avatar = stringy_file
834
- end
835
- end
836
-
837
- it "generates a url for the thumb" do
838
- object = double
839
- allow(@dummy.avatar).to receive(:s3_object).with(:thumb).and_return(object)
840
- expect(object).to receive(:presigned_url).with(:get, { expires_in: 1800 })
841
- @dummy.avatar.expiring_url(1800, :thumb)
842
- end
843
-
844
- it "generates a url for the default style" do
845
- object = double
846
- allow(@dummy.avatar).to receive(:s3_object).with(:original).and_return(object)
847
- expect(object).to receive(:presigned_url).with(:get, { expires_in: 1800 })
848
- @dummy.avatar.expiring_url(1800)
849
- end
850
- end
851
-
852
- context "Parsing S3 credentials with a bucket in them" do
853
- before do
854
- rebuild_model aws2_add_region.merge storage: :s3,
855
- s3_credentials: {
856
- production: { bucket: "prod_bucket" },
857
- development: { bucket: "dev_bucket" }
858
- }
859
- @dummy = Dummy.new
860
- end
861
-
862
- it "gets the right bucket in production" do
863
- rails_env("production") do
864
- assert_equal "prod_bucket", @dummy.avatar.bucket_name
865
- assert_equal "prod_bucket", @dummy.avatar.s3_bucket.name
866
- end
867
- end
868
-
869
- it "gets the right bucket in development" do
870
- rails_env("development") do
871
- assert_equal "dev_bucket", @dummy.avatar.bucket_name
872
- assert_equal "dev_bucket", @dummy.avatar.s3_bucket.name
873
- end
874
- end
875
- end
876
-
877
- # the bucket.name is determined by the :s3_region
878
- context "Parsing S3 credentials with a s3_host_name in them" do
879
- before do
880
- rebuild_model storage: :s3,
881
- bucket: "testing",
882
- s3_credentials: {
883
- production: {
884
- s3_region: "world-end",
885
- s3_host_name: "s3-world-end.amazonaws.com"
886
- },
887
- development: {
888
- s3_region: "ap-northeast-1",
889
- s3_host_name: "s3-ap-northeast-1.amazonaws.com"
890
- },
891
- test: {}
892
- }
893
- @dummy = Dummy.new
894
- end
895
-
896
- it "gets the right s3_host_name in production" do
897
- rails_env("production") do
898
- assert_match %r{^s3-world-end.amazonaws.com}, @dummy.avatar.s3_host_name
899
- assert_match %r{^s3.world-end.amazonaws.com},
900
- @dummy.avatar.s3_bucket.client.config.endpoint.host
901
- end
902
- end
903
-
904
- it "gets the right s3_host_name in development" do
905
- rails_env("development") do
906
- assert_match %r{^s3.ap-northeast-1.amazonaws.com},
907
- @dummy.avatar.s3_host_name
908
- assert_match %r{^s3.ap-northeast-1.amazonaws.com},
909
- @dummy.avatar.s3_bucket.client.config.endpoint.host
910
- end
911
- end
912
-
913
- it "gets the right s3_host_name if the key does not exist" do
914
- rails_env("test") do
915
- assert_match %r{^s3.amazonaws.com}, @dummy.avatar.s3_host_name
916
- assert_raises(Aws::Errors::MissingRegionError) do
917
- @dummy.avatar.s3_bucket.client.config.endpoint.host
918
- end
919
- end
920
- end
921
- end
922
-
923
- context "An attachment with S3 storage" do
924
- before do
925
- rebuild_model aws2_add_region.merge storage: :s3,
926
- bucket: "testing",
927
- path: ":attachment/:style/:basename:dotextension",
928
- s3_credentials: {
929
- access_key_id: "12345",
930
- secret_access_key: "54321"
931
- }
932
- end
933
-
934
- it "is extended by the S3 module" do
935
- assert Dummy.new.avatar.is_a?(Paperclip::Storage::S3)
936
- end
937
-
938
- it "won't be extended by the Filesystem module" do
939
- assert !Dummy.new.avatar.is_a?(Paperclip::Storage::Filesystem)
940
- end
941
-
942
- context "when assigned" do
943
- before do
944
- @file = File.new(fixture_file("5k.png"), "rb")
945
- @dummy = Dummy.new
946
- @dummy.avatar = @file
947
- allow(@dummy).to receive(:new_record?).and_return(false)
948
- end
949
-
950
- after { @file.close }
951
-
952
- it "does not get a bucket to get a URL" do
953
- expect(@dummy.avatar).to_not receive(:s3)
954
- expect(@dummy.avatar).to_not receive(:s3_bucket)
955
- assert_match %r{^//s3\.amazonaws\.com/testing/avatars/original/5k\.png}, @dummy.avatar.url
956
- end
957
-
958
- it "is rewound after flush_writes" do
959
- @dummy.avatar.instance_eval "def after_flush_writes; end"
960
- allow(@dummy.avatar).to receive(:s3_object).and_return(double(upload_file: true))
961
- files = @dummy.avatar.queued_for_write.values.each(&:read)
962
- @dummy.save
963
- assert files.none?(&:eof?), "Expect all the files to be rewound."
964
- end
965
-
966
- it "is removed after after_flush_writes" do
967
- allow(@dummy.avatar).to receive(:s3_object).and_return(double(upload_file: true))
968
- paths = @dummy.avatar.queued_for_write.values.map(&:path)
969
- @dummy.save
970
- assert paths.none? { |path| File.exist?(path) },
971
- "Expect all the files to be deleted."
972
- end
973
-
974
- it "will retry to save again but back off on SlowDown" do
975
- allow(@dummy.avatar).to receive(:sleep)
976
- allow_any_instance_of(Aws::S3::Object).to receive(:upload_file).
977
- and_raise(Aws::S3::Errors::SlowDown.new(spy,
978
- spy(status: 503, body: "")))
979
- expect { @dummy.save }.to raise_error(Aws::S3::Errors::SlowDown)
980
- expect(@dummy.avatar).to have_received(:sleep).with(1)
981
- expect(@dummy.avatar).to have_received(:sleep).with(2)
982
- expect(@dummy.avatar).to have_received(:sleep).with(4)
983
- expect(@dummy.avatar).to have_received(:sleep).with(8)
984
- expect(@dummy.avatar).to have_received(:sleep).with(16)
985
- end
986
-
987
- context "and saved" do
988
- before do
989
- object = double
990
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
991
- expect(object).to receive(:upload_file).
992
- with(anything, { content_type: "image/png", acl: :"public-read" })
993
- @dummy.save
994
- end
995
-
996
- it "succeeds" do
997
- assert true
998
- end
999
- end
1000
-
1001
- context "and saved without a bucket" do
1002
- before do
1003
- allow_any_instance_of(Aws::S3::Object).to receive(:upload_file).
1004
- and_raise(Aws::S3::Errors::NoSuchBucket.new(double, double(status: 404, body: "<foo/>", empty?: false)))
1005
- allow_any_instance_of(Aws::S3::Object).to receive(:upload_file).and_return(nil)
1006
- @dummy.save
1007
- end
1008
-
1009
- it "succeeds" do
1010
- assert true
1011
- end
1012
- end
1013
-
1014
- context "and remove" do
1015
- before do
1016
- allow_any_instance_of(Aws::S3::Object).to receive(:exists?).and_return(true)
1017
- allow_any_instance_of(Aws::S3::Object).to receive(:delete)
1018
- @dummy.destroy
1019
- end
1020
-
1021
- it "succeeds" do
1022
- assert true
1023
- end
1024
- end
1025
-
1026
- context "and remove, calling S3 Object destroy once per unique style" do
1027
- before do
1028
- allow_any_instance_of(Aws::S3::Object).to receive(:exists?).and_return(true)
1029
- expect_any_instance_of(Aws::S3::Object).to receive(:delete).once
1030
- @dummy.avatar.clear(:original)
1031
- @dummy.destroy
1032
- end
1033
-
1034
- it "succeeds" do
1035
- assert true
1036
- end
1037
- end
1038
-
1039
- context "that the file were missing" do
1040
- before do
1041
- allow_any_instance_of(Aws::S3::Object).to receive(:exists?).
1042
- and_raise(Aws::S3::Errors::ServiceError.new("rspec stub raises",
1043
- "object exists?"))
1044
- end
1045
-
1046
- it "returns false on exists?" do
1047
- assert !@dummy.avatar.exists?
1048
- end
1049
- end
1050
- end
1051
- end
1052
-
1053
- context "An attachment with S3 storage and bucket defined as a Proc" do
1054
- before do
1055
- rebuild_model aws2_add_region.merge storage: :s3,
1056
- bucket: lambda { |attachment| "bucket_#{attachment.instance.other}" },
1057
- s3_credentials: { not: :important }
1058
- end
1059
-
1060
- it "gets the right bucket name" do
1061
- assert "bucket_a", Dummy.new(other: "a").avatar.bucket_name
1062
- assert "bucket_a", Dummy.new(other: "a").avatar.s3_bucket.name
1063
- assert "bucket_b", Dummy.new(other: "b").avatar.bucket_name
1064
- assert "bucket_b", Dummy.new(other: "b").avatar.s3_bucket.name
1065
- end
1066
- end
1067
-
1068
- context "An attachment with S3 storage and S3 credentials defined as a Proc" do
1069
- before do
1070
- rebuild_model aws2_add_region.merge storage: :s3,
1071
- bucket: { not: :important },
1072
- s3_credentials: lambda { |attachment|
1073
- Hash["access_key_id" => "access#{attachment.instance.other}", "secret_access_key" => "secret#{attachment.instance.other}"]
1074
- }
1075
- end
1076
-
1077
- it "gets the right credentials" do
1078
- assert "access1234", Dummy.new(other: "1234").avatar.s3_credentials[:access_key_id]
1079
- assert "secret1234", Dummy.new(other: "1234").avatar.s3_credentials[:secret_access_key]
1080
- end
1081
- end
1082
-
1083
- context "An attachment with S3 storage and S3 credentials with a :credential_provider" do
1084
- before do
1085
- class DummyCredentialProvider; end
1086
-
1087
- rebuild_model aws2_add_region.merge storage: :s3,
1088
- bucket: "testing",
1089
- s3_credentials: {
1090
- credentials: DummyCredentialProvider.new
1091
- }
1092
- @dummy = Dummy.new
1093
- end
1094
-
1095
- it "sets the credential-provider" do
1096
- expect(@dummy.avatar.s3_bucket.client.config.credentials).to be_a DummyCredentialProvider
1097
- end
1098
- end
1099
-
1100
- context "An attachment with S3 storage and S3 credentials in an unsupported manor" do
1101
- before do
1102
- rebuild_model aws2_add_region.merge storage: :s3,
1103
- bucket: "testing", s3_credentials: ["unsupported"]
1104
- @dummy = Dummy.new
1105
- end
1106
-
1107
- it "does not accept the credentials" do
1108
- assert_raises(ArgumentError) do
1109
- @dummy.avatar.s3_credentials
1110
- end
1111
- end
1112
- end
1113
-
1114
- context "An attachment with S3 storage and S3 credentials not supplied" do
1115
- before do
1116
- rebuild_model aws2_add_region.merge storage: :s3, bucket: "testing"
1117
- @dummy = Dummy.new
1118
- end
1119
-
1120
- it "does not parse any credentials" do
1121
- assert_equal({}, @dummy.avatar.s3_credentials)
1122
- end
1123
- end
1124
-
1125
- context "An attachment with S3 storage and specific s3 headers set" do
1126
- before do
1127
- rebuild_model aws2_add_region.merge storage: :s3,
1128
- bucket: "testing",
1129
- path: ":attachment/:style/:basename:dotextension",
1130
- s3_credentials: {
1131
- "access_key_id" => "12345",
1132
- "secret_access_key" => "54321"
1133
- },
1134
- s3_headers: { "Cache-Control" => "max-age=31557600" }
1135
- end
1136
-
1137
- context "when assigned" do
1138
- before do
1139
- @file = File.new(fixture_file("5k.png"), "rb")
1140
- @dummy = Dummy.new
1141
- @dummy.avatar = @file
1142
- end
1143
-
1144
- after { @file.close }
1145
-
1146
- context "and saved" do
1147
- before do
1148
- object = double
1149
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
1150
-
1151
- expect(object).to receive(:upload_file).
1152
- with(
1153
- anything,
1154
- {
1155
- content_type: "image/png",
1156
- acl: :"public-read",
1157
- cache_control: "max-age=31557600",
1158
- },
1159
- )
1160
- @dummy.save
1161
- end
1162
-
1163
- it "succeeds" do
1164
- assert true
1165
- end
1166
- end
1167
- end
1168
- end
1169
-
1170
- context "An attachment with S3 storage and metadata set using header names" do
1171
- before do
1172
- rebuild_model aws2_add_region.merge storage: :s3,
1173
- bucket: "testing",
1174
- path: ":attachment/:style/:basename:dotextension",
1175
- s3_credentials: {
1176
- "access_key_id" => "12345",
1177
- "secret_access_key" => "54321"
1178
- },
1179
- s3_headers: { "x-amz-meta-color" => "red" }
1180
- end
1181
-
1182
- context "when assigned" do
1183
- before do
1184
- @file = File.new(fixture_file("5k.png"), "rb")
1185
- @dummy = Dummy.new
1186
- @dummy.avatar = @file
1187
- end
1188
-
1189
- after { @file.close }
1190
-
1191
- context "and saved" do
1192
- before do
1193
- object = double
1194
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
1195
-
1196
- expect(object).to receive(:upload_file).
1197
- with(
1198
- anything,
1199
- {
1200
- content_type: "image/png",
1201
- acl: :"public-read",
1202
- metadata: { "color" => "red" },
1203
- },
1204
- )
1205
- @dummy.save
1206
- end
1207
-
1208
- it "succeeds" do
1209
- assert true
1210
- end
1211
- end
1212
- end
1213
- end
1214
-
1215
- context "An attachment with S3 storage and metadata set using the :s3_metadata option" do
1216
- before do
1217
- rebuild_model aws2_add_region.merge storage: :s3,
1218
- bucket: "testing",
1219
- path: ":attachment/:style/:basename:dotextension",
1220
- s3_credentials: {
1221
- "access_key_id" => "12345",
1222
- "secret_access_key" => "54321"
1223
- },
1224
- s3_metadata: { "color" => "red" }
1225
- end
1226
-
1227
- context "when assigned" do
1228
- before do
1229
- @file = File.new(fixture_file("5k.png"), "rb")
1230
- @dummy = Dummy.new
1231
- @dummy.avatar = @file
1232
- end
1233
-
1234
- after { @file.close }
1235
-
1236
- context "and saved" do
1237
- before do
1238
- object = double
1239
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
1240
-
1241
- expect(object).to receive(:upload_file).
1242
- with(
1243
- anything,
1244
- {
1245
- content_type: "image/png",
1246
- acl: :"public-read",
1247
- metadata: { "color" => "red" },
1248
- },
1249
- )
1250
- @dummy.save
1251
- end
1252
-
1253
- it "succeeds" do
1254
- assert true
1255
- end
1256
- end
1257
- end
1258
- end
1259
-
1260
- context "An attachment with S3 storage and storage class set" do
1261
- context "using the header name" do
1262
- before do
1263
- rebuild_model aws2_add_region.merge storage: :s3,
1264
- bucket: "testing",
1265
- path: ":attachment/:style/:basename:dotextension",
1266
- s3_credentials: {
1267
- "access_key_id" => "12345",
1268
- "secret_access_key" => "54321"
1269
- },
1270
- s3_headers: { "x-amz-storage-class" => "reduced_redundancy" }
1271
- end
1272
-
1273
- context "when assigned" do
1274
- before do
1275
- @file = File.new(fixture_file("5k.png"), "rb")
1276
- @dummy = Dummy.new
1277
- @dummy.avatar = @file
1278
- end
1279
-
1280
- after { @file.close }
1281
-
1282
- context "and saved" do
1283
- before do
1284
- object = double
1285
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
1286
-
1287
- expect(object).to receive(:upload_file).
1288
- with(
1289
- anything,
1290
- {
1291
- content_type: "image/png",
1292
- acl: :"public-read",
1293
- storage_class: "reduced_redundancy",
1294
- },
1295
- )
1296
- @dummy.save
1297
- end
1298
-
1299
- it "succeeds" do
1300
- assert true
1301
- end
1302
- end
1303
- end
1304
- end
1305
-
1306
- context "using per style hash" do
1307
- before do
1308
- rebuild_model aws2_add_region.merge storage: :s3,
1309
- bucket: "testing",
1310
- path: ":attachment/:style/:basename.:extension",
1311
- styles: {
1312
- thumb: "80x80>"
1313
- },
1314
- s3_credentials: {
1315
- "access_key_id" => "12345",
1316
- "secret_access_key" => "54321"
1317
- },
1318
- s3_storage_class: {
1319
- thumb: :reduced_redundancy
1320
- }
1321
- end
1322
-
1323
- context "when assigned" do
1324
- before do
1325
- @file = File.new(fixture_file("5k.png"), "rb")
1326
- @dummy = Dummy.new
1327
- @dummy.avatar = @file
1328
- end
1329
-
1330
- after { @file.close }
1331
-
1332
- context "and saved" do
1333
- before do
1334
- object = double
1335
- [:thumb, :original].each do |style|
1336
- allow(@dummy.avatar).to receive(:s3_object).with(style).and_return(object)
1337
-
1338
- expected_options = {
1339
- content_type: "image/png",
1340
- acl: :"public-read"
1341
- }
1342
- expected_options.merge!(storage_class: :reduced_redundancy) if style == :thumb
1343
-
1344
- expect(object).to receive(:upload_file).
1345
- with(anything, expected_options)
1346
- end
1347
- @dummy.save
1348
- end
1349
-
1350
- it "succeeds" do
1351
- assert true
1352
- end
1353
- end
1354
- end
1355
- end
1356
-
1357
- context "using global hash option" do
1358
- before do
1359
- rebuild_model aws2_add_region.merge storage: :s3,
1360
- bucket: "testing",
1361
- path: ":attachment/:style/:basename.:extension",
1362
- styles: {
1363
- thumb: "80x80>"
1364
- },
1365
- s3_credentials: {
1366
- "access_key_id" => "12345",
1367
- "secret_access_key" => "54321"
1368
- },
1369
- s3_storage_class: :reduced_redundancy
1370
- end
1371
-
1372
- context "when assigned" do
1373
- before do
1374
- @file = File.new(fixture_file("5k.png"), "rb")
1375
- @dummy = Dummy.new
1376
- @dummy.avatar = @file
1377
- end
1378
-
1379
- after { @file.close }
1380
-
1381
- context "and saved" do
1382
- before do
1383
- object = double
1384
- [:thumb, :original].each do |style|
1385
- allow(@dummy.avatar).to receive(:s3_object).with(style).and_return(object)
1386
-
1387
- expect(object).to receive(:upload_file).
1388
- with(
1389
- anything,
1390
- {
1391
- content_type: "image/png",
1392
- acl: :"public-read",
1393
- storage_class: :reduced_redundancy,
1394
- },
1395
- )
1396
- end
1397
- @dummy.save
1398
- end
1399
-
1400
- it "succeeds" do
1401
- assert true
1402
- end
1403
- end
1404
- end
1405
- end
1406
- end
1407
-
1408
- context "Can disable AES256 encryption multiple ways" do
1409
- [nil, false, ""].each do |tech|
1410
- before do
1411
- rebuild_model(
1412
- aws2_add_region.merge(storage: :s3,
1413
- bucket: "testing",
1414
- path: ":attachment/:style/:basename:dotextension",
1415
- s3_credentials: {
1416
- "access_key_id" => "12345",
1417
- "secret_access_key" => "54321"
1418
- },
1419
- s3_server_side_encryption: tech)
1420
- )
1421
- end
1422
-
1423
- context "when assigned" do
1424
- before do
1425
- @file = File.new(fixture_file("5k.png"), "rb")
1426
- @dummy = Dummy.new
1427
- @dummy.avatar = @file
1428
- end
1429
-
1430
- after { @file.close }
1431
-
1432
- context "and saved" do
1433
- before do
1434
- object = double
1435
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
1436
-
1437
- expect(object).to receive(:upload_file).
1438
- with(anything, { content_type: "image/png", acl: :"public-read" })
1439
- @dummy.save
1440
- end
1441
-
1442
- it "succeeds" do
1443
- assert true
1444
- end
1445
- end
1446
- end
1447
- end
1448
- end
1449
-
1450
- context "An attachment with S3 storage and using AES256 encryption" do
1451
- before do
1452
- rebuild_model aws2_add_region.merge storage: :s3,
1453
- bucket: "testing",
1454
- path: ":attachment/:style/:basename:dotextension",
1455
- s3_credentials: {
1456
- "access_key_id" => "12345",
1457
- "secret_access_key" => "54321"
1458
- },
1459
- s3_server_side_encryption: "AES256"
1460
- end
1461
-
1462
- context "when assigned" do
1463
- before do
1464
- @file = File.new(fixture_file("5k.png"), "rb")
1465
- @dummy = Dummy.new
1466
- @dummy.avatar = @file
1467
- end
1468
-
1469
- after { @file.close }
1470
-
1471
- context "and saved" do
1472
- before do
1473
- object = double
1474
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
1475
-
1476
- expect(object).to receive(:upload_file).
1477
- with(
1478
- anything,
1479
- {
1480
- content_type: "image/png",
1481
- acl: :"public-read",
1482
- server_side_encryption: "AES256",
1483
- },
1484
- )
1485
- @dummy.save
1486
- end
1487
-
1488
- it "succeeds" do
1489
- assert true
1490
- end
1491
- end
1492
- end
1493
- end
1494
-
1495
- context "An attachment with S3 storage and storage class set using the :storage_class option" do
1496
- before do
1497
- rebuild_model aws2_add_region.merge storage: :s3,
1498
- bucket: "testing",
1499
- path: ":attachment/:style/:basename:dotextension",
1500
- s3_credentials: {
1501
- "access_key_id" => "12345",
1502
- "secret_access_key" => "54321"
1503
- },
1504
- s3_storage_class: :reduced_redundancy
1505
- end
1506
-
1507
- context "when assigned" do
1508
- before do
1509
- @file = File.new(fixture_file("5k.png"), "rb")
1510
- @dummy = Dummy.new
1511
- @dummy.avatar = @file
1512
- end
1513
-
1514
- after { @file.close }
1515
-
1516
- context "and saved" do
1517
- before do
1518
- object = double
1519
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
1520
-
1521
- expect(object).to receive(:upload_file).
1522
- with(
1523
- anything,
1524
- {
1525
- content_type: "image/png",
1526
- acl: :"public-read",
1527
- storage_class: :reduced_redundancy,
1528
- },
1529
- )
1530
- @dummy.save
1531
- end
1532
-
1533
- it "succeeds" do
1534
- assert true
1535
- end
1536
- end
1537
- end
1538
- end
1539
-
1540
- context "with S3 credentials supplied as Pathname" do
1541
- before do
1542
- ENV["S3_KEY"] = "pathname_key"
1543
- ENV["S3_BUCKET"] = "pathname_bucket"
1544
- ENV["S3_SECRET"] = "pathname_secret"
1545
-
1546
- rails_env("test") do
1547
- rebuild_model aws2_add_region.merge storage: :s3,
1548
- s3_credentials: Pathname.new(fixture_file("s3.yml"))
1549
-
1550
- Dummy.delete_all
1551
- @dummy = Dummy.new
1552
- end
1553
- end
1554
-
1555
- it "parses the credentials" do
1556
- assert_equal "pathname_bucket", @dummy.avatar.bucket_name
1557
-
1558
- assert_equal "pathname_key",
1559
- @dummy.avatar.s3_bucket.client.config.access_key_id
1560
-
1561
- assert_equal "pathname_secret",
1562
- @dummy.avatar.s3_bucket.client.config.secret_access_key
1563
- end
1564
- end
1565
-
1566
- context "with S3 credentials supplied as Pathname and aliases being set" do
1567
- before do
1568
- ENV["S3_KEY"] = "pathname_key"
1569
- ENV["S3_BUCKET"] = "pathname_bucket"
1570
- ENV["S3_SECRET"] = "pathname_secret"
1571
-
1572
- rails_env("test") do
1573
- rebuild_model aws2_add_region.merge storage: :s3,
1574
- s3_credentials: Pathname.new(fixture_file("aws_s3.yml"))
1575
-
1576
- Dummy.delete_all
1577
- @dummy = Dummy.new
1578
- end
1579
- end
1580
-
1581
- it "parses the credentials" do
1582
- assert_equal "pathname_bucket", @dummy.avatar.bucket_name
1583
-
1584
- assert_equal "pathname_key",
1585
- @dummy.avatar.s3_bucket.client.config.access_key_id
1586
-
1587
- assert_equal "pathname_secret",
1588
- @dummy.avatar.s3_bucket.client.config.secret_access_key
1589
- end
1590
- end
1591
-
1592
- context "with S3 credentials in a YAML file" do
1593
- before do
1594
- ENV["S3_KEY"] = "env_key"
1595
- ENV["S3_BUCKET"] = "env_bucket"
1596
- ENV["S3_SECRET"] = "env_secret"
1597
-
1598
- rails_env("test") do
1599
- rebuild_model aws2_add_region.merge storage: :s3,
1600
- s3_credentials: File.new(fixture_file("s3.yml"))
1601
-
1602
- Dummy.delete_all
1603
-
1604
- @dummy = Dummy.new
1605
- end
1606
- end
1607
-
1608
- it "runs the file through ERB" do
1609
- assert_equal "env_bucket", @dummy.avatar.bucket_name
1610
-
1611
- assert_equal "env_key",
1612
- @dummy.avatar.s3_bucket.client.config.access_key_id
1613
-
1614
- assert_equal "env_secret",
1615
- @dummy.avatar.s3_bucket.client.config.secret_access_key
1616
- end
1617
- end
1618
-
1619
- context "with S3 credentials in a YAML file and aliases being set" do
1620
- before do
1621
- ENV["S3_KEY"] = "env_key"
1622
- ENV["S3_BUCKET"] = "env_bucket"
1623
- ENV["S3_SECRET"] = "env_secret"
1624
-
1625
- rails_env("test") do
1626
- rebuild_model aws2_add_region.merge storage: :s3,
1627
- s3_credentials: File.new(fixture_file("aws_s3.yml"))
1628
-
1629
- Dummy.delete_all
1630
-
1631
- @dummy = Dummy.new
1632
- end
1633
- end
1634
-
1635
- it "runs the file through ERB" do
1636
- assert_equal "env_bucket", @dummy.avatar.bucket_name
1637
-
1638
- assert_equal "env_key",
1639
- @dummy.avatar.s3_bucket.client.config.access_key_id
1640
-
1641
- assert_equal "env_secret",
1642
- @dummy.avatar.s3_bucket.client.config.secret_access_key
1643
- end
1644
- end
1645
-
1646
- context "S3 Permissions" do
1647
- context "defaults to :public_read" do
1648
- before do
1649
- rebuild_model aws2_add_region.merge storage: :s3,
1650
- bucket: "testing",
1651
- path: ":attachment/:style/:basename:dotextension",
1652
- s3_credentials: {
1653
- "access_key_id" => "12345",
1654
- "secret_access_key" => "54321"
1655
- }
1656
- end
1657
-
1658
- context "when assigned" do
1659
- before do
1660
- @file = File.new(fixture_file("5k.png"), "rb")
1661
- @dummy = Dummy.new
1662
- @dummy.avatar = @file
1663
- end
1664
-
1665
- after { @file.close }
1666
-
1667
- context "and saved" do
1668
- before do
1669
- object = double
1670
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
1671
-
1672
- expect(object).to receive(:upload_file).
1673
- with(anything, { content_type: "image/png", acl: :"public-read" })
1674
- @dummy.save
1675
- end
1676
-
1677
- it "succeeds" do
1678
- assert true
1679
- end
1680
- end
1681
- end
1682
- end
1683
-
1684
- context "string permissions set" do
1685
- before do
1686
- rebuild_model aws2_add_region.merge storage: :s3,
1687
- bucket: "testing",
1688
- path: ":attachment/:style/:basename:dotextension",
1689
- s3_credentials: {
1690
- "access_key_id" => "12345",
1691
- "secret_access_key" => "54321"
1692
- },
1693
- s3_permissions: :private
1694
- end
1695
-
1696
- context "when assigned" do
1697
- before do
1698
- @file = File.new(fixture_file("5k.png"), "rb")
1699
- @dummy = Dummy.new
1700
- @dummy.avatar = @file
1701
- end
1702
-
1703
- after { @file.close }
1704
-
1705
- context "and saved" do
1706
- before do
1707
- object = double
1708
- allow(@dummy.avatar).to receive(:s3_object).and_return(object)
1709
-
1710
- expect(object).to receive(:upload_file).
1711
- with(anything, { content_type: "image/png", acl: :private })
1712
- @dummy.save
1713
- end
1714
-
1715
- it "succeeds" do
1716
- assert true
1717
- end
1718
- end
1719
- end
1720
- end
1721
-
1722
- context "hash permissions set" do
1723
- before do
1724
- rebuild_model aws2_add_region.merge storage: :s3,
1725
- bucket: "testing",
1726
- path: ":attachment/:style/:basename:dotextension",
1727
- styles: {
1728
- thumb: "80x80>"
1729
- },
1730
- s3_credentials: {
1731
- "access_key_id" => "12345",
1732
- "secret_access_key" => "54321"
1733
- },
1734
- s3_permissions: {
1735
- original: :private,
1736
- thumb: :public_read
1737
- }
1738
- end
1739
-
1740
- context "when assigned" do
1741
- before do
1742
- @file = File.new(fixture_file("5k.png"), "rb")
1743
- @dummy = Dummy.new
1744
- @dummy.avatar = @file
1745
- end
1746
-
1747
- after { @file.close }
1748
-
1749
- context "and saved" do
1750
- before do
1751
- [:thumb, :original].each do |style|
1752
- object = double
1753
- allow(@dummy.avatar).to receive(:s3_object).with(style).and_return(object)
1754
-
1755
- expect(object).to receive(:upload_file).
1756
- with(anything,
1757
- {
1758
- content_type: "image/png",
1759
- acl: style == :thumb ? :public_read : :private
1760
- })
1761
- end
1762
- @dummy.save
1763
- end
1764
-
1765
- it "succeeds" do
1766
- assert true
1767
- end
1768
- end
1769
- end
1770
- end
1771
-
1772
- context "proc permission set" do
1773
- before do
1774
- rebuild_model(
1775
- aws2_add_region.merge(storage: :s3,
1776
- bucket: "testing",
1777
- path: ":attachment/:style/:basename:dotextension",
1778
- styles: {
1779
- thumb: "80x80>"
1780
- },
1781
- s3_credentials: {
1782
- "access_key_id" => "12345",
1783
- "secret_access_key" => "54321"
1784
- },
1785
- s3_permissions: lambda { |attachment, style|
1786
- attachment.instance.private_attachment? && style.to_sym != :thumb ? :private : :"public-read"
1787
- })
1788
- )
1789
- end
1790
- end
1791
- end
1792
-
1793
- context "An attachment with S3 storage and metadata set using a proc as headers" do
1794
- before do
1795
- rebuild_model(
1796
- aws2_add_region.merge(storage: :s3,
1797
- bucket: "testing",
1798
- path: ":attachment/:style/:basename:dotextension",
1799
- styles: {
1800
- thumb: "80x80>"
1801
- },
1802
- s3_credentials: {
1803
- "access_key_id" => "12345",
1804
- "secret_access_key" => "54321"
1805
- },
1806
- s3_headers: lambda { |attachment|
1807
- { "Content-Disposition" => "attachment; filename=\"#{attachment.name}\"" }
1808
- })
1809
- )
1810
- end
1811
-
1812
- context "when assigned" do
1813
- before do
1814
- @file = File.new(fixture_file("5k.png"), "rb")
1815
- @dummy = Dummy.new
1816
- allow(@dummy).to receive(:name).and_return("Custom Avatar Name.png")
1817
- @dummy.avatar = @file
1818
- end
1819
-
1820
- after { @file.close }
1821
-
1822
- context "and saved" do
1823
- before do
1824
- [:thumb, :original].each do |style|
1825
- object = double
1826
- allow(@dummy.avatar).to receive(:s3_object).with(style).and_return(object)
1827
-
1828
- expect(object).to receive(:upload_file).
1829
- with(
1830
- anything,
1831
- {
1832
- content_type: "image/png",
1833
- acl: :"public-read",
1834
- content_disposition: 'attachment; filename="Custom Avatar Name.png"',
1835
- },
1836
- )
1837
- end
1838
- @dummy.save
1839
- end
1840
-
1841
- it "succeeds" do
1842
- assert true
1843
- end
1844
- end
1845
- end
1846
- end
1847
-
1848
- context "path is a proc" do
1849
- before do
1850
- rebuild_model aws2_add_region.merge storage: :s3,
1851
- path: ->(attachment) { attachment.instance.attachment_path }
1852
-
1853
- @dummy = Dummy.new
1854
- @dummy.class_eval do
1855
- def attachment_path
1856
- "/some/dynamic/path"
1857
- end
1858
- end
1859
- @dummy.avatar = stringy_file
1860
- end
1861
-
1862
- it "returns a correct path" do
1863
- assert_match "/some/dynamic/path", @dummy.avatar.path
1864
- end
1865
- end
1866
-
1867
- private
1868
-
1869
- def rails_env(env)
1870
- stored_env = Rails.env
1871
- Rails.env = env
1872
- begin
1873
- yield
1874
- ensure
1875
- Rails.env = stored_env
1876
- end
1877
- end
1878
- end