paperclip 3.4.0 → 6.1.0

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