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.

Files changed (198) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -6
  3. data/.hound.yml +1066 -0
  4. data/.rubocop.yml +1 -0
  5. data/.travis.yml +11 -17
  6. data/Appraisals +6 -14
  7. data/CONTRIBUTING.md +13 -8
  8. data/Gemfile +16 -3
  9. data/LICENSE +1 -3
  10. data/NEWS +167 -49
  11. data/README.md +294 -75
  12. data/RELEASING.md +17 -0
  13. data/Rakefile +6 -8
  14. data/features/basic_integration.feature +24 -6
  15. data/features/step_definitions/attachment_steps.rb +30 -22
  16. data/features/step_definitions/html_steps.rb +2 -2
  17. data/features/step_definitions/rails_steps.rb +44 -14
  18. data/features/step_definitions/web_steps.rb +1 -103
  19. data/features/support/env.rb +2 -2
  20. data/features/support/file_helpers.rb +2 -2
  21. data/features/support/fixtures/gemfile.txt +1 -1
  22. data/features/support/rails.rb +2 -1
  23. data/gemfiles/3.2.gemfile +14 -6
  24. data/gemfiles/4.1.gemfile +19 -0
  25. data/gemfiles/4.2.gemfile +19 -0
  26. data/lib/generators/paperclip/paperclip_generator.rb +0 -2
  27. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
  28. data/lib/paperclip/attachment.rb +132 -38
  29. data/lib/paperclip/attachment_registry.rb +1 -1
  30. data/lib/paperclip/callbacks.rb +11 -1
  31. data/lib/paperclip/content_type_detector.rb +25 -22
  32. data/lib/paperclip/deprecations.rb +42 -0
  33. data/lib/paperclip/errors.rb +5 -0
  34. data/lib/paperclip/file_command_content_type_detector.rb +6 -8
  35. data/lib/paperclip/geometry_detector_factory.rb +3 -1
  36. data/lib/paperclip/geometry_parser_factory.rb +1 -1
  37. data/lib/paperclip/has_attached_file.rb +10 -0
  38. data/lib/paperclip/interpolations/plural_cache.rb +6 -5
  39. data/lib/paperclip/interpolations.rb +25 -12
  40. data/lib/paperclip/io_adapters/abstract_adapter.rb +3 -1
  41. data/lib/paperclip/io_adapters/attachment_adapter.rb +4 -4
  42. data/lib/paperclip/io_adapters/data_uri_adapter.rb +5 -10
  43. data/lib/paperclip/io_adapters/stringio_adapter.rb +6 -10
  44. data/lib/paperclip/io_adapters/uri_adapter.rb +30 -11
  45. data/lib/paperclip/locales/de.yml +18 -0
  46. data/lib/paperclip/locales/en.yml +1 -0
  47. data/lib/paperclip/locales/es.yml +18 -0
  48. data/lib/paperclip/locales/ja.yml +18 -0
  49. data/lib/paperclip/locales/pt-BR.yml +18 -0
  50. data/lib/paperclip/locales/zh-CN.yml +18 -0
  51. data/lib/paperclip/locales/zh-HK.yml +18 -0
  52. data/lib/paperclip/locales/zh-TW.yml +18 -0
  53. data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -1
  54. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -1
  55. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -1
  56. data/lib/paperclip/media_type_spoof_detector.rb +89 -0
  57. data/lib/paperclip/processor.rb +0 -37
  58. data/lib/paperclip/processor_helpers.rb +50 -0
  59. data/lib/paperclip/rails_environment.rb +25 -0
  60. data/lib/paperclip/schema.rb +10 -2
  61. data/lib/paperclip/storage/filesystem.rb +1 -1
  62. data/lib/paperclip/storage/fog.rb +18 -7
  63. data/lib/paperclip/storage/s3.rb +53 -22
  64. data/lib/paperclip/style.rb +8 -2
  65. data/lib/paperclip/tempfile_factory.rb +5 -1
  66. data/lib/paperclip/thumbnail.rb +12 -10
  67. data/lib/paperclip/url_generator.rb +11 -3
  68. data/lib/paperclip/validators/attachment_content_type_validator.rb +4 -0
  69. data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
  70. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
  71. data/lib/paperclip/validators/attachment_presence_validator.rb +4 -0
  72. data/lib/paperclip/validators/attachment_size_validator.rb +11 -3
  73. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +27 -0
  74. data/lib/paperclip/validators.rb +10 -3
  75. data/lib/paperclip/version.rb +1 -1
  76. data/lib/paperclip.rb +26 -8
  77. data/lib/tasks/paperclip.rake +17 -2
  78. data/paperclip.gemspec +16 -14
  79. data/shoulda_macros/paperclip.rb +0 -1
  80. data/spec/paperclip/attachment_definitions_spec.rb +13 -0
  81. data/{test/attachment_processing_test.rb → spec/paperclip/attachment_processing_spec.rb} +20 -21
  82. data/spec/paperclip/attachment_registry_spec.rb +130 -0
  83. data/{test/attachment_test.rb → spec/paperclip/attachment_spec.rb} +438 -397
  84. data/{test/content_type_detector_test.rb → spec/paperclip/content_type_detector_spec.rb} +16 -19
  85. data/spec/paperclip/deprecations_spec.rb +65 -0
  86. data/{test/file_command_content_type_detector_test.rb → spec/paperclip/file_command_content_type_detector_spec.rb} +5 -6
  87. data/spec/paperclip/filename_cleaner_spec.rb +14 -0
  88. data/spec/paperclip/geometry_detector_spec.rb +39 -0
  89. data/{test/geometry_parser_test.rb → spec/paperclip/geometry_parser_spec.rb} +27 -27
  90. data/{test/geometry_test.rb → spec/paperclip/geometry_spec.rb} +50 -52
  91. data/spec/paperclip/glue_spec.rb +44 -0
  92. data/{test/has_attached_file_test.rb → spec/paperclip/has_attached_file_spec.rb} +45 -28
  93. data/{test/integration_test.rb → spec/paperclip/integration_spec.rb} +134 -126
  94. data/{test/interpolations_test.rb → spec/paperclip/interpolations_spec.rb} +70 -46
  95. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +78 -0
  96. data/{test/io_adapters/attachment_adapter_test.rb → spec/paperclip/io_adapters/attachment_adapter_spec.rb} +27 -29
  97. data/{test/io_adapters/data_uri_adapter_test.rb → spec/paperclip/io_adapters/data_uri_adapter_spec.rb} +26 -17
  98. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
  99. data/{test/io_adapters/file_adapter_test.rb → spec/paperclip/io_adapters/file_adapter_spec.rb} +36 -40
  100. data/{test/io_adapters/http_url_proxy_adapter_test.rb → spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb} +31 -29
  101. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
  102. data/{test/io_adapters/nil_adapter_test.rb → spec/paperclip/io_adapters/nil_adapter_spec.rb} +7 -7
  103. data/{test/io_adapters/registry_test.rb → spec/paperclip/io_adapters/registry_spec.rb} +10 -7
  104. data/{test/io_adapters/stringio_adapter_test.rb → spec/paperclip/io_adapters/stringio_adapter_spec.rb} +20 -17
  105. data/{test/io_adapters/uploaded_file_adapter_test.rb → spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb} +41 -41
  106. data/{test/io_adapters/uri_adapter_test.rb → spec/paperclip/io_adapters/uri_adapter_spec.rb} +53 -28
  107. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
  108. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +99 -0
  109. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
  110. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
  111. data/spec/paperclip/media_type_spoof_detector_spec.rb +79 -0
  112. data/spec/paperclip/meta_class_spec.rb +30 -0
  113. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
  114. data/{test/paperclip_test.rb → spec/paperclip/paperclip_spec.rb} +53 -48
  115. data/spec/paperclip/plural_cache_spec.rb +37 -0
  116. data/spec/paperclip/processor_helpers_spec.rb +57 -0
  117. data/{test/processor_test.rb → spec/paperclip/processor_spec.rb} +5 -5
  118. data/spec/paperclip/rails_environment_spec.rb +33 -0
  119. data/{test/rake_test.rb → spec/paperclip/rake_spec.rb} +15 -15
  120. data/spec/paperclip/schema_spec.rb +248 -0
  121. data/{test/storage/filesystem_test.rb → spec/paperclip/storage/filesystem_spec.rb} +18 -18
  122. data/spec/paperclip/storage/fog_spec.rb +535 -0
  123. data/spec/paperclip/storage/s3_live_spec.rb +182 -0
  124. data/spec/paperclip/storage/s3_spec.rb +1526 -0
  125. data/spec/paperclip/style_spec.rb +255 -0
  126. data/spec/paperclip/tempfile_factory_spec.rb +33 -0
  127. data/{test/thumbnail_test.rb → spec/paperclip/thumbnail_spec.rb} +123 -107
  128. data/spec/paperclip/url_generator_spec.rb +211 -0
  129. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
  130. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
  131. data/{test/validators/attachment_presence_validator_test.rb → spec/paperclip/validators/attachment_presence_validator_spec.rb} +20 -20
  132. data/{test/validators/attachment_size_validator_test.rb → spec/paperclip/validators/attachment_size_validator_spec.rb} +65 -58
  133. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +52 -0
  134. data/spec/paperclip/validators_spec.rb +164 -0
  135. data/spec/spec_helper.rb +43 -0
  136. data/spec/support/assertions.rb +71 -0
  137. data/spec/support/deprecations.rb +9 -0
  138. data/spec/support/fake_model.rb +25 -0
  139. data/spec/support/fake_rails.rb +12 -0
  140. data/spec/support/fixtures/empty.html +1 -0
  141. data/spec/support/fixtures/empty.xlsx +0 -0
  142. data/spec/support/fixtures/spaced file.jpg +0 -0
  143. data/spec/support/matchers/accept.rb +5 -0
  144. data/spec/support/matchers/exist.rb +5 -0
  145. data/spec/support/matchers/have_column.rb +23 -0
  146. data/spec/support/model_reconstruction.rb +60 -0
  147. data/spec/support/rails_helpers.rb +7 -0
  148. data/spec/support/test_data.rb +13 -0
  149. data/spec/support/version_helper.rb +9 -0
  150. metadata +334 -219
  151. data/RUNNING_TESTS.md +0 -4
  152. data/gemfiles/3.0.gemfile +0 -11
  153. data/gemfiles/3.1.gemfile +0 -11
  154. data/gemfiles/4.0.gemfile +0 -11
  155. data/test/attachment_definitions_test.rb +0 -12
  156. data/test/attachment_registry_test.rb +0 -88
  157. data/test/filename_cleaner_test.rb +0 -14
  158. data/test/generator_test.rb +0 -84
  159. data/test/geometry_detector_test.rb +0 -24
  160. data/test/helper.rb +0 -232
  161. data/test/io_adapters/abstract_adapter_test.rb +0 -58
  162. data/test/io_adapters/empty_string_adapter_test.rb +0 -18
  163. data/test/io_adapters/identity_adapter_test.rb +0 -8
  164. data/test/matchers/have_attached_file_matcher_test.rb +0 -24
  165. data/test/matchers/validate_attachment_content_type_matcher_test.rb +0 -110
  166. data/test/matchers/validate_attachment_presence_matcher_test.rb +0 -69
  167. data/test/matchers/validate_attachment_size_matcher_test.rb +0 -86
  168. data/test/meta_class_test.rb +0 -32
  169. data/test/paperclip_missing_attachment_styles_test.rb +0 -90
  170. data/test/plural_cache_test.rb +0 -36
  171. data/test/schema_test.rb +0 -200
  172. data/test/storage/fog_test.rb +0 -473
  173. data/test/storage/s3_live_test.rb +0 -179
  174. data/test/storage/s3_test.rb +0 -1356
  175. data/test/style_test.rb +0 -213
  176. data/test/support/mock_model.rb +0 -2
  177. data/test/tempfile_factory_test.rb +0 -17
  178. data/test/url_generator_test.rb +0 -187
  179. data/test/validators/attachment_content_type_validator_test.rb +0 -324
  180. data/test/validators_test.rb +0 -61
  181. /data/{test → spec}/database.yml +0 -0
  182. /data/{test → spec/support}/fixtures/12k.png +0 -0
  183. /data/{test → spec/support}/fixtures/50x50.png +0 -0
  184. /data/{test → spec/support}/fixtures/5k.png +0 -0
  185. /data/{test → spec/support}/fixtures/animated +0 -0
  186. /data/{test → spec/support}/fixtures/animated.gif +0 -0
  187. /data/{test → spec/support}/fixtures/animated.unknown +0 -0
  188. /data/{test → spec/support}/fixtures/bad.png +0 -0
  189. /data/{test → spec/support}/fixtures/fog.yml +0 -0
  190. /data/{test → spec/support}/fixtures/rotated.jpg +0 -0
  191. /data/{test → spec/support}/fixtures/s3.yml +0 -0
  192. /data/{test → spec/support}/fixtures/spaced file.png +0 -0
  193. /data/{test → spec/support}/fixtures/text.txt +0 -0
  194. /data/{test → spec/support}/fixtures/twopage.pdf +0 -0
  195. /data/{test → spec/support}/fixtures/uppercase.PNG +0 -0
  196. /data/{test → spec}/support/mock_attachment.rb +0 -0
  197. /data/{test → spec}/support/mock_interpolator.rb +0 -0
  198. /data/{test → spec}/support/mock_url_generator_builder.rb +0 -0
