paperclip 4.2.2 → 5.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +17 -0
  3. data/.hound.yml +1055 -0
  4. data/.rubocop.yml +1 -0
  5. data/.travis.yml +17 -15
  6. data/Appraisals +4 -16
  7. data/CONTRIBUTING.md +19 -8
  8. data/Gemfile +5 -9
  9. data/LICENSE +1 -1
  10. data/NEWS +148 -31
  11. data/README.md +327 -191
  12. data/RELEASING.md +17 -0
  13. data/Rakefile +2 -2
  14. data/UPGRADING +12 -9
  15. data/features/basic_integration.feature +10 -6
  16. data/features/migration.feature +0 -24
  17. data/features/step_definitions/attachment_steps.rb +33 -27
  18. data/features/step_definitions/html_steps.rb +2 -2
  19. data/features/step_definitions/rails_steps.rb +39 -38
  20. data/features/step_definitions/s3_steps.rb +2 -2
  21. data/features/step_definitions/web_steps.rb +1 -103
  22. data/features/support/env.rb +1 -0
  23. data/features/support/file_helpers.rb +2 -2
  24. data/features/support/paths.rb +1 -1
  25. data/features/support/rails.rb +0 -24
  26. data/gemfiles/4.2.gemfile +6 -8
  27. data/gemfiles/5.0.gemfile +17 -0
  28. data/lib/paperclip/attachment.rb +32 -20
  29. data/lib/paperclip/attachment_registry.rb +3 -2
  30. data/lib/paperclip/callbacks.rb +8 -6
  31. data/lib/paperclip/content_type_detector.rb +27 -11
  32. data/lib/paperclip/errors.rb +3 -1
  33. data/lib/paperclip/file_command_content_type_detector.rb +6 -8
  34. data/lib/paperclip/geometry_parser_factory.rb +1 -1
  35. data/lib/paperclip/glue.rb +1 -1
  36. data/lib/paperclip/has_attached_file.rb +9 -2
  37. data/lib/paperclip/helpers.rb +14 -10
  38. data/lib/paperclip/interpolations/plural_cache.rb +6 -5
  39. data/lib/paperclip/interpolations.rb +19 -14
  40. data/lib/paperclip/io_adapters/abstract_adapter.rb +26 -3
  41. data/lib/paperclip/io_adapters/attachment_adapter.rb +10 -5
  42. data/lib/paperclip/io_adapters/data_uri_adapter.rb +8 -8
  43. data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
  44. data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
  45. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +7 -7
  46. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
  47. data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
  48. data/lib/paperclip/io_adapters/registry.rb +6 -2
  49. data/lib/paperclip/io_adapters/stringio_adapter.rb +9 -6
  50. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
  51. data/lib/paperclip/io_adapters/uri_adapter.rb +41 -19
  52. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
  53. data/lib/paperclip/media_type_spoof_detector.rb +2 -2
  54. data/lib/paperclip/processor.rb +5 -4
  55. data/lib/paperclip/rails_environment.rb +25 -0
  56. data/lib/paperclip/schema.rb +3 -9
  57. data/lib/paperclip/storage/filesystem.rb +13 -2
  58. data/lib/paperclip/storage/fog.rb +30 -18
  59. data/lib/paperclip/storage/s3.rb +92 -65
  60. data/lib/paperclip/thumbnail.rb +16 -7
  61. data/lib/paperclip/url_generator.rb +16 -13
  62. data/lib/paperclip/validators/attachment_size_validator.rb +1 -7
  63. data/lib/paperclip/validators.rb +1 -1
  64. data/lib/paperclip/version.rb +3 -1
  65. data/lib/paperclip.rb +25 -12
  66. data/lib/tasks/paperclip.rake +33 -3
  67. data/paperclip.gemspec +18 -15
  68. data/spec/paperclip/attachment_definitions_spec.rb +1 -1
  69. data/spec/paperclip/attachment_processing_spec.rb +2 -4
  70. data/spec/paperclip/attachment_registry_spec.rb +84 -13
  71. data/spec/paperclip/attachment_spec.rb +130 -39
  72. data/spec/paperclip/content_type_detector_spec.rb +8 -1
  73. data/spec/paperclip/file_command_content_type_detector_spec.rb +0 -1
  74. data/spec/paperclip/geometry_spec.rb +1 -1
  75. data/spec/paperclip/glue_spec.rb +44 -0
  76. data/spec/paperclip/has_attached_file_spec.rb +24 -8
  77. data/spec/paperclip/integration_spec.rb +4 -3
  78. data/spec/paperclip/interpolations_spec.rb +16 -13
  79. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +47 -23
  80. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +6 -3
  81. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +7 -1
  82. data/spec/paperclip/io_adapters/file_adapter_spec.rb +6 -3
  83. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +26 -6
  84. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
  85. data/spec/paperclip/io_adapters/registry_spec.rb +2 -2
  86. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +5 -1
  87. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +5 -5
  88. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +77 -7
  89. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +10 -0
  90. data/spec/paperclip/media_type_spoof_detector_spec.rb +34 -11
  91. data/spec/paperclip/paperclip_spec.rb +4 -29
  92. data/spec/paperclip/plural_cache_spec.rb +17 -16
  93. data/spec/paperclip/rails_environment_spec.rb +33 -0
  94. data/spec/paperclip/storage/fog_spec.rb +58 -3
  95. data/spec/paperclip/storage/s3_live_spec.rb +20 -14
  96. data/spec/paperclip/storage/s3_spec.rb +398 -213
  97. data/spec/paperclip/tempfile_factory_spec.rb +4 -0
  98. data/spec/paperclip/tempfile_spec.rb +35 -0
  99. data/spec/paperclip/thumbnail_spec.rb +51 -32
  100. data/spec/paperclip/url_generator_spec.rb +55 -44
  101. data/spec/paperclip/validators/attachment_size_validator_spec.rb +26 -20
  102. data/spec/paperclip/validators_spec.rb +5 -5
  103. data/spec/spec_helper.rb +8 -1
  104. data/spec/support/assertions.rb +12 -1
  105. data/spec/support/conditional_filter_helper.rb +5 -0
  106. data/spec/support/fake_model.rb +4 -0
  107. data/spec/support/fixtures/empty.xlsx +0 -0
  108. data/spec/support/matchers/have_column.rb +11 -2
  109. data/spec/support/mock_attachment.rb +2 -0
  110. data/spec/support/mock_url_generator_builder.rb +2 -2
  111. data/spec/support/model_reconstruction.rb +9 -1
  112. data/spec/support/reporting.rb +11 -0
  113. metadata +109 -162
  114. data/RUNNING_TESTS.md +0 -4
  115. data/cucumber/paperclip_steps.rb +0 -6
  116. data/gemfiles/3.2.gemfile +0 -19
  117. data/gemfiles/4.0.gemfile +0 -19
  118. data/gemfiles/4.1.gemfile +0 -19
  119. data/lib/paperclip/locales/de.yml +0 -18
  120. data/lib/paperclip/locales/es.yml +0 -18
  121. data/lib/paperclip/locales/ja.yml +0 -18
  122. data/lib/paperclip/locales/pt-BR.yml +0 -18
  123. data/lib/paperclip/locales/zh-CN.yml +0 -18
  124. data/lib/paperclip/locales/zh-HK.yml +0 -18
  125. data/lib/paperclip/locales/zh-TW.yml +0 -18
  126. data/spec/support/mock_model.rb +0 -2
  127. data/spec/support/rails_helpers.rb +0 -7
