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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +17 -0
- data/.hound.yml +1055 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +17 -15
- data/Appraisals +4 -16
- data/CONTRIBUTING.md +19 -8
- data/Gemfile +5 -9
- data/LICENSE +1 -1
- data/NEWS +148 -31
- data/README.md +327 -191
- data/RELEASING.md +17 -0
- data/Rakefile +2 -2
- data/UPGRADING +12 -9
- data/features/basic_integration.feature +10 -6
- data/features/migration.feature +0 -24
- data/features/step_definitions/attachment_steps.rb +33 -27
- data/features/step_definitions/html_steps.rb +2 -2
- data/features/step_definitions/rails_steps.rb +39 -38
- data/features/step_definitions/s3_steps.rb +2 -2
- data/features/step_definitions/web_steps.rb +1 -103
- data/features/support/env.rb +1 -0
- data/features/support/file_helpers.rb +2 -2
- data/features/support/paths.rb +1 -1
- data/features/support/rails.rb +0 -24
- data/gemfiles/4.2.gemfile +6 -8
- data/gemfiles/5.0.gemfile +17 -0
- data/lib/paperclip/attachment.rb +32 -20
- data/lib/paperclip/attachment_registry.rb +3 -2
- data/lib/paperclip/callbacks.rb +8 -6
- data/lib/paperclip/content_type_detector.rb +27 -11
- data/lib/paperclip/errors.rb +3 -1
- data/lib/paperclip/file_command_content_type_detector.rb +6 -8
- data/lib/paperclip/geometry_parser_factory.rb +1 -1
- data/lib/paperclip/glue.rb +1 -1
- data/lib/paperclip/has_attached_file.rb +9 -2
- data/lib/paperclip/helpers.rb +14 -10
- data/lib/paperclip/interpolations/plural_cache.rb +6 -5
- data/lib/paperclip/interpolations.rb +19 -14
- data/lib/paperclip/io_adapters/abstract_adapter.rb +26 -3
- data/lib/paperclip/io_adapters/attachment_adapter.rb +10 -5
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +8 -8
- data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
- data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +7 -7
- data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
- data/lib/paperclip/io_adapters/registry.rb +6 -2
- data/lib/paperclip/io_adapters/stringio_adapter.rb +9 -6
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
- data/lib/paperclip/io_adapters/uri_adapter.rb +41 -19
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
- data/lib/paperclip/media_type_spoof_detector.rb +2 -2
- data/lib/paperclip/processor.rb +5 -4
- data/lib/paperclip/rails_environment.rb +25 -0
- data/lib/paperclip/schema.rb +3 -9
- data/lib/paperclip/storage/filesystem.rb +13 -2
- data/lib/paperclip/storage/fog.rb +30 -18
- data/lib/paperclip/storage/s3.rb +92 -65
- data/lib/paperclip/thumbnail.rb +16 -7
- data/lib/paperclip/url_generator.rb +16 -13
- data/lib/paperclip/validators/attachment_size_validator.rb +1 -7
- data/lib/paperclip/validators.rb +1 -1
- data/lib/paperclip/version.rb +3 -1
- data/lib/paperclip.rb +25 -12
- data/lib/tasks/paperclip.rake +33 -3
- data/paperclip.gemspec +18 -15
- data/spec/paperclip/attachment_definitions_spec.rb +1 -1
- data/spec/paperclip/attachment_processing_spec.rb +2 -4
- data/spec/paperclip/attachment_registry_spec.rb +84 -13
- data/spec/paperclip/attachment_spec.rb +130 -39
- data/spec/paperclip/content_type_detector_spec.rb +8 -1
- data/spec/paperclip/file_command_content_type_detector_spec.rb +0 -1
- data/spec/paperclip/geometry_spec.rb +1 -1
- data/spec/paperclip/glue_spec.rb +44 -0
- data/spec/paperclip/has_attached_file_spec.rb +24 -8
- data/spec/paperclip/integration_spec.rb +4 -3
- data/spec/paperclip/interpolations_spec.rb +16 -13
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +47 -23
- data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +6 -3
- data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +7 -1
- data/spec/paperclip/io_adapters/file_adapter_spec.rb +6 -3
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +26 -6
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
- data/spec/paperclip/io_adapters/registry_spec.rb +2 -2
- data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +5 -1
- data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +5 -5
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +77 -7
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +10 -0
- data/spec/paperclip/media_type_spoof_detector_spec.rb +34 -11
- data/spec/paperclip/paperclip_spec.rb +4 -29
- data/spec/paperclip/plural_cache_spec.rb +17 -16
- data/spec/paperclip/rails_environment_spec.rb +33 -0
- data/spec/paperclip/storage/fog_spec.rb +58 -3
- data/spec/paperclip/storage/s3_live_spec.rb +20 -14
- data/spec/paperclip/storage/s3_spec.rb +398 -213
- data/spec/paperclip/tempfile_factory_spec.rb +4 -0
- data/spec/paperclip/tempfile_spec.rb +35 -0
- data/spec/paperclip/thumbnail_spec.rb +51 -32
- data/spec/paperclip/url_generator_spec.rb +55 -44
- data/spec/paperclip/validators/attachment_size_validator_spec.rb +26 -20
- data/spec/paperclip/validators_spec.rb +5 -5
- data/spec/spec_helper.rb +8 -1
- data/spec/support/assertions.rb +12 -1
- data/spec/support/conditional_filter_helper.rb +5 -0
- data/spec/support/fake_model.rb +4 -0
- data/spec/support/fixtures/empty.xlsx +0 -0
- data/spec/support/matchers/have_column.rb +11 -2
- data/spec/support/mock_attachment.rb +2 -0
- data/spec/support/mock_url_generator_builder.rb +2 -2
- data/spec/support/model_reconstruction.rb +9 -1
- data/spec/support/reporting.rb +11 -0
- metadata +109 -162
- data/RUNNING_TESTS.md +0 -4
- data/cucumber/paperclip_steps.rb +0 -6
- data/gemfiles/3.2.gemfile +0 -19
- data/gemfiles/4.0.gemfile +0 -19
- data/gemfiles/4.1.gemfile +0 -19
- data/lib/paperclip/locales/de.yml +0 -18
- data/lib/paperclip/locales/es.yml +0 -18
- data/lib/paperclip/locales/ja.yml +0 -18
- data/lib/paperclip/locales/pt-BR.yml +0 -18
- data/lib/paperclip/locales/zh-CN.yml +0 -18
- data/lib/paperclip/locales/zh-HK.yml +0 -18
- data/lib/paperclip/locales/zh-TW.yml +0 -18
- data/spec/support/mock_model.rb +0 -2
- data/spec/support/rails_helpers.rb +0 -7
data/paperclip.gemspec
CHANGED
|
@@ -12,40 +12,43 @@ Gem::Specification.new do |s|
|
|
|
12
12
|
s.description = "Easy upload management for ActiveRecord"
|
|
13
13
|
s.license = "MIT"
|
|
14
14
|
|
|
15
|
-
s.rubyforge_project = "paperclip"
|
|
16
|
-
|
|
17
15
|
s.files = `git ls-files`.split("\n")
|
|
18
16
|
s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
|
|
19
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
20
18
|
s.require_paths = ["lib"]
|
|
21
19
|
|
|
20
|
+
if File.exist?('UPGRADING')
|
|
21
|
+
s.post_install_message = File.read("UPGRADING")
|
|
22
|
+
end
|
|
23
|
+
|
|
22
24
|
s.requirements << "ImageMagick"
|
|
23
|
-
s.required_ruby_version = ">= 1.
|
|
25
|
+
s.required_ruby_version = ">= 2.1.0"
|
|
24
26
|
|
|
25
|
-
s.add_dependency('activemodel', '>=
|
|
26
|
-
s.add_dependency('activesupport', '>=
|
|
27
|
-
s.add_dependency('cocaine', '~> 0.5.
|
|
27
|
+
s.add_dependency('activemodel', '>= 4.2.0')
|
|
28
|
+
s.add_dependency('activesupport', '>= 4.2.0')
|
|
29
|
+
s.add_dependency('cocaine', '~> 0.5.5')
|
|
28
30
|
s.add_dependency('mime-types')
|
|
31
|
+
s.add_dependency('mimemagic', '~> 0.3.0')
|
|
29
32
|
|
|
30
|
-
s.add_development_dependency('activerecord', '>=
|
|
33
|
+
s.add_development_dependency('activerecord', '>= 4.2.0')
|
|
31
34
|
s.add_development_dependency('shoulda')
|
|
32
|
-
s.add_development_dependency('rspec')
|
|
35
|
+
s.add_development_dependency('rspec', '~> 3.0')
|
|
33
36
|
s.add_development_dependency('appraisal')
|
|
34
37
|
s.add_development_dependency('mocha')
|
|
35
|
-
s.add_development_dependency('aws-sdk', '>=
|
|
38
|
+
s.add_development_dependency('aws-sdk', '>= 2.3.0', '< 3.0')
|
|
36
39
|
s.add_development_dependency('bourne')
|
|
37
|
-
s.add_development_dependency('cucumber'
|
|
38
|
-
s.add_development_dependency('
|
|
40
|
+
s.add_development_dependency('cucumber-rails')
|
|
41
|
+
s.add_development_dependency('cucumber-expressions', '4.0.3') # TODO: investigate failures on 4.0.4
|
|
42
|
+
s.add_development_dependency('aruba', '~> 0.9.0')
|
|
39
43
|
s.add_development_dependency('nokogiri')
|
|
40
|
-
|
|
41
|
-
s.add_development_dependency('capybara', '= 2.0.3')
|
|
44
|
+
s.add_development_dependency('capybara')
|
|
42
45
|
s.add_development_dependency('bundler')
|
|
43
|
-
s.add_development_dependency('fog'
|
|
46
|
+
s.add_development_dependency('fog-aws')
|
|
47
|
+
s.add_development_dependency('fog-local')
|
|
44
48
|
s.add_development_dependency('launchy')
|
|
45
49
|
s.add_development_dependency('rake')
|
|
46
50
|
s.add_development_dependency('fakeweb')
|
|
47
51
|
s.add_development_dependency('railties')
|
|
48
|
-
s.add_development_dependency('actionmailer', '>= 3.0.0')
|
|
49
52
|
s.add_development_dependency('generator_spec')
|
|
50
53
|
s.add_development_dependency('timecop')
|
|
51
54
|
end
|
|
@@ -8,6 +8,6 @@ describe "Attachment Definitions" do
|
|
|
8
8
|
Dummy.do_not_validate_attachment_file_type :avatar
|
|
9
9
|
expected = {avatar: {path: "abc"}, other_attachment: {url: "123"}}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
expect(Dummy.attachment_definitions).to eq expected
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
require 'spec_helper'
|
|
3
3
|
|
|
4
4
|
describe 'Attachment Processing' do
|
|
5
|
-
|
|
6
|
-
before do
|
|
7
|
-
rebuild_class
|
|
8
|
-
end
|
|
5
|
+
before { rebuild_class }
|
|
9
6
|
|
|
7
|
+
context 'using validates_attachment_content_type' do
|
|
10
8
|
it 'processes attachments given a valid assignment' do
|
|
11
9
|
file = File.new(fixture_file("5k.png"))
|
|
12
10
|
Dummy.validates_attachment_content_type :avatar, content_type: "image/png"
|
|
@@ -31,8 +31,8 @@ describe 'Attachment Registry' do
|
|
|
31
31
|
it 'calls the block with the class, attachment name, and options' do
|
|
32
32
|
foo = Class.new
|
|
33
33
|
expected_accumulations = [
|
|
34
|
-
[foo, :avatar, { yo:
|
|
35
|
-
[foo, :greeter, { ciao:
|
|
34
|
+
[foo, :avatar, { yo: "greeting" }],
|
|
35
|
+
[foo, :greeter, { ciao: "greeting" }]
|
|
36
36
|
]
|
|
37
37
|
expected_accumulations.each do |args|
|
|
38
38
|
Paperclip::AttachmentRegistry.register(*args)
|
|
@@ -50,25 +50,92 @@ describe 'Attachment Registry' do
|
|
|
50
50
|
context '.definitions_for' do
|
|
51
51
|
it 'produces the attachment name and options' do
|
|
52
52
|
expected_definitions = {
|
|
53
|
-
avatar: { yo:
|
|
54
|
-
greeter: { ciao:
|
|
53
|
+
avatar: { yo: "greeting" },
|
|
54
|
+
greeter: { ciao: "greeting" }
|
|
55
55
|
}
|
|
56
56
|
foo = Class.new
|
|
57
|
-
Paperclip::AttachmentRegistry.register(
|
|
58
|
-
|
|
57
|
+
Paperclip::AttachmentRegistry.register(
|
|
58
|
+
foo,
|
|
59
|
+
:avatar,
|
|
60
|
+
yo: "greeting"
|
|
61
|
+
)
|
|
62
|
+
Paperclip::AttachmentRegistry.register(
|
|
63
|
+
foo,
|
|
64
|
+
:greeter,
|
|
65
|
+
ciao: "greeting"
|
|
66
|
+
)
|
|
59
67
|
|
|
60
68
|
definitions = Paperclip::AttachmentRegistry.definitions_for(foo)
|
|
61
69
|
|
|
62
70
|
assert_equal expected_definitions, definitions
|
|
63
71
|
end
|
|
64
72
|
|
|
65
|
-
it
|
|
66
|
-
expected_definitions = { avatar: { yo:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
Paperclip::AttachmentRegistry.register(
|
|
73
|
+
it 'produces defintions for subclasses' do
|
|
74
|
+
expected_definitions = { avatar: { yo: "greeting" } }
|
|
75
|
+
foo = Class.new
|
|
76
|
+
bar = Class.new(foo)
|
|
77
|
+
Paperclip::AttachmentRegistry.register(
|
|
78
|
+
foo,
|
|
79
|
+
:avatar,
|
|
80
|
+
expected_definitions[:avatar]
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
definitions = Paperclip::AttachmentRegistry.definitions_for(bar)
|
|
84
|
+
|
|
85
|
+
assert_equal expected_definitions, definitions
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'produces defintions for subclasses but deep merging them' do
|
|
89
|
+
foo_definitions = { avatar: { yo: "greeting" } }
|
|
90
|
+
bar_definitions = { avatar: { ciao: "greeting" } }
|
|
91
|
+
expected_definitions = {
|
|
92
|
+
avatar: {
|
|
93
|
+
yo: "greeting",
|
|
94
|
+
ciao: "greeting"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
foo = Class.new
|
|
98
|
+
bar = Class.new(foo)
|
|
99
|
+
Paperclip::AttachmentRegistry.register(
|
|
100
|
+
foo,
|
|
101
|
+
:avatar,
|
|
102
|
+
foo_definitions[:avatar]
|
|
103
|
+
)
|
|
104
|
+
Paperclip::AttachmentRegistry.register(
|
|
105
|
+
bar,
|
|
106
|
+
:avatar,
|
|
107
|
+
bar_definitions[:avatar]
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
definitions = Paperclip::AttachmentRegistry.definitions_for(bar)
|
|
70
111
|
|
|
71
|
-
|
|
112
|
+
assert_equal expected_definitions, definitions
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it 'allows subclasses to override attachment defitions' do
|
|
116
|
+
foo_definitions = { avatar: { yo: "greeting" } }
|
|
117
|
+
bar_definitions = { avatar: { yo: "hello" } }
|
|
118
|
+
|
|
119
|
+
expected_definitions = {
|
|
120
|
+
avatar: {
|
|
121
|
+
yo: "hello"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
foo = Class.new
|
|
126
|
+
bar = Class.new(foo)
|
|
127
|
+
Paperclip::AttachmentRegistry.register(
|
|
128
|
+
foo,
|
|
129
|
+
:avatar,
|
|
130
|
+
foo_definitions[:avatar]
|
|
131
|
+
)
|
|
132
|
+
Paperclip::AttachmentRegistry.register(
|
|
133
|
+
bar,
|
|
134
|
+
:avatar,
|
|
135
|
+
bar_definitions[:avatar]
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
definitions = Paperclip::AttachmentRegistry.definitions_for(bar)
|
|
72
139
|
|
|
73
140
|
assert_equal expected_definitions, definitions
|
|
74
141
|
end
|
|
@@ -77,7 +144,11 @@ describe 'Attachment Registry' do
|
|
|
77
144
|
context '.clear' do
|
|
78
145
|
it 'removes all of the existing attachment definitions' do
|
|
79
146
|
foo = Class.new
|
|
80
|
-
Paperclip::AttachmentRegistry.register(
|
|
147
|
+
Paperclip::AttachmentRegistry.register(
|
|
148
|
+
foo,
|
|
149
|
+
:greeter,
|
|
150
|
+
ciao: "greeting"
|
|
151
|
+
)
|
|
81
152
|
|
|
82
153
|
Paperclip::AttachmentRegistry.clear
|
|
83
154
|
|
|
@@ -13,7 +13,7 @@ describe Paperclip::Attachment do
|
|
|
13
13
|
it "is present when the file is set" do
|
|
14
14
|
rebuild_class
|
|
15
15
|
dummy = Dummy.new
|
|
16
|
-
dummy.avatar = File.new(fixture_file("50x50.png"), "rb")
|
|
16
|
+
dummy.avatar = File.new(fixture_file("50x50.png"), "rb")
|
|
17
17
|
expect(dummy.avatar).to_not be_blank
|
|
18
18
|
expect(dummy.avatar).to be_present
|
|
19
19
|
end
|
|
@@ -34,9 +34,9 @@ describe Paperclip::Attachment do
|
|
|
34
34
|
it "does not delete styles that don't get reprocessed" do
|
|
35
35
|
file = File.new(fixture_file("50x50.png"), 'rb')
|
|
36
36
|
rebuild_class styles: {
|
|
37
|
-
small:
|
|
38
|
-
large:
|
|
39
|
-
original:
|
|
37
|
+
small: "100x>",
|
|
38
|
+
large: "500x>",
|
|
39
|
+
original: "42x42#"
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
dummy = Dummy.new
|
|
@@ -75,7 +75,11 @@ describe Paperclip::Attachment do
|
|
|
75
75
|
|
|
76
76
|
it "handles a boolean second argument to #url" do
|
|
77
77
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
78
|
-
attachment = Paperclip::Attachment.new(
|
|
78
|
+
attachment = Paperclip::Attachment.new(
|
|
79
|
+
:name,
|
|
80
|
+
FakeModel.new,
|
|
81
|
+
url_generator: mock_url_generator_builder
|
|
82
|
+
)
|
|
79
83
|
|
|
80
84
|
attachment.url(:style_name, true)
|
|
81
85
|
expect(mock_url_generator_builder.has_generated_url_with_options?(timestamp: true, escape: true)).to eq true
|
|
@@ -86,7 +90,11 @@ describe Paperclip::Attachment do
|
|
|
86
90
|
|
|
87
91
|
it "passes the style and options through to the URL generator on #url" do
|
|
88
92
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
89
|
-
attachment = Paperclip::Attachment.new(
|
|
93
|
+
attachment = Paperclip::Attachment.new(
|
|
94
|
+
:name,
|
|
95
|
+
FakeModel.new,
|
|
96
|
+
url_generator: mock_url_generator_builder
|
|
97
|
+
)
|
|
90
98
|
|
|
91
99
|
attachment.url(:style_name, options: :values)
|
|
92
100
|
expect(mock_url_generator_builder.has_generated_url_with_options?(options: :values)).to eq true
|
|
@@ -95,7 +103,7 @@ describe Paperclip::Attachment do
|
|
|
95
103
|
it "passes default options through when #url is given one argument" do
|
|
96
104
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
97
105
|
attachment = Paperclip::Attachment.new(:name,
|
|
98
|
-
|
|
106
|
+
FakeModel.new,
|
|
99
107
|
url_generator: mock_url_generator_builder,
|
|
100
108
|
use_timestamp: true)
|
|
101
109
|
|
|
@@ -106,7 +114,7 @@ describe Paperclip::Attachment do
|
|
|
106
114
|
it "passes default style and options through when #url is given no arguments" do
|
|
107
115
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
108
116
|
attachment = Paperclip::Attachment.new(:name,
|
|
109
|
-
|
|
117
|
+
FakeModel.new,
|
|
110
118
|
default_style: 'default style',
|
|
111
119
|
url_generator: mock_url_generator_builder,
|
|
112
120
|
use_timestamp: true)
|
|
@@ -119,7 +127,7 @@ describe Paperclip::Attachment do
|
|
|
119
127
|
it "passes the option timestamp: true if :use_timestamp is true and :timestamp is not passed" do
|
|
120
128
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
121
129
|
attachment = Paperclip::Attachment.new(:name,
|
|
122
|
-
|
|
130
|
+
FakeModel.new,
|
|
123
131
|
url_generator: mock_url_generator_builder,
|
|
124
132
|
use_timestamp: true)
|
|
125
133
|
|
|
@@ -130,7 +138,7 @@ describe Paperclip::Attachment do
|
|
|
130
138
|
it "passes the option timestamp: false if :use_timestamp is false and :timestamp is not passed" do
|
|
131
139
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
132
140
|
attachment = Paperclip::Attachment.new(:name,
|
|
133
|
-
|
|
141
|
+
FakeModel.new,
|
|
134
142
|
url_generator: mock_url_generator_builder,
|
|
135
143
|
use_timestamp: false)
|
|
136
144
|
|
|
@@ -141,7 +149,7 @@ describe Paperclip::Attachment do
|
|
|
141
149
|
it "does not change the :timestamp if :timestamp is passed" do
|
|
142
150
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
143
151
|
attachment = Paperclip::Attachment.new(:name,
|
|
144
|
-
|
|
152
|
+
FakeModel.new,
|
|
145
153
|
url_generator: mock_url_generator_builder,
|
|
146
154
|
use_timestamp: false)
|
|
147
155
|
|
|
@@ -152,7 +160,7 @@ describe Paperclip::Attachment do
|
|
|
152
160
|
it "renders JSON as default style" do
|
|
153
161
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
154
162
|
attachment = Paperclip::Attachment.new(:name,
|
|
155
|
-
|
|
163
|
+
FakeModel.new,
|
|
156
164
|
default_style: 'default style',
|
|
157
165
|
url_generator: mock_url_generator_builder)
|
|
158
166
|
|
|
@@ -163,7 +171,7 @@ describe Paperclip::Attachment do
|
|
|
163
171
|
it "passes the option escape: true if :escape_url is true and :escape is not passed" do
|
|
164
172
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
165
173
|
attachment = Paperclip::Attachment.new(:name,
|
|
166
|
-
|
|
174
|
+
FakeModel.new,
|
|
167
175
|
url_generator: mock_url_generator_builder,
|
|
168
176
|
escape_url: true)
|
|
169
177
|
|
|
@@ -174,7 +182,7 @@ describe Paperclip::Attachment do
|
|
|
174
182
|
it "passes the option escape: false if :escape_url is false and :escape is not passed" do
|
|
175
183
|
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
|
176
184
|
attachment = Paperclip::Attachment.new(:name,
|
|
177
|
-
|
|
185
|
+
FakeModel.new,
|
|
178
186
|
url_generator: mock_url_generator_builder,
|
|
179
187
|
escape_url: false)
|
|
180
188
|
|
|
@@ -212,10 +220,8 @@ describe Paperclip::Attachment do
|
|
|
212
220
|
dummy = Dummy.new
|
|
213
221
|
dummy.id = 1234
|
|
214
222
|
dummy.avatar_file_name = "fake.jpg"
|
|
223
|
+
dummy.stubs(:new_record?).returns(false)
|
|
215
224
|
expected_string = '{"avatar":"/system/dummies/avatars/000/001/234/original/fake.jpg"}'
|
|
216
|
-
if ActiveRecord::Base.include_root_in_json # This is true by default in Rails 3, and false in 4
|
|
217
|
-
expected_string = %({"dummy":#{expected_string}})
|
|
218
|
-
end
|
|
219
225
|
# active_model pre-3.2 checks only by calling any? on it, thus it doesn't work if it is empty
|
|
220
226
|
assert_equal expected_string, dummy.to_json(only: [:dummy_key_for_old_active_model], methods: [:avatar])
|
|
221
227
|
end
|
|
@@ -245,12 +251,17 @@ describe Paperclip::Attachment do
|
|
|
245
251
|
|
|
246
252
|
context "without an Attachment" do
|
|
247
253
|
before do
|
|
254
|
+
rebuild_model default_url: "default.url"
|
|
248
255
|
@dummy = Dummy.new
|
|
249
256
|
end
|
|
250
257
|
|
|
251
258
|
it "returns false when asked exists?" do
|
|
252
259
|
assert !@dummy.avatar.exists?
|
|
253
260
|
end
|
|
261
|
+
|
|
262
|
+
it "#url returns the default_url" do
|
|
263
|
+
expect(@dummy.avatar.url).to eq "default.url"
|
|
264
|
+
end
|
|
254
265
|
end
|
|
255
266
|
|
|
256
267
|
context "on an Attachment" do
|
|
@@ -489,6 +500,7 @@ describe Paperclip::Attachment do
|
|
|
489
500
|
@attachment.expects(:post_process).with(:thumb)
|
|
490
501
|
@attachment.expects(:post_process).with(:large).never
|
|
491
502
|
@attachment.assign(@file)
|
|
503
|
+
@attachment.save
|
|
492
504
|
end
|
|
493
505
|
end
|
|
494
506
|
|
|
@@ -635,15 +647,40 @@ describe Paperclip::Attachment do
|
|
|
635
647
|
before do
|
|
636
648
|
rebuild_model processor: [:thumbnail], styles: { small: '' }, whiny_thumbnails: true
|
|
637
649
|
@dummy = Dummy.new
|
|
638
|
-
Paperclip::Thumbnail.expects(:make).raises(Paperclip::Error, "cannot be processed.")
|
|
639
650
|
@file = StringIO.new("...")
|
|
640
651
|
@file.stubs(:to_tempfile).returns(@file)
|
|
641
|
-
@dummy.avatar = @file
|
|
642
652
|
end
|
|
643
653
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
654
|
+
context "when error is meaningful for the end user" do
|
|
655
|
+
before do
|
|
656
|
+
Paperclip::Thumbnail.expects(:make).raises(
|
|
657
|
+
Paperclip::Errors::NotIdentifiedByImageMagickError,
|
|
658
|
+
"cannot be processed."
|
|
659
|
+
)
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
it "correctly forwards processing error message to the instance" do
|
|
663
|
+
@dummy.avatar = @file
|
|
664
|
+
@dummy.valid?
|
|
665
|
+
assert_contains(
|
|
666
|
+
@dummy.errors.full_messages,
|
|
667
|
+
"Avatar cannot be processed."
|
|
668
|
+
)
|
|
669
|
+
end
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
context "when error is intended for the developer" do
|
|
673
|
+
before do
|
|
674
|
+
Paperclip::Thumbnail.expects(:make).raises(
|
|
675
|
+
Paperclip::Errors::CommandNotFoundError
|
|
676
|
+
)
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
it "propagates the error" do
|
|
680
|
+
assert_raises(Paperclip::Errors::CommandNotFoundError) do
|
|
681
|
+
@dummy.avatar = @file
|
|
682
|
+
end
|
|
683
|
+
end
|
|
647
684
|
end
|
|
648
685
|
end
|
|
649
686
|
|
|
@@ -661,9 +698,6 @@ describe Paperclip::Attachment do
|
|
|
661
698
|
|
|
662
699
|
context "when assigned" do
|
|
663
700
|
it "calls #make on all specified processors" do
|
|
664
|
-
Paperclip::Thumbnail.stubs(:make).with(any_parameters).returns(@file)
|
|
665
|
-
Paperclip::Test.stubs(:make).with(any_parameters).returns(@file)
|
|
666
|
-
|
|
667
701
|
@dummy.avatar = @file
|
|
668
702
|
|
|
669
703
|
expect(Paperclip::Thumbnail).to have_received(:make)
|
|
@@ -678,7 +712,6 @@ describe Paperclip::Attachment do
|
|
|
678
712
|
convert_options: "",
|
|
679
713
|
source_file_options: ""
|
|
680
714
|
})
|
|
681
|
-
Paperclip::Thumbnail.stubs(:make).returns(@file)
|
|
682
715
|
|
|
683
716
|
@dummy.avatar = @file
|
|
684
717
|
|
|
@@ -686,12 +719,36 @@ describe Paperclip::Attachment do
|
|
|
686
719
|
end
|
|
687
720
|
|
|
688
721
|
it "calls #make with attachment passed as third argument" do
|
|
689
|
-
Paperclip::Test.expects(:make).returns(@file)
|
|
690
|
-
|
|
691
722
|
@dummy.avatar = @file
|
|
692
723
|
|
|
693
724
|
expect(Paperclip::Test).to have_received(:make).with(anything, anything, @dummy.avatar)
|
|
694
725
|
end
|
|
726
|
+
|
|
727
|
+
it "calls #make and unlinks intermediary files afterward" do
|
|
728
|
+
@dummy.avatar.expects(:unlink_files).with([@file, @file])
|
|
729
|
+
|
|
730
|
+
@dummy.avatar = @file
|
|
731
|
+
end
|
|
732
|
+
end
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
context "An attachment with a processor that returns original file" do
|
|
736
|
+
before do
|
|
737
|
+
class Paperclip::Test < Paperclip::Processor
|
|
738
|
+
def make; @file; end
|
|
739
|
+
end
|
|
740
|
+
rebuild_model processors: [:test], styles: { once: "100x100" }
|
|
741
|
+
@file = StringIO.new("...")
|
|
742
|
+
@file.stubs(:close)
|
|
743
|
+
@dummy = Dummy.new
|
|
744
|
+
end
|
|
745
|
+
|
|
746
|
+
context "when assigned" do
|
|
747
|
+
it "#calls #make and doesn't unlink the original file" do
|
|
748
|
+
@dummy.avatar.expects(:unlink_files).with([])
|
|
749
|
+
|
|
750
|
+
@dummy.avatar = @file
|
|
751
|
+
end
|
|
695
752
|
end
|
|
696
753
|
end
|
|
697
754
|
|
|
@@ -1065,7 +1122,7 @@ describe Paperclip::Attachment do
|
|
|
1065
1122
|
context "with a file assigned but not saved yet" do
|
|
1066
1123
|
it "clears out any attached files" do
|
|
1067
1124
|
@attachment.assign(@file)
|
|
1068
|
-
assert
|
|
1125
|
+
assert @attachment.queued_for_write.present?
|
|
1069
1126
|
@attachment.clear
|
|
1070
1127
|
assert @attachment.queued_for_write.blank?
|
|
1071
1128
|
end
|
|
@@ -1315,6 +1372,12 @@ describe Paperclip::Attachment do
|
|
|
1315
1372
|
end
|
|
1316
1373
|
|
|
1317
1374
|
it "does not calculate fingerprint" do
|
|
1375
|
+
Digest::MD5.stubs(:file)
|
|
1376
|
+
@dummy.avatar = @file
|
|
1377
|
+
expect(Digest::MD5).to have_received(:file).never
|
|
1378
|
+
end
|
|
1379
|
+
|
|
1380
|
+
it "does not assign fingerprint" do
|
|
1318
1381
|
@dummy.avatar = @file
|
|
1319
1382
|
assert_nil @dummy.avatar.fingerprint
|
|
1320
1383
|
end
|
|
@@ -1371,16 +1434,46 @@ describe Paperclip::Attachment do
|
|
|
1371
1434
|
assert_nothing_raised { @dummy.avatar = @file }
|
|
1372
1435
|
end
|
|
1373
1436
|
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1437
|
+
context "with explicitly set digest" do
|
|
1438
|
+
before do
|
|
1439
|
+
rebuild_class adapter_options: { hash_digest: Digest::SHA256 }
|
|
1440
|
+
@dummy = Dummy.new
|
|
1441
|
+
end
|
|
1442
|
+
|
|
1443
|
+
it "returns the right value when sent #avatar_fingerprint" do
|
|
1444
|
+
@dummy.avatar = @file
|
|
1445
|
+
assert_equal "734016d801a497f5579cdd4ef2ae1d020088c1db754dc434482d76dd5486520a",
|
|
1446
|
+
@dummy.avatar_fingerprint
|
|
1447
|
+
end
|
|
1448
|
+
|
|
1449
|
+
it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
|
|
1450
|
+
@dummy.avatar = @file
|
|
1451
|
+
@dummy.save
|
|
1452
|
+
@dummy = Dummy.find(@dummy.id)
|
|
1453
|
+
assert_equal "734016d801a497f5579cdd4ef2ae1d020088c1db754dc434482d76dd5486520a",
|
|
1454
|
+
@dummy.avatar_fingerprint
|
|
1455
|
+
end
|
|
1377
1456
|
end
|
|
1378
1457
|
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1458
|
+
context "with the default digest" do
|
|
1459
|
+
before do
|
|
1460
|
+
rebuild_class # MD5 is the default
|
|
1461
|
+
@dummy = Dummy.new
|
|
1462
|
+
end
|
|
1463
|
+
|
|
1464
|
+
it "returns the right value when sent #avatar_fingerprint" do
|
|
1465
|
+
@dummy.avatar = @file
|
|
1466
|
+
assert_equal "aec488126c3b33c08a10c3fa303acf27",
|
|
1467
|
+
@dummy.avatar_fingerprint
|
|
1468
|
+
end
|
|
1469
|
+
|
|
1470
|
+
it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
|
|
1471
|
+
@dummy.avatar = @file
|
|
1472
|
+
@dummy.save
|
|
1473
|
+
@dummy = Dummy.find(@dummy.id)
|
|
1474
|
+
assert_equal "aec488126c3b33c08a10c3fa303acf27",
|
|
1475
|
+
@dummy.avatar_fingerprint
|
|
1476
|
+
end
|
|
1384
1477
|
end
|
|
1385
1478
|
end
|
|
1386
1479
|
end
|
|
@@ -1452,6 +1545,4 @@ describe Paperclip::Attachment do
|
|
|
1452
1545
|
assert_file_exists(@path)
|
|
1453
1546
|
end
|
|
1454
1547
|
end
|
|
1455
|
-
|
|
1456
1548
|
end
|
|
1457
|
-
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Paperclip::ContentTypeDetector do
|
|
4
|
+
it 'returns a meaningful content type for open xml spreadsheets' do
|
|
5
|
+
file = File.new(fixture_file("empty.xlsx"))
|
|
6
|
+
assert_equal "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
7
|
+
Paperclip::ContentTypeDetector.new(file.path).detect
|
|
8
|
+
end
|
|
9
|
+
|
|
4
10
|
it 'gives a sensible default when the name is empty' do
|
|
5
11
|
assert_equal "application/octet-stream", Paperclip::ContentTypeDetector.new("").detect
|
|
6
12
|
end
|
|
@@ -13,7 +19,8 @@ describe Paperclip::ContentTypeDetector do
|
|
|
13
19
|
|
|
14
20
|
it 'returns content type of file if it is an acceptable type' do
|
|
15
21
|
MIME::Types.stubs(:type_for).returns([MIME::Type.new('application/mp4'), MIME::Type.new('video/mp4'), MIME::Type.new('audio/mp4')])
|
|
16
|
-
Paperclip.
|
|
22
|
+
Paperclip::ContentTypeDetector.any_instance
|
|
23
|
+
.stubs(:type_from_file_contents).returns("video/mp4")
|
|
17
24
|
@filename = "my_file.mp4"
|
|
18
25
|
assert_equal "video/mp4", Paperclip::ContentTypeDetector.new(@filename).detect
|
|
19
26
|
end
|
|
@@ -82,7 +82,7 @@ describe Paperclip::Geometry do
|
|
|
82
82
|
assert_equal 456, @upper.height
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
-
['>', '<', '#', '@', '%', '^', '!', nil].each do |mod|
|
|
85
|
+
['>', '<', '#', '@', '@>', '>@', '%', '^', '!', nil].each do |mod|
|
|
86
86
|
it "ensures the modifier #{description} is preserved" do
|
|
87
87
|
assert @geo = Paperclip::Geometry.parse("123x456#{mod}")
|
|
88
88
|
assert_equal mod, @geo.modifier
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Paperclip::Glue do
|
|
4
|
+
describe "when ActiveRecord does not exist" do
|
|
5
|
+
before do
|
|
6
|
+
ActiveRecordSaved = ActiveRecord
|
|
7
|
+
Object.send :remove_const, "ActiveRecord"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
after do
|
|
11
|
+
ActiveRecord = ActiveRecordSaved
|
|
12
|
+
Object.send :remove_const, "ActiveRecordSaved"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "does not fail" do
|
|
16
|
+
NonActiveRecordModel = Class.new
|
|
17
|
+
NonActiveRecordModel.send :include, Paperclip::Glue
|
|
18
|
+
Object.send :remove_const, "NonActiveRecordModel"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "when ActiveRecord does exist" do
|
|
23
|
+
before do
|
|
24
|
+
if Object.const_defined?("ActiveRecord")
|
|
25
|
+
@defined_active_record = false
|
|
26
|
+
else
|
|
27
|
+
ActiveRecord = :defined
|
|
28
|
+
@defined_active_record = true
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
after do
|
|
33
|
+
if @defined_active_record
|
|
34
|
+
Object.send :remove_const, "ActiveRecord"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "does not fail" do
|
|
39
|
+
NonActiveRecordModel = Class.new
|
|
40
|
+
NonActiveRecordModel.send :include, Paperclip::Glue
|
|
41
|
+
Object.send :remove_const, "NonActiveRecordModel"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|