@@ -1,1356 +0,0 @@
1
- require './test/helper'
2
- require 'aws'
3
-
4
- class S3Test < Test::Unit::TestCase
5
- def rails_env(env)
6
- silence_warnings do
7
- Object.const_set(:Rails, stub('Rails', :env => env))
8
- end
9
- end
10
-
11
- def setup
12
- AWS.config(:access_key_id => "TESTKEY", :secret_access_key => "TESTSECRET", :stub_requests => true)
13
- end
14
-
15
- def teardown
16
- AWS.config(:access_key_id => nil, :secret_access_key => nil, :stub_requests => nil)
17
- end
18
-
19
- context "Parsing S3 credentials" do
20
- setup do
21
- @proxy_settings = {:host => "127.0.0.1", :port => 8888, :user => "foo", :password => "bar"}
22
- rebuild_model :storage => :s3,
23
- :bucket => "testing",
24
- :http_proxy => @proxy_settings,
25
- :s3_credentials => {:not => :important}
26
-
27
- @dummy = Dummy.new
28
- @avatar = @dummy.avatar
29
- end
30
-
31
- should "get the correct credentials when RAILS_ENV is production" do
32
- rails_env("production")
33
- assert_equal({:key => "12345"},
34
- @avatar.parse_credentials('production' => {:key => '12345'},
35
- :development => {:key => "54321"}))
36
- end
37
-
38
- should "get the correct credentials when RAILS_ENV is development" do
39
- rails_env("development")
40
- assert_equal({:key => "54321"},
41
- @avatar.parse_credentials('production' => {:key => '12345'},
42
- :development => {:key => "54321"}))
43
- end
44
-
45
- should "return the argument if the key does not exist" do
46
- rails_env("not really an env")
47
- assert_equal({:test => "12345"}, @avatar.parse_credentials(:test => "12345"))
48
- end
49
-
50
- should "support HTTP proxy settings" do
51
- rails_env("development")
52
- assert_equal(true, @avatar.using_http_proxy?)
53
- assert_equal(@proxy_settings[:host], @avatar.http_proxy_host)
54
- assert_equal(@proxy_settings[:port], @avatar.http_proxy_port)
55
- assert_equal(@proxy_settings[:user], @avatar.http_proxy_user)
56
- assert_equal(@proxy_settings[:password], @avatar.http_proxy_password)
57
- end
58
-
59
- end
60
-
61
- context ":bucket option via :s3_credentials" do
62
-
63
- setup do
64
- rebuild_model :storage => :s3, :s3_credentials => {:bucket => 'testing'}
65
- @dummy = Dummy.new
66
- end
67
-
68
- should "populate #bucket_name" do
69
- assert_equal @dummy.avatar.bucket_name, 'testing'
70
- end
71
-
72
- end
73
-
74
- context ":bucket option" do
75
-
76
- setup do
77
- rebuild_model :storage => :s3, :bucket => "testing", :s3_credentials => {}
78
- @dummy = Dummy.new
79
- end
80
-
81
- should "populate #bucket_name" do
82
- assert_equal @dummy.avatar.bucket_name, 'testing'
83
- end
84
-
85
- end
86
-
87
- context "missing :bucket option" do
88
-
89
- setup do
90
- rebuild_model :storage => :s3,
91
- :http_proxy => @proxy_settings,
92
- :s3_credentials => {:not => :important}
93
-
94
- @dummy = Dummy.new
95
- @dummy.avatar = StringIO.new(".")
96
-
97
- end
98
-
99
- should "raise an argument error" do
100
- exception = assert_raise(ArgumentError) { @dummy.save }
101
- assert_match /missing required :bucket option/, exception.message
102
- end
103
-
104
- end
105
-
106
- context "" do
107
- setup do
108
- rebuild_model :storage => :s3,
109
- :s3_credentials => {},
110
- :bucket => "bucket",
111
- :path => ":attachment/:basename.:extension",
112
- :url => ":s3_path_url"
113
- @dummy = Dummy.new
114
- @dummy.avatar = StringIO.new(".")
115
- end
116
-
117
- should "return a url based on an S3 path" do
118
- assert_match %r{^http://s3.amazonaws.com/bucket/avatars/stringio.txt}, @dummy.avatar.url
119
- end
120
-
121
- should "use the correct bucket" do
122
- assert_equal "bucket", @dummy.avatar.s3_bucket.name
123
- end
124
-
125
- should "use the correct key" do
126
- assert_equal "avatars/stringio.txt", @dummy.avatar.s3_object.key
127
- end
128
- end
129
-
130
- context "s3_protocol" do
131
- ["http", :http, ""].each do |protocol|
132
- context "as #{protocol.inspect}" do
133
- setup do
134
- rebuild_model :storage => :s3, :s3_protocol => protocol
135
-
136
- @dummy = Dummy.new
137
- end
138
-
139
- should "return the s3_protocol in string" do
140
- assert_equal protocol.to_s, @dummy.avatar.s3_protocol
141
- end
142
- end
143
- end
144
- end
145
-
146
- context ":s3_protocol => 'https'" do
147
- setup do
148
- rebuild_model :storage => :s3,
149
- :s3_credentials => {},
150
- :s3_protocol => 'https',
151
- :bucket => "bucket",
152
- :path => ":attachment/:basename.:extension"
153
- @dummy = Dummy.new
154
- @dummy.avatar = StringIO.new(".")
155
- end
156
-
157
- should "return a url based on an S3 path" do
158
- assert_match %r{^https://s3.amazonaws.com/bucket/avatars/stringio.txt}, @dummy.avatar.url
159
- end
160
- end
161
-
162
- context ":s3_protocol => :https" do
163
- setup do
164
- rebuild_model :storage => :s3,
165
- :s3_credentials => {},
166
- :s3_protocol => :https,
167
- :bucket => "bucket",
168
- :path => ":attachment/:basename.:extension"
169
- @dummy = Dummy.new
170
- @dummy.avatar = StringIO.new(".")
171
- end
172
-
173
- should "return a url based on an S3 path" do
174
- assert_match %r{^https://s3.amazonaws.com/bucket/avatars/stringio.txt}, @dummy.avatar.url
175
- end
176
- end
177
-
178
- context ":s3_protocol => ''" do
179
- setup do
180
- rebuild_model :storage => :s3,
181
- :s3_credentials => {},
182
- :s3_protocol => '',
183
- :bucket => "bucket",
184
- :path => ":attachment/:basename.:extension"
185
- @dummy = Dummy.new
186
- @dummy.avatar = StringIO.new(".")
187
- end
188
-
189
- should "return a url based on an S3 path" do
190
- assert_match %r{^//s3.amazonaws.com/bucket/avatars/stringio.txt}, @dummy.avatar.url
191
- end
192
- end
193
-
194
- context "An attachment that uses S3 for storage and has the style in the path" do
195
- setup do
196
- rebuild_model :storage => :s3,
197
- :bucket => "testing",
198
- :path => ":attachment/:style/:basename.:extension",
199
- :styles => {
200
- :thumb => "80x80>"
201
- },
202
- :s3_credentials => {
203
- 'access_key_id' => "12345",
204
- 'secret_access_key' => "54321"
205
- }
206
-
207
- @dummy = Dummy.new
208
- @dummy.avatar = StringIO.new(".")
209
- @avatar = @dummy.avatar
210
- end
211
-
212
- should "use an S3 object based on the correct path for the default style" do
213
- assert_equal("avatars/original/stringio.txt", @dummy.avatar.s3_object.key)
214
- end
215
-
216
- should "use an S3 object based on the correct path for the custom style" do
217
- assert_equal("avatars/thumb/stringio.txt", @dummy.avatar.s3_object(:thumb).key)
218
- end
219
- end
220
-
221
- context "s3_host_name" do
222
- setup do
223
- rebuild_model :storage => :s3,
224
- :s3_credentials => {},
225
- :bucket => "bucket",
226
- :path => ":attachment/:basename.:extension",
227
- :s3_host_name => "s3-ap-northeast-1.amazonaws.com"
228
- @dummy = Dummy.new
229
- @dummy.avatar = StringIO.new(".")
230
- end
231
-
232
- should "return a url based on an :s3_host_name path" do
233
- assert_match %r{^http://s3-ap-northeast-1.amazonaws.com/bucket/avatars/stringio.txt}, @dummy.avatar.url
234
- end
235
-
236
- should "use the S3 bucket with the correct host name" do
237
- assert_equal "s3-ap-northeast-1.amazonaws.com", @dummy.avatar.s3_bucket.config.s3_endpoint
238
- end
239
- end
240
-
241
- context "dynamic s3_host_name" do
242
- setup do
243
- rebuild_model :storage => :s3,
244
- :s3_credentials => {},
245
- :bucket => "bucket",
246
- :path => ":attachment/:basename.:extension",
247
- :s3_host_name => lambda {|a| a.instance.value }
248
- @dummy = Dummy.new
249
- class << @dummy
250
- attr_accessor :value
251
- end
252
- @dummy.avatar = StringIO.new(".")
253
- end
254
-
255
- should "use s3_host_name as a proc if available" do
256
- @dummy.value = "s3.something.com"
257
- assert_equal "http://s3.something.com/bucket/avatars/stringio.txt", @dummy.avatar.url(:original, :timestamp => false)
258
- end
259
- end
260
-
261
- context "An attachment that uses S3 for storage and has styles that return different file types" do
262
- setup do
263
- rebuild_model :styles => { :large => ['500x500#', :jpg] },
264
- :storage => :s3,
265
- :bucket => "bucket",
266
- :path => ":attachment/:basename.:extension",
267
- :s3_credentials => {
268
- 'access_key_id' => "12345",
269
- 'secret_access_key' => "54321"
270
- }
271
-
272
- File.open(fixture_file('5k.png'), 'rb') do |file|
273
- @dummy = Dummy.new
274
- @dummy.avatar = file
275
- end
276
- end
277
-
278
- should "return a url containing the correct original file mime type" do
279
- assert_match /.+\/5k.png/, @dummy.avatar.url
280
- end
281
-
282
- should 'use the correct key for the original file mime type' do
283
- assert_match /.+\/5k.png/, @dummy.avatar.s3_object.key
284
- end
285
-
286
- should "return a url containing the correct processed file mime type" do
287
- assert_match /.+\/5k.jpg/, @dummy.avatar.url(:large)
288
- end
289
-
290
- should "use the correct key for the processed file mime type" do
291
- assert_match /.+\/5k.jpg/, @dummy.avatar.s3_object(:large).key
292
- end
293
- end
294
-
295
- context "An attachment that uses S3 for storage and has a proc for styles" do
296
- setup do
297
- rebuild_model :styles => lambda { |attachment| attachment.instance.counter; {:thumbnail => { :geometry => "50x50#", :s3_headers => {'Cache-Control' => 'max-age=31557600'}} }},
298
- :storage => :s3,
299
- :bucket => "bucket",
300
- :path => ":attachment/:style/:basename.:extension",
301
- :s3_credentials => {
302
- 'access_key_id' => "12345",
303
- 'secret_access_key' => "54321"
304
- }
305
-
306
- @file = File.new(fixture_file('5k.png'), 'rb')
307
-
308
- Dummy.class_eval do
309
- def counter
310
- @counter ||= 0
311
- @counter += 1
312
- @counter
313
- end
314
- end
315
-
316
- @dummy = Dummy.new
317
- @dummy.avatar = @file
318
-
319
- object = stub
320
- @dummy.avatar.stubs(:s3_object).with(:original).returns(object)
321
- @dummy.avatar.stubs(:s3_object).with(:thumbnail).returns(object)
322
- object.expects(:write).with(anything, :content_type => 'image/png', :acl => :public_read)
323
- object.expects(:write).with(anything, :content_type => 'image/png', :acl => :public_read, :cache_control => 'max-age=31557600')
324
- @dummy.save
325
- end
326
-
327
- teardown { @file.close }
328
-
329
- should "succeed" do
330
- assert_equal @dummy.counter, 7
331
- end
332
- end
333
-
334
- context "An attachment that uses S3 for storage and has spaces in file name" do
335
- setup do
336
- rebuild_model :styles => { :large => ['500x500#', :jpg] },
337
- :storage => :s3,
338
- :bucket => "bucket",
339
- :s3_credentials => {
340
- 'access_key_id' => "12345",
341
- 'secret_access_key' => "54321"
342
- }
343
-
344
- File.open(fixture_file('spaced file.png'), 'rb') do |file|
345
- @dummy = Dummy.new
346
- @dummy.avatar = file
347
- end
348
- end
349
-
350
- should "return a replaced version for path" do
351
- assert_match /.+\/spaced_file\.png/, @dummy.avatar.path
352
- end
353
-
354
- should "return a replaced version for url" do
355
- assert_match /.+\/spaced_file\.png/, @dummy.avatar.url
356
- end
357
- end
358
-
359
- context "An attachment that uses S3 for storage and has a question mark in file name" do
360
- setup do
361
- rebuild_model :styles => { :large => ['500x500#', :jpg] },
362
- :storage => :s3,
363
- :bucket => "bucket",
364
- :s3_credentials => {
365
- 'access_key_id' => "12345",
366
- 'secret_access_key' => "54321"
367
- }
368
-
369
- stringio = StringIO.new(".")
370
- class << stringio
371
- def original_filename
372
- "question?mark.png"
373
- end
374
- end
375
- file = Paperclip.io_adapters.for(stringio)
376
- @dummy = Dummy.new
377
- @dummy.avatar = file
378
- @dummy.save
379
- end
380
-
381
- should "return a replaced version for path" do
382
- assert_match /.+\/question_mark\.png/, @dummy.avatar.path
383
- end
384
-
385
- should "return a replaced version for url" do
386
- assert_match /.+\/question_mark\.png/, @dummy.avatar.url
387
- end
388
- end
389
-
390
- context "" do
391
- setup do
392
- rebuild_model :storage => :s3,
393
- :s3_credentials => {},
394
- :bucket => "bucket",
395
- :path => ":attachment/:basename.:extension",
396
- :url => ":s3_domain_url"
397
- @dummy = Dummy.new
398
- @dummy.avatar = StringIO.new(".")
399
- end
400
-
401
- should "return a url based on an S3 subdomain" do
402
- assert_match %r{^http://bucket.s3.amazonaws.com/avatars/stringio.txt}, @dummy.avatar.url
403
- end
404
- end
405
-
406
- context "" do
407
- setup do
408
- rebuild_model :storage => :s3,
409
- :s3_credentials => {
410
- :production => { :bucket => "prod_bucket" },
411
- :development => { :bucket => "dev_bucket" }
412
- },
413
- :s3_host_alias => "something.something.com",
414
- :path => ":attachment/:basename.:extension",
415
- :url => ":s3_alias_url"
416
- @dummy = Dummy.new
417
- @dummy.avatar = StringIO.new(".")
418
- end
419
-
420
- should "return a url based on the host_alias" do
421
- assert_match %r{^http://something.something.com/avatars/stringio.txt}, @dummy.avatar.url
422
- end
423
- end
424
-
425
- context "generating a url with a proc as the host alias" do
426
- setup do
427
- rebuild_model :storage => :s3,
428
- :s3_credentials => { :bucket => "prod_bucket" },
429
- :s3_host_alias => Proc.new{|atch| "cdn#{atch.instance.counter % 4}.example.com"},
430
- :path => ":attachment/:basename.:extension",
431
- :url => ":s3_alias_url"
432
- Dummy.class_eval do
433
- def counter
434
- @counter ||= 0
435
- @counter += 1
436
- @counter
437
- end
438
- end
439
- @dummy = Dummy.new
440
- @dummy.avatar = StringIO.new(".")
441
- end
442
-
443
- should "return a url based on the host_alias" do
444
- assert_match %r{^http://cdn1.example.com/avatars/stringio.txt}, @dummy.avatar.url
445
- assert_match %r{^http://cdn2.example.com/avatars/stringio.txt}, @dummy.avatar.url
446
- end
447
-
448
- should "still return the bucket name" do
449
- assert_equal "prod_bucket", @dummy.avatar.bucket_name
450
- end
451
-
452
- end
453
-
454
- context "" do
455
- setup do
456
- rebuild_model :storage => :s3,
457
- :s3_credentials => {},
458
- :bucket => "bucket",
459
- :path => ":attachment/:basename.:extension",
460
- :url => ":asset_host"
461
- @dummy = Dummy.new
462
- @dummy.avatar = StringIO.new(".")
463
- end
464
-
465
- should "return a relative URL for Rails to calculate assets host" do
466
- assert_match %r{^avatars/stringio\.txt}, @dummy.avatar.url
467
- end
468
-
469
- end
470
-
471
- context "Generating a secure url with an expiration" do
472
- setup do
473
- @build_model_with_options = lambda {|options|
474
- base_options = {
475
- :storage => :s3,
476
- :s3_credentials => {
477
- :production => { :bucket => "prod_bucket" },
478
- :development => { :bucket => "dev_bucket" }
479
- },
480
- :s3_host_alias => "something.something.com",
481
- :s3_permissions => "private",
482
- :path => ":attachment/:basename.:extension",
483
- :url => ":s3_alias_url"
484
- }
485
-
486
- rebuild_model base_options.merge(options)
487
- }
488
- end
489
-
490
- should "use default options" do
491
- @build_model_with_options[{}]
492
-
493
- rails_env("production")
494
-
495
- @dummy = Dummy.new
496
- @dummy.avatar = StringIO.new(".")
497
-
498
- object = stub
499
- @dummy.avatar.stubs(:s3_object).returns(object)
500
- object.expects(:url_for).with(:read, :expires => 3600, :secure => true)
501
-
502
- @dummy.avatar.expiring_url
503
- end
504
-
505
- should "allow overriding s3_url_options" do
506
- @build_model_with_options[:s3_url_options => { :response_content_disposition => "inline" }]
507
-
508
- rails_env("production")
509
-
510
- @dummy = Dummy.new
511
- @dummy.avatar = StringIO.new(".")
512
-
513
- object = stub
514
- @dummy.avatar.stubs(:s3_object).returns(object)
515
- object.expects(:url_for).with(:read, :expires => 3600, :secure => true, :response_content_disposition => "inline")
516
-
517
- @dummy.avatar.expiring_url
518
- end
519
-
520
- should "allow overriding s3_object options with a proc" do
521
- @build_model_with_options[:s3_url_options => lambda {|attachment| { :response_content_type => attachment.avatar_content_type } }]
522
-
523
- rails_env("production")
524
-
525
- @dummy = Dummy.new
526
-
527
- @file = StringIO.new(".")
528
- @file.stubs(:original_filename).returns("5k.png\n\n")
529
- @file.stubs(:content_type).returns("image/png\n\n")
530
- @file.stubs(:to_tempfile).returns(@file)
531
-
532
- @dummy.avatar = @file
533
-
534
- object = stub
535
- @dummy.avatar.stubs(:s3_object).returns(object)
536
- object.expects(:url_for).with(:read, :expires => 3600, :secure => true, :response_content_type => "image/png")
537
-
538
- @dummy.avatar.expiring_url
539
- end
540
- end
541
-
542
- context "#expiring_url" do
543
- setup { @dummy = Dummy.new }
544
-
545
- context "with no attachment" do
546
- setup { assert(!@dummy.avatar.exists?) }
547
-
548
- should "return the default URL" do
549
- assert_equal(@dummy.avatar.url, @dummy.avatar.expiring_url)
550
- end
551
-
552
- should 'generate a url for a style when a file does not exist' do
553
- assert_equal(@dummy.avatar.url(:thumb), @dummy.avatar.expiring_url(3600, :thumb))
554
- end
555
- end
556
-
557
- should "generate the same url when using Times and Integer offsets" do
558
- assert_equal @dummy.avatar.expiring_url(1234), @dummy.avatar.expiring_url(Time.now + 1234)
559
- end
560
- end
561
-
562
- context "Generating a url with an expiration for each style" do
563
- setup do
564
- rebuild_model :storage => :s3,
565
- :s3_credentials => {
566
- :production => { :bucket => "prod_bucket" },
567
- :development => { :bucket => "dev_bucket" }
568
- },
569
- :s3_permissions => :private,
570
- :s3_host_alias => "something.something.com",
571
- :path => ":attachment/:style/:basename.:extension",
572
- :url => ":s3_alias_url"
573
-
574
- rails_env("production")
575
-
576
- @dummy = Dummy.new
577
- @dummy.avatar = StringIO.new(".")
578
- end
579
-
580
- should "should generate a url for the thumb" do
581
- object = stub
582
- @dummy.avatar.stubs(:s3_object).with(:thumb).returns(object)
583
- object.expects(:url_for).with(:read, :expires => 1800, :secure => true)
584
- @dummy.avatar.expiring_url(1800, :thumb)
585
- end
586
-
587
- should "should generate a url for the default style" do
588
- object = stub
589
- @dummy.avatar.stubs(:s3_object).with(:original).returns(object)
590
- object.expects(:url_for).with(:read, :expires => 1800, :secure => true)
591
- @dummy.avatar.expiring_url(1800)
592
- end
593
- end
594
-
595
- context "Parsing S3 credentials with a bucket in them" do
596
- setup do
597
- rebuild_model :storage => :s3,
598
- :s3_credentials => {
599
- :production => { :bucket => "prod_bucket" },
600
- :development => { :bucket => "dev_bucket" }
601
- }
602
- @dummy = Dummy.new
603
- end
604
-
605
- should "get the right bucket in production" do
606
- rails_env("production")
607
- assert_equal "prod_bucket", @dummy.avatar.bucket_name
608
- assert_equal "prod_bucket", @dummy.avatar.s3_bucket.name
609
- end
610
-
611
- should "get the right bucket in development" do
612
- rails_env("development")
613
- assert_equal "dev_bucket", @dummy.avatar.bucket_name
614
- assert_equal "dev_bucket", @dummy.avatar.s3_bucket.name
615
- end
616
- end
617
-
618
- context "Parsing S3 credentials with a s3_host_name in them" do
619
- setup do
620
- rebuild_model :storage => :s3,
621
- :bucket => 'testing',
622
- :s3_credentials => {
623
- :production => { :s3_host_name => "s3-world-end.amazonaws.com" },
624
- :development => { :s3_host_name => "s3-ap-northeast-1.amazonaws.com" }
625
- }
626
- @dummy = Dummy.new
627
- end
628
-
629
- should "get the right s3_host_name in production" do
630
- rails_env("production")
631
- assert_match %r{^s3-world-end.amazonaws.com}, @dummy.avatar.s3_host_name
632
- assert_match %r{^s3-world-end.amazonaws.com}, @dummy.avatar.s3_bucket.config.s3_endpoint
633
- end
634
-
635
- should "get the right s3_host_name in development" do
636
- rails_env("development")
637
- assert_match %r{^s3-ap-northeast-1.amazonaws.com}, @dummy.avatar.s3_host_name
638
- assert_match %r{^s3-ap-northeast-1.amazonaws.com}, @dummy.avatar.s3_bucket.config.s3_endpoint
639
- end
640
-
641
- should "get the right s3_host_name if the key does not exist" do
642
- rails_env("test")
643
- assert_match %r{^s3.amazonaws.com}, @dummy.avatar.s3_host_name
644
- assert_match %r{^s3.amazonaws.com}, @dummy.avatar.s3_bucket.config.s3_endpoint
645
- end
646
- end
647
-
648
- context "An attachment with S3 storage" do
649
- setup do
650
- rebuild_model :storage => :s3,
651
- :bucket => "testing",
652
- :path => ":attachment/:style/:basename.:extension",
653
- :s3_credentials => {
654
- 'access_key_id' => "12345",
655
- 'secret_access_key' => "54321"
656
- }
657
- end
658
-
659
- should "be extended by the S3 module" do
660
- assert Dummy.new.avatar.is_a?(Paperclip::Storage::S3)
661
- end
662
-
663
- should "not be extended by the Filesystem module" do
664
- assert ! Dummy.new.avatar.is_a?(Paperclip::Storage::Filesystem)
665
- end
666
-
667
- context "when assigned" do
668
- setup do
669
- @file = File.new(fixture_file('5k.png'), 'rb')
670
- @dummy = Dummy.new
671
- @dummy.avatar = @file
672
- end
673
-
674
- teardown { @file.close }
675
-
676
- should "not get a bucket to get a URL" do
677
- @dummy.avatar.expects(:s3).never
678
- @dummy.avatar.expects(:s3_bucket).never
679
- assert_match %r{^http://s3\.amazonaws\.com/testing/avatars/original/5k\.png}, @dummy.avatar.url
680
- end
681
-
682
- should "be rewinded after flush_writes" do
683
- @dummy.avatar.instance_eval "def after_flush_writes; end"
684
-
685
- files = @dummy.avatar.queued_for_write.values.each(&:read)
686
- @dummy.save
687
- assert files.none?(&:eof?), "Expect all the files to be rewinded."
688
- end
689
-
690
- should "be removed after after_flush_writes" do
691
- paths = @dummy.avatar.queued_for_write.values.map(&:path)
692
- @dummy.save
693
- assert paths.none?{ |path| File.exists?(path) },
694
- "Expect all the files to be deleted."
695
- end
696
-
697
- context "and saved" do
698
- setup do
699
- object = stub
700
- @dummy.avatar.stubs(:s3_object).returns(object)
701
- object.expects(:write).with(anything,
702
- :content_type => "image/png",
703
- :acl => :public_read)
704
- @dummy.save
705
- end
706
-
707
- should "succeed" do
708
- assert true
709
- end
710
- end
711
-
712
- context "and saved without a bucket" do
713
- setup do
714
- AWS::S3::BucketCollection.any_instance.expects(:create).with("testing")
715
- AWS::S3::S3Object.any_instance.stubs(:write).
716
- raises(AWS::S3::Errors::NoSuchBucket.new(stub,
717
- stub(:status => 404,
718
- :body => "<foo/>"))).
719
- then.returns(nil)
720
- @dummy.save
721
- end
722
-
723
- should "succeed" do
724
- assert true
725
- end
726
- end
727
-
728
- context "and remove" do
729
- setup do
730
- AWS::S3::S3Object.any_instance.stubs(:exists?).returns(true)
731
- AWS::S3::S3Object.any_instance.stubs(:delete)
732
- @dummy.destroy
733
- end
734
-
735
- should "succeed" do
736
- assert true
737
- end
738
- end
739
-
740
- context 'that the file were missing' do
741
- setup do
742
- AWS::S3::S3Object.any_instance.stubs(:exists?).raises(AWS::Errors::Base)
743
- end
744
-
745
- should 'return false on exists?' do
746
- assert !@dummy.avatar.exists?
747
- end
748
- end
749
- end
750
- end
751
-
752
- context "An attachment with S3 storage and bucket defined as a Proc" do
753
- setup do
754
- rebuild_model :storage => :s3,
755
- :bucket => lambda { |attachment| "bucket_#{attachment.instance.other}" },
756
- :s3_credentials => {:not => :important}
757
- end
758
-
759
- should "get the right bucket name" do
760
- assert "bucket_a", Dummy.new(:other => 'a').avatar.bucket_name
761
- assert "bucket_a", Dummy.new(:other => 'a').avatar.s3_bucket.name
762
- assert "bucket_b", Dummy.new(:other => 'b').avatar.bucket_name
763
- assert "bucket_b", Dummy.new(:other => 'b').avatar.s3_bucket.name
764
- end
765
- end
766
-
767
- context "An attachment with S3 storage and S3 credentials defined as a Proc" do
768
- setup do
769
- rebuild_model :storage => :s3,
770
- :bucket => {:not => :important},
771
- :s3_credentials => lambda { |attachment|
772
- Hash['access_key_id' => "access#{attachment.instance.other}", 'secret_access_key' => "secret#{attachment.instance.other}"]
773
- }
774
- end
775
-
776
- should "get the right credentials" do
777
- assert "access1234", Dummy.new(:other => '1234').avatar.s3_credentials[:access_key_id]
778
- assert "secret1234", Dummy.new(:other => '1234').avatar.s3_credentials[:secret_access_key]
779
- end
780
- end
781
-
782
- context "An attachment with S3 storage and S3 credentials with a :credential_provider" do
783
- setup do
784
- class DummyCredentialProvider; end
785
-
786
- rebuild_model :storage => :s3,
787
- :bucket => "testing",
788
- :s3_credentials => {
789
- :credential_provider => DummyCredentialProvider.new
790
- }
791
- @dummy = Dummy.new
792
- end
793
-
794
- should "set the credential-provider" do
795
- assert_kind_of DummyCredentialProvider, @dummy.avatar.s3_bucket.config.credential_provider
796
- end
797
- end
798
-
799
- context "An attachment with S3 storage and S3 credentials in an unsupported manor" do
800
- setup do
801
- rebuild_model :storage => :s3, :bucket => "testing", :s3_credentials => ["unsupported"]
802
- @dummy = Dummy.new
803
- end
804
-
805
- should "not accept the credentials" do
806
- assert_raise(ArgumentError) do
807
- @dummy.avatar.s3_credentials
808
- end
809
- end
810
- end
811
-
812
- context "An attachment with S3 storage and S3 credentials not supplied" do
813
- setup do
814
- rebuild_model :storage => :s3, :bucket => "testing"
815
- @dummy = Dummy.new
816
- end
817
-
818
- should "not parse any credentials" do
819
- assert_equal({}, @dummy.avatar.s3_credentials)
820
- end
821
- end
822
-
823
- context "An attachment with S3 storage and specific s3 headers set" do
824
- setup do
825
- rebuild_model :storage => :s3,
826
- :bucket => "testing",
827
- :path => ":attachment/:style/:basename.:extension",
828
- :s3_credentials => {
829
- 'access_key_id' => "12345",
830
- 'secret_access_key' => "54321"
831
- },
832
- :s3_headers => {'Cache-Control' => 'max-age=31557600'}
833
- end
834
-
835
- context "when assigned" do
836
- setup do
837
- @file = File.new(fixture_file('5k.png'), 'rb')
838
- @dummy = Dummy.new
839
- @dummy.avatar = @file
840
- end
841
-
842
- teardown { @file.close }
843
-
844
- context "and saved" do
845
- setup do
846
- object = stub
847
- @dummy.avatar.stubs(:s3_object).returns(object)
848
- object.expects(:write).with(anything,
849
- :content_type => "image/png",
850
- :acl => :public_read,
851
- :cache_control => 'max-age=31557600')
852
- @dummy.save
853
- end
854
-
855
- should "succeed" do
856
- assert true
857
- end
858
- end
859
- end
860
- end
861
-
862
- context "An attachment with S3 storage and metadata set using header names" do
863
- setup do
864
- rebuild_model :storage => :s3,
865
- :bucket => "testing",
866
- :path => ":attachment/:style/:basename.:extension",
867
- :s3_credentials => {
868
- 'access_key_id' => "12345",
869
- 'secret_access_key' => "54321"
870
- },
871
- :s3_headers => {'x-amz-meta-color' => 'red'}
872
- end
873
-
874
- context "when assigned" do
875
- setup do
876
- @file = File.new(fixture_file('5k.png'), 'rb')
877
- @dummy = Dummy.new
878
- @dummy.avatar = @file
879
- end
880
-
881
- teardown { @file.close }
882
-
883
- context "and saved" do
884
- setup do
885
- object = stub
886
- @dummy.avatar.stubs(:s3_object).returns(object)
887
- object.expects(:write).with(anything,
888
- :content_type => "image/png",
889
- :acl => :public_read,
890
- :metadata => { "color" => "red" })
891
- @dummy.save
892
- end
893
-
894
- should "succeed" do
895
- assert true
896
- end
897
- end
898
- end
899
- end
900
-
901
- context "An attachment with S3 storage and metadata set using the :s3_metadata option" do
902
- setup do
903
- rebuild_model :storage => :s3,
904
- :bucket => "testing",
905
- :path => ":attachment/:style/:basename.:extension",
906
- :s3_credentials => {
907
- 'access_key_id' => "12345",
908
- 'secret_access_key' => "54321"
909
- },
910
- :s3_metadata => { "color" => "red" }
911
- end
912
-
913
- context "when assigned" do
914
- setup do
915
- @file = File.new(fixture_file('5k.png'), 'rb')
916
- @dummy = Dummy.new
917
- @dummy.avatar = @file
918
- end
919
-
920
- teardown { @file.close }
921
-
922
- context "and saved" do
923
- setup do
924
- object = stub
925
- @dummy.avatar.stubs(:s3_object).returns(object)
926
- object.expects(:write).with(anything,
927
- :content_type => "image/png",
928
- :acl => :public_read,
929
- :metadata => { "color" => "red" })
930
- @dummy.save
931
- end
932
-
933
- should "succeed" do
934
- assert true
935
- end
936
- end
937
- end
938
- end
939
-
940
- context "An attachment with S3 storage and storage class set using the header name" do
941
- setup do
942
- rebuild_model :storage => :s3,
943
- :bucket => "testing",
944
- :path => ":attachment/:style/:basename.:extension",
945
- :s3_credentials => {
946
- 'access_key_id' => "12345",
947
- 'secret_access_key' => "54321"
948
- },
949
- :s3_headers => { "x-amz-storage-class" => "reduced_redundancy" }
950
- end
951
-
952
- context "when assigned" do
953
- setup do
954
- @file = File.new(fixture_file('5k.png'), 'rb')
955
- @dummy = Dummy.new
956
- @dummy.avatar = @file
957
- end
958
-
959
- teardown { @file.close }
960
-
961
- context "and saved" do
962
- setup do
963
- object = stub
964
- @dummy.avatar.stubs(:s3_object).returns(object)
965
- object.expects(:write).with(anything,
966
- :content_type => "image/png",
967
- :acl => :public_read,
968
- :storage_class => "reduced_redundancy")
969
- @dummy.save
970
- end
971
-
972
- should "succeed" do
973
- assert true
974
- end
975
- end
976
- end
977
- end
978
-
979
- context "Can disable AES256 encryption multiple ways" do
980
- [nil, false, ''].each do |tech|
981
- setup do
982
- rebuild_model(
983
- :storage => :s3,
984
- :bucket => "testing",
985
- :path => ":attachment/:style/:basename.:extension",
986
- :s3_credentials => {
987
- 'access_key_id' => "12345",
988
- 'secret_access_key' => "54321"},
989
- :s3_server_side_encryption => tech)
990
- end
991
-
992
- context "when assigned" do
993
- setup do
994
- @file = File.new(fixture_file('5k.png'), 'rb')
995
- @dummy = Dummy.new
996
- @dummy.avatar = @file
997
- end
998
-
999
- teardown { @file.close }
1000
-
1001
- context "and saved" do
1002
- setup do
1003
- object = stub
1004
- @dummy.avatar.stubs(:s3_object).returns(object)
1005
- object.expects(:write).with(anything,
1006
- :content_type => "image/png",
1007
- :acl => :public_read)
1008
- @dummy.save
1009
- end
1010
-
1011
- should "succeed" do
1012
- assert true
1013
- end
1014
- end
1015
- end
1016
- end
1017
- end
1018
-
1019
- context "An attachment with S3 storage and using AES256 encryption" do
1020
- setup do
1021
- rebuild_model :storage => :s3,
1022
- :bucket => "testing",
1023
- :path => ":attachment/:style/:basename.:extension",
1024
- :s3_credentials => {
1025
- 'access_key_id' => "12345",
1026
- 'secret_access_key' => "54321"
1027
- },
1028
- :s3_server_side_encryption => :aes256
1029
- end
1030
-
1031
- context "when assigned" do
1032
- setup do
1033
- @file = File.new(fixture_file('5k.png'), 'rb')
1034
- @dummy = Dummy.new
1035
- @dummy.avatar = @file
1036
- end
1037
-
1038
- teardown { @file.close }
1039
-
1040
- context "and saved" do
1041
- setup do
1042
- object = stub
1043
- @dummy.avatar.stubs(:s3_object).returns(object)
1044
- object.expects(:write).with(anything,
1045
- :content_type => "image/png",
1046
- :acl => :public_read,
1047
- :server_side_encryption => 'AES256')
1048
- @dummy.save
1049
- end
1050
-
1051
- should "succeed" do
1052
- assert true
1053
- end
1054
- end
1055
- end
1056
- end
1057
-
1058
- context "An attachment with S3 storage and storage class set using the :storage_class option" do
1059
- setup do
1060
- rebuild_model :storage => :s3,
1061
- :bucket => "testing",
1062
- :path => ":attachment/:style/:basename.:extension",
1063
- :s3_credentials => {
1064
- 'access_key_id' => "12345",
1065
- 'secret_access_key' => "54321"
1066
- },
1067
- :s3_storage_class => :reduced_redundancy
1068
- end
1069
-
1070
- context "when assigned" do
1071
- setup do
1072
- @file = File.new(fixture_file('5k.png'), 'rb')
1073
- @dummy = Dummy.new
1074
- @dummy.avatar = @file
1075
- end
1076
-
1077
- teardown { @file.close }
1078
-
1079
- context "and saved" do
1080
- setup do
1081
- object = stub
1082
- @dummy.avatar.stubs(:s3_object).returns(object)
1083
- object.expects(:write).with(anything,
1084
- :content_type => "image/png",
1085
- :acl => :public_read,
1086
- :storage_class => :reduced_redundancy)
1087
- @dummy.save
1088
- end
1089
-
1090
- should "succeed" do
1091
- assert true
1092
- end
1093
- end
1094
- end
1095
- end
1096
-
1097
- context "with S3 credentials supplied as Pathname" do
1098
- setup do
1099
- ENV['S3_KEY'] = 'pathname_key'
1100
- ENV['S3_BUCKET'] = 'pathname_bucket'
1101
- ENV['S3_SECRET'] = 'pathname_secret'
1102
-
1103
- rails_env('test')
1104
-
1105
- rebuild_model :storage => :s3,
1106
- :s3_credentials => Pathname.new(fixture_file('s3.yml'))
1107
-
1108
- Dummy.delete_all
1109
- @dummy = Dummy.new
1110
- end
1111
-
1112
- should "parse the credentials" do
1113
- assert_equal 'pathname_bucket', @dummy.avatar.bucket_name
1114
- assert_equal 'pathname_key', @dummy.avatar.s3_bucket.config.access_key_id
1115
- assert_equal 'pathname_secret', @dummy.avatar.s3_bucket.config.secret_access_key
1116
- end
1117
- end
1118
-
1119
- context "with S3 credentials in a YAML file" do
1120
- setup do
1121
- ENV['S3_KEY'] = 'env_key'
1122
- ENV['S3_BUCKET'] = 'env_bucket'
1123
- ENV['S3_SECRET'] = 'env_secret'
1124
-
1125
- rails_env('test')
1126
-
1127
- rebuild_model :storage => :s3,
1128
- :s3_credentials => File.new(fixture_file('s3.yml'))
1129
-
1130
- Dummy.delete_all
1131
-
1132
- @dummy = Dummy.new
1133
- end
1134
-
1135
- should "run the file through ERB" do
1136
- assert_equal 'env_bucket', @dummy.avatar.bucket_name
1137
- assert_equal 'env_key', @dummy.avatar.s3_bucket.config.access_key_id
1138
- assert_equal 'env_secret', @dummy.avatar.s3_bucket.config.secret_access_key
1139
- end
1140
- end
1141
-
1142
- context "S3 Permissions" do
1143
- context "defaults to :public_read" do
1144
- setup do
1145
- rebuild_model :storage => :s3,
1146
- :bucket => "testing",
1147
- :path => ":attachment/:style/:basename.:extension",
1148
- :s3_credentials => {
1149
- 'access_key_id' => "12345",
1150
- 'secret_access_key' => "54321"
1151
- }
1152
- end
1153
-
1154
- context "when assigned" do
1155
- setup do
1156
- @file = File.new(fixture_file('5k.png'), 'rb')
1157
- @dummy = Dummy.new
1158
- @dummy.avatar = @file
1159
- end
1160
-
1161
- teardown { @file.close }
1162
-
1163
- context "and saved" do
1164
- setup do
1165
- object = stub
1166
- @dummy.avatar.stubs(:s3_object).returns(object)
1167
- object.expects(:write).with(anything,
1168
- :content_type => "image/png",
1169
- :acl => :public_read)
1170
- @dummy.save
1171
- end
1172
-
1173
- should "succeed" do
1174
- assert true
1175
- end
1176
- end
1177
- end
1178
- end
1179
-
1180
- context "string permissions set" do
1181
- setup do
1182
- rebuild_model :storage => :s3,
1183
- :bucket => "testing",
1184
- :path => ":attachment/:style/:basename.:extension",
1185
- :s3_credentials => {
1186
- 'access_key_id' => "12345",
1187
- 'secret_access_key' => "54321"
1188
- },
1189
- :s3_permissions => :private
1190
- end
1191
-
1192
- context "when assigned" do
1193
- setup do
1194
- @file = File.new(fixture_file('5k.png'), 'rb')
1195
- @dummy = Dummy.new
1196
- @dummy.avatar = @file
1197
- end
1198
-
1199
- teardown { @file.close }
1200
-
1201
- context "and saved" do
1202
- setup do
1203
- object = stub
1204
- @dummy.avatar.stubs(:s3_object).returns(object)
1205
- object.expects(:write).with(anything,
1206
- :content_type => "image/png",
1207
- :acl => :private)
1208
- @dummy.save
1209
- end
1210
-
1211
- should "succeed" do
1212
- assert true
1213
- end
1214
- end
1215
- end
1216
- end
1217
-
1218
- context "hash permissions set" do
1219
- setup do
1220
- rebuild_model :storage => :s3,
1221
- :bucket => "testing",
1222
- :path => ":attachment/:style/:basename.:extension",
1223
- :styles => {
1224
- :thumb => "80x80>"
1225
- },
1226
- :s3_credentials => {
1227
- 'access_key_id' => "12345",
1228
- 'secret_access_key' => "54321"
1229
- },
1230
- :s3_permissions => {
1231
- :original => :private,
1232
- :thumb => :public_read
1233
- }
1234
- end
1235
-
1236
- context "when assigned" do
1237
- setup do
1238
- @file = File.new(fixture_file('5k.png'), 'rb')
1239
- @dummy = Dummy.new
1240
- @dummy.avatar = @file
1241
- end
1242
-
1243
- teardown { @file.close }
1244
-
1245
- context "and saved" do
1246
- setup do
1247
- [:thumb, :original].each do |style|
1248
- object = stub
1249
- @dummy.avatar.stubs(:s3_object).with(style).returns(object)
1250
- object.expects(:write).with(anything,
1251
- :content_type => "image/png",
1252
- :acl => style == :thumb ? :public_read : :private)
1253
- end
1254
- @dummy.save
1255
- end
1256
-
1257
- should "succeed" do
1258
- assert true
1259
- end
1260
- end
1261
- end
1262
- end
1263
-
1264
- context "proc permission set" do
1265
- setup do
1266
- rebuild_model(
1267
- :storage => :s3,
1268
- :bucket => "testing",
1269
- :path => ":attachment/:style/:basename.:extension",
1270
- :styles => {
1271
- :thumb => "80x80>"
1272
- },
1273
- :s3_credentials => {
1274
- 'access_key_id' => "12345",
1275
- 'secret_access_key' => "54321"
1276
- },
1277
- :s3_permissions => lambda {|attachment, style|
1278
- attachment.instance.private_attachment? && style.to_sym != :thumb ? :private : :public_read
1279
- }
1280
- )
1281
- end
1282
-
1283
- context "when assigned" do
1284
- setup do
1285
- @file = File.new(fixture_file('5k.png'), 'rb')
1286
- @dummy = Dummy.new
1287
- @dummy.stubs(:private_attachment? => true)
1288
- @dummy.avatar = @file
1289
- end
1290
-
1291
- teardown { @file.close }
1292
-
1293
- context "and saved" do
1294
- setup do
1295
- @dummy.save
1296
- end
1297
-
1298
- should "succeed" do
1299
- assert @dummy.avatar.url().include? "https://"
1300
- assert @dummy.avatar.url(:thumb).include? "http://"
1301
- end
1302
- end
1303
- end
1304
-
1305
- end
1306
- end
1307
-
1308
- context "An attachment with S3 storage and metadata set using a proc as headers" do
1309
- setup do
1310
- rebuild_model(
1311
- :storage => :s3,
1312
- :bucket => "testing",
1313
- :path => ":attachment/:style/:basename.:extension",
1314
- :styles => {
1315
- :thumb => "80x80>"
1316
- },
1317
- :s3_credentials => {
1318
- 'access_key_id' => "12345",
1319
- 'secret_access_key' => "54321"
1320
- },
1321
- :s3_headers => lambda {|attachment|
1322
- {'Content-Disposition' => "attachment; filename=\"#{attachment.name}\""}
1323
- }
1324
- )
1325
- end
1326
-
1327
- context "when assigned" do
1328
- setup do
1329
- @file = File.new(fixture_file('5k.png'), 'rb')
1330
- @dummy = Dummy.new
1331
- @dummy.stubs(:name => 'Custom Avatar Name.png')
1332
- @dummy.avatar = @file
1333
- end
1334
-
1335
- teardown { @file.close }
1336
-
1337
- context "and saved" do
1338
- setup do
1339
- [:thumb, :original].each do |style|
1340
- object = stub
1341
- @dummy.avatar.stubs(:s3_object).with(style).returns(object)
1342
- object.expects(:write).with(anything,
1343
- :content_type => "image/png",
1344
- :acl => :public_read,
1345
- :content_disposition => 'attachment; filename="Custom Avatar Name.png"')
1346
- end
1347
- @dummy.save
1348
- end
1349
-
1350
- should "succeed" do
1351
- assert true
1352
- end
1353
- end
1354
- end
1355
- end
1356
- end