@@ -17,22 +17,26 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
17
17
 
18
18
  it "rejects a class with no validation" do
19
19
  expect(matcher).to_not accept(Dummy)
20
+ expect { matcher.failure_message }.to_not raise_error
20
21
  end
21
22
 
22
23
  it 'rejects a class when the validation fails' do
23
24
  Dummy.validates_attachment_content_type :avatar, content_type: %r{audio/.*}
24
25
  expect(matcher).to_not accept(Dummy)
26
+ expect { matcher.failure_message }.to_not raise_error
25
27
  end
26
28
 
27
29
  it "accepts a class with a matching validation" do
28
30
  Dummy.validates_attachment_content_type :avatar, content_type: %r{image/.*}
29
31
  expect(matcher).to accept(Dummy)
32
+ expect { matcher.failure_message }.to_not raise_error
30
33
  end
31
34
 
32
35
  it "accepts a class with other validations but matching types" do
33
36
  Dummy.validates_presence_of :title
34
37
  Dummy.validates_attachment_content_type :avatar, content_type: %r{image/.*}
35
38
  expect(matcher).to accept(Dummy)
39
+ expect { matcher.failure_message }.to_not raise_error
36
40
  end
37
41
 
38
42
  it "accepts a class that matches and a matcher that only specifies 'allowing'" do
@@ -40,6 +44,7 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
40
44
  matcher = plain_matcher.allowing(%w(image/png image/jpeg))
41
45
 
42
46
  expect(matcher).to accept(Dummy)
47
+ expect { matcher.failure_message }.to_not raise_error
43
48
  end
44
49
 
45
50
  it "rejects a class that does not match and a matcher that only specifies 'allowing'" do
@@ -47,6 +52,7 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
47
52
  matcher = plain_matcher.allowing(%w(image/png image/jpeg))
48
53
 
49
54
  expect(matcher).to_not accept(Dummy)
55
+ expect { matcher.failure_message }.to_not raise_error
50
56
  end
51
57
 
52
58
  it "accepts a class that matches and a matcher that only specifies 'rejecting'" do
@@ -54,6 +60,7 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
54
60
  matcher = plain_matcher.rejecting(%w(audio/mp3 application/octet-stream))
55
61
 
56
62
  expect(matcher).to accept(Dummy)
63
+ expect { matcher.failure_message }.to_not raise_error
57
64
  end
58
65
 
59
66
  it "rejects a class that does not match and a matcher that only specifies 'rejecting'" do
@@ -61,6 +68,7 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
61
68
  matcher = plain_matcher.rejecting(%w(audio/mp3 application/octet-stream))
62
69
 
63
70
  expect(matcher).to_not accept(Dummy)
71
+ expect { matcher.failure_message }.to_not raise_error
64
72
  end
65
73
 
66
74
  context "using an :if to control the validation" do
@@ -75,12 +83,14 @@ describe Paperclip::Shoulda::Matchers::ValidateAttachmentContentTypeMatcher do
75
83
  dummy = Dummy.new
76
84
  dummy.go = true
77
85
  expect(matcher).to accept(dummy)
86
+ expect { matcher.failure_message }.to_not raise_error
78
87
  end
79
88
 
80
89
  it "does not run the validation if the control is false" do
81
90
  dummy = Dummy.new
82
91
  dummy.go = false
83
92
  expect(matcher).to_not accept(dummy)
93
+ expect { matcher.failure_message }.to_not raise_error
84
94
  end
85
95
  end
86
96
 
@@ -3,32 +3,32 @@ require 'spec_helper'
3
3
  describe Paperclip::MediaTypeSpoofDetector do
4
4
  it 'rejects a file that is named .html and identifies as PNG' do
5
5
  file = File.open(fixture_file("5k.png"))
6
- assert Paperclip::MediaTypeSpoofDetector.using(file, "5k.html").spoofed?
6
+ assert Paperclip::MediaTypeSpoofDetector.using(file, "5k.html", "image/png").spoofed?
7
7
  end
8
8
 
9
9
  it 'does not reject a file that is named .jpg and identifies as PNG' do
10
10
  file = File.open(fixture_file("5k.png"))
11
- assert ! Paperclip::MediaTypeSpoofDetector.using(file, "5k.jpg").spoofed?
11
+ assert ! Paperclip::MediaTypeSpoofDetector.using(file, "5k.jpg", "image/png").spoofed?
12
12
  end
13
13
 
14
14
  it 'does not reject a file that is named .html and identifies as HTML' do
15
15
  file = File.open(fixture_file("empty.html"))
16
- assert ! Paperclip::MediaTypeSpoofDetector.using(file, "empty.html").spoofed?
16
+ assert ! Paperclip::MediaTypeSpoofDetector.using(file, "empty.html", "text/html").spoofed?
17
17
  end
18
18
 
19
19
  it 'does not reject a file that does not have a name' do
20
20
  file = File.open(fixture_file("empty.html"))
21
- assert ! Paperclip::MediaTypeSpoofDetector.using(file, "").spoofed?
21
+ assert ! Paperclip::MediaTypeSpoofDetector.using(file, "", "text/html").spoofed?
22
22
  end
23
23
 
24
24
  it 'does not reject a file that does have an extension' do
25
25
  file = File.open(fixture_file("empty.html"))
26
- assert ! Paperclip::MediaTypeSpoofDetector.using(file, "data").spoofed?
26
+ assert ! Paperclip::MediaTypeSpoofDetector.using(file, "data", "text/html").spoofed?
27
27
  end
28
28
 
29
29
  it 'does not reject when the supplied file is an IOAdapter' do
30
30
  adapter = Paperclip.io_adapters.for(File.new(fixture_file("5k.png")))
31
- assert ! Paperclip::MediaTypeSpoofDetector.using(adapter, adapter.original_filename).spoofed?
31
+ assert ! Paperclip::MediaTypeSpoofDetector.using(adapter, adapter.original_filename, adapter.content_type).spoofed?
32
32
  end
33
33
 
34
34
  it 'does not reject when the extension => content_type is in :content_type_mappings' do
@@ -38,19 +38,42 @@ describe Paperclip::MediaTypeSpoofDetector do
38
38
  file.puts "Certificate!"
39
39
  file.close
40
40
  adapter = Paperclip.io_adapters.for(File.new(file.path));
41
- assert ! Paperclip::MediaTypeSpoofDetector.using(adapter, adapter.original_filename).spoofed?
41
+ assert ! Paperclip::MediaTypeSpoofDetector.using(adapter, adapter.original_filename, adapter.content_type).spoofed?
42
42
  ensure
43
43
  Paperclip.options[:content_type_mappings] = {}
44
44
  end
45
45
  end
46
46
 
47
- it "rejects a file if named .html and is as HTML, but we're told JPG" do
48
- file = File.open(fixture_file("empty.html"))
49
- assert Paperclip::MediaTypeSpoofDetector.using(file, "empty.html", "image/jpg").spoofed?
47
+ context "file named .html and is as HTML, but we're told JPG" do
48
+ let(:file) { File.open(fixture_file("empty.html")) }
49
+ let(:spoofed?) { Paperclip::MediaTypeSpoofDetector.using(file, "empty.html", "image/jpg").spoofed? }
50
+
51
+ it "rejects the file" do
52
+ assert spoofed?
53
+ end
54
+
55
+ it "logs info about the detected spoof" do
56
+ Paperclip.expects(:log).with('Content Type Spoof: Filename empty.html (image/jpg from Headers, ["text/html"] from Extension), content type discovered from file command: text/html. See documentation to allow this combination.')
57
+ spoofed?
58
+ end
50
59
  end
51
60
 
52
- it "does not reject is content_type is empty but otherwise checks out" do
61
+ it "does not reject if content_type is empty but otherwise checks out" do
53
62
  file = File.open(fixture_file("empty.html"))
54
63
  assert ! Paperclip::MediaTypeSpoofDetector.using(file, "empty.html", "").spoofed?
55
64
  end
65
+
66
+ it 'does allow array as :content_type_mappings' do
67
+ begin
68
+ Paperclip.options[:content_type_mappings] = {
69
+ html: ['binary', 'text/html']
70
+ }
71
+ file = File.open(fixture_file('empty.html'))
72
+ spoofed = Paperclip::MediaTypeSpoofDetector
73
+ .using(file, "empty.html", "text/html").spoofed?
74
+ assert !spoofed
75
+ ensure
76
+ Paperclip.options[:content_type_mappings] = {}
77
+ end
78
+ end
56
79
  end
@@ -20,7 +20,7 @@ describe Paperclip do
20
20
  it "saves Cocaine::CommandLine.path that set before" do
21
21
  Cocaine::CommandLine.path = "/opt/my_app/bin"
22
22
  Paperclip.run("convert", "stuff")
23
- assert_equal [Cocaine::CommandLine.path].flatten.include?("/opt/my_app/bin"), true
23
+ expect(Cocaine::CommandLine.path).to match("/opt/my_app/bin")
24
24
  end
25
25
 
26
26
  it "does not duplicate Cocaine::CommandLine.path on multiple runs" do
@@ -29,7 +29,9 @@ describe Paperclip do
29
29
  Paperclip.options[:command_path] = "/opt/my_app/bin"
30
30
  Paperclip.run("convert", "stuff")
31
31
  Paperclip.run("convert", "more_stuff")
32
- assert_equal 1, [Cocaine::CommandLine.path].flatten.size
32
+
33
+ cmd_path = Paperclip.options[:command_path]
34
+ assert_equal 1, Cocaine::CommandLine.path.scan(cmd_path).count
33
35
  end
34
36
  end
35
37
 
@@ -123,33 +125,6 @@ describe Paperclip do
123
125
  end
124
126
  end
125
127
 
126
- if using_protected_attributes?
127
- context "that is attr_protected" do
128
- before do
129
- Dummy.class_eval do
130
- attr_protected :avatar
131
- end
132
- @dummy = Dummy.new
133
- end
134
-
135
- it "does not assign the avatar on mass-set" do
136
- @dummy.attributes = { other: "I'm set!",
137
- avatar: @file }
138
-
139
- assert_equal "I'm set!", @dummy.other
140
- assert ! @dummy.avatar?
141
- end
142
-
143
- it "allows assigment on normal set" do
144
- @dummy.other = "I'm set!"
145
- @dummy.avatar = @file
146
-
147
- assert_equal "I'm set!", @dummy.other
148
- assert @dummy.avatar?
149
- end
150
- end
151
- end
152
-
153
128
  context "with a subclass" do
154
129
  before do
155
130
  class ::SubDummy < Dummy; end
@@ -3,34 +3,35 @@ require 'spec_helper'
3
3
  describe 'Plural cache' do
4
4
  it 'caches pluralizations' do
5
5
  cache = Paperclip::Interpolations::PluralCache.new
6
- word = "box"
6
+ symbol = :box
7
7
 
8
- word.expects(:pluralize).returns("boxes").once
9
-
10
- cache.pluralize(word)
11
- cache.pluralize(word)
8
+ first = cache.pluralize_symbol(symbol)
9
+ second = cache.pluralize_symbol(symbol)
10
+ expect(first).to equal(second)
12
11
  end
13
12
 
14
13
  it 'caches pluralizations and underscores' do
14
+ class BigBox ; end
15
15
  cache = Paperclip::Interpolations::PluralCache.new
16
- word = "BigBox"
17
-
18
- word.expects(:pluralize).returns(word).once
19
- word.expects(:underscore).returns(word).once
16
+ klass = BigBox
20
17
 
21
- cache.underscore_and_pluralize(word)
22
- cache.underscore_and_pluralize(word)
18
+ first = cache.underscore_and_pluralize_class(klass)
19
+ second = cache.underscore_and_pluralize_class(klass)
20
+ expect(first).to equal(second)
23
21
  end
24
22
 
25
23
  it 'pluralizes words' do
26
24
  cache = Paperclip::Interpolations::PluralCache.new
27
- word = "box"
28
- assert_equal "boxes", cache.pluralize(word)
25
+ symbol = :box
26
+
27
+ expect(cache.pluralize_symbol(symbol)).to eq("boxes")
29
28
  end
30
29
 
31
- it 'pluralizes and underscore words' do
30
+ it 'pluralizes and underscore class names' do
31
+ class BigBox ; end
32
32
  cache = Paperclip::Interpolations::PluralCache.new
33
- word = "BigBox"
34
- assert_equal "big_boxes", cache.underscore_and_pluralize(word)
33
+ klass = BigBox
34
+
35
+ expect(cache.underscore_and_pluralize_class(klass)).to eq("big_boxes")
35
36
  end
36
37
  end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::RailsEnvironment do
4
+
5
+ it "returns nil when Rails isn't defined" do
6
+ resetting_rails_to(nil) do
7
+ expect(Paperclip::RailsEnvironment.get).to be_nil
8
+ end
9
+ end
10
+
11
+ it "returns nil when Rails.env isn't defined" do
12
+ resetting_rails_to({}) do
13
+ expect(Paperclip::RailsEnvironment.get).to be_nil
14
+ end
15
+ end
16
+
17
+ it "returns the value of Rails.env if it is set" do
18
+ resetting_rails_to(OpenStruct.new(env: "foo")) do
19
+ expect(Paperclip::RailsEnvironment.get).to eq "foo"
20
+ end
21
+ end
22
+
23
+ def resetting_rails_to(new_value)
24
+ begin
25
+ previous_rails = Object.send(:remove_const, "Rails")
26
+ Object.const_set("Rails", new_value) unless new_value.nil?
27
+ yield
28
+ ensure
29
+ Object.send(:remove_const, "Rails") if Object.const_defined?("Rails")
30
+ Object.const_set("Rails", previous_rails)
31
+ end
32
+ end
33
+ end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
- require 'fog'
2
+ require 'fog/aws'
3
+ require 'fog/local'
3
4
  require 'timecop'
4
5
 
5
6
  describe Paperclip::Storage::Fog do
@@ -182,6 +183,13 @@ describe Paperclip::Storage::Fog do
182
183
  tempfile.close
183
184
  end
184
185
 
186
+ it 'is able to be handled when missing while copying to a local file' do
187
+ tempfile = Tempfile.new("known_location")
188
+ tempfile.binmode
189
+ assert_equal false, @dummy.avatar.copy_to_local_file(:original, tempfile.path)
190
+ tempfile.close
191
+ end
192
+
185
193
  it "passes the content type to the Fog::Storage::AWS::Files instance" do
186
194
  Fog::Storage::AWS::Files.any_instance.expects(:create).with do |hash|
187
195
  hash[:content_type]
@@ -265,6 +273,22 @@ describe Paperclip::Storage::Fog do
265
273
  end
266
274
  end
267
275
 
276
+ context "with fog_public as a proc" do
277
+ let(:proc) { ->(attachment) { !attachment } }
278
+
279
+ before do
280
+ rebuild_model(@options.merge(fog_public: proc))
281
+ @dummy = Dummy.new
282
+ @dummy.avatar = StringIO.new(".")
283
+ @dummy.save
284
+ end
285
+
286
+ it "sets the @fog_public instance variable to false" do
287
+ assert_equal proc, @dummy.avatar.instance_variable_get("@options")[:fog_public]
288
+ assert_equal false, @dummy.avatar.fog_public
289
+ end
290
+ end
291
+
268
292
  context "with styles set and fog_public set to false" do
269
293
  before do
270
294
  rebuild_model(@options.merge(fog_public: false, styles: { medium: "300x300>", thumb: "100x100>" }))
@@ -320,6 +344,9 @@ describe Paperclip::Storage::Fog do
320
344
  it "honors the scheme in public url" do
321
345
  assert_match(/^http:\/\//, @dummy.avatar.url)
322
346
  end
347
+ it "honors the scheme in expiring url" do
348
+ assert_match(/^http:\/\//, @dummy.avatar.expiring_url)
349
+ end
323
350
  end
324
351
 
325
352
  context "with scheme not set" do
@@ -334,15 +361,20 @@ describe Paperclip::Storage::Fog do
334
361
  it "provides HTTPS public url" do
335
362
  assert_match(/^https:\/\//, @dummy.avatar.url)
336
363
  end
364
+ it "provides HTTPS expiring url" do
365
+ assert_match(/^https:\/\//, @dummy.avatar.expiring_url)
366
+ end
337
367
  end
338
368
 
339
369
  context "with a valid bucket name for a subdomain" do
370
+ before { @dummy.stubs(:new_record?).returns(false) }
371
+
340
372
  it "provides an url in subdomain style" do
341
373
  assert_match(/^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png/, @dummy.avatar.url)
342
374
  end
343
375
 
344
376
  it "provides an url that expires in subdomain style" do
345
- assert_match(/^http:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url)
377
+ assert_match(/^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url)
346
378
  end
347
379
  end
348
380
 
@@ -390,7 +422,7 @@ describe Paperclip::Storage::Fog do
390
422
  end
391
423
 
392
424
  it "provides a url that expires in folder style" do
393
- assert_match(/^http:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url)
425
+ assert_match(/^https:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url)
394
426
  end
395
427
 
396
428
  end
@@ -409,6 +441,9 @@ describe Paperclip::Storage::Fog do
409
441
  assert @connection.directories.get(@dynamic_fog_directory).inspect
410
442
  end
411
443
 
444
+ it "provides an url using dynamic bucket name" do
445
+ assert_match(/^https:\/\/dynamicpaperclip.s3.amazonaws.com\/avatars\/5k.png\?\d*$/, @dummy.avatar.url)
446
+ end
412
447
  end
413
448
 
414
449
  context "with a proc for the fog_host evaluating a model method" do
@@ -475,6 +510,25 @@ describe Paperclip::Storage::Fog do
475
510
  assert_equal @dummy.avatar.fog_credentials, @dynamic_fog_credentials
476
511
  end
477
512
  end
513
+
514
+ context "with custom fog_options" do
515
+ before do
516
+ rebuild_model(
517
+ @options.merge(fog_options: { multipart_chunk_size: 104857600 }),
518
+ )
519
+ @dummy = Dummy.new
520
+ @dummy.avatar = @file
521
+ end
522
+
523
+ it "applies the options to the fog #create call" do
524
+ files = stub
525
+ @dummy.avatar.stubs(:directory).returns stub(files: files)
526
+ files.expects(:create).with(
527
+ has_entries(multipart_chunk_size: 104857600),
528
+ )
529
+ @dummy.save
530
+ end
531
+ end
478
532
  end
479
533
 
480
534
  end
@@ -492,6 +546,7 @@ describe Paperclip::Storage::Fog do
492
546
  @file = File.new(fixture_file('5k.png'), 'rb')
493
547
  @dummy = Dummy.new
494
548
  @dummy.avatar = @file
549
+ @dummy.stubs(:new_record?).returns(false)
495
550
  end
496
551
 
497
552
  after do
@@ -8,9 +8,10 @@ unless ENV["S3_BUCKET"].blank?
8
8
  storage: :s3,
9
9
  bucket: ENV["S3_BUCKET"],
10
10
  path: ":class/:attachment/:id/:style.:extension",
11
+ s3_region: ENV["S3_REGION"],
11
12
  s3_credentials: {
12
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
13
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
13
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
14
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
14
15
  }
15
16
 
16
17
  @file = File.new(fixture_file("5k.png"))
@@ -45,9 +46,10 @@ unless ENV["S3_BUCKET"].blank?
45
46
  storage: :s3,
46
47
  bucket: ENV["S3_BUCKET"],
47
48
  path: ":class/:attachment/:id/:style.:extension",
49
+ s3_region: ENV["S3_REGION"],
48
50
  s3_credentials: {
49
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
50
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
51
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
52
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
51
53
  }
52
54
 
53
55
  @dummy = Dummy.new
@@ -64,9 +66,10 @@ unless ENV["S3_BUCKET"].blank?
64
66
  storage: :s3,
65
67
  bucket: ENV["S3_BUCKET"],
66
68
  path: ":class/:attachment/:id/:style.:extension",
69
+ s3_region: ENV["S3_REGION"],
67
70
  s3_credentials: {
68
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
69
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
71
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
72
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
70
73
  }
71
74
 
72
75
  Dummy.delete_all
@@ -105,9 +108,12 @@ unless ENV["S3_BUCKET"].blank?
105
108
  rebuild_model styles: { thumb: "100x100", square: "32x32#" },
106
109
  storage: :s3,
107
110
  bucket: ENV["S3_BUCKET"],
111
+ s3_region: ENV["S3_REGION"],
112
+ url: ":s3_domain_url",
113
+ path: "/:class/:attachment/:id_partition/:style/:filename",
108
114
  s3_credentials: {
109
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
110
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
115
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
116
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
111
117
  }
112
118
 
113
119
  Dummy.delete_all
@@ -136,7 +142,7 @@ unless ENV["S3_BUCKET"].blank?
136
142
  it "is destroyable" do
137
143
  url = @dummy.avatar.url
138
144
  @dummy.destroy
139
- assert_not_found_response url
145
+ assert_forbidden_response url
140
146
  end
141
147
  end
142
148
 
@@ -146,12 +152,12 @@ unless ENV["S3_BUCKET"].blank?
146
152
  storage: :s3,
147
153
  bucket: ENV["S3_BUCKET"],
148
154
  path: ":class/:attachment/:id/:style.:extension",
155
+ s3_region: ENV["S3_REGION"],
149
156
  s3_credentials: {
150
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
151
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
157
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
158
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
152
159
  },
153
- s3_server_side_encryption: :aes256
154
-
160
+ s3_server_side_encryption: "AES256"
155
161
  Dummy.delete_all
156
162
  @dummy = Dummy.new
157
163
  end
@@ -173,7 +179,7 @@ unless ENV["S3_BUCKET"].blank?
173
179
  end
174
180
 
175
181
  it "is encrypted on S3" do
176
- assert @dummy.avatar.s3_object.server_side_encryption == :aes256
182
+ assert @dummy.avatar.s3_object.server_side_encryption == "AES256"
177
183
  end
178
184
  end
179
185
  end