paperclip 4.2.4 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +4 -8
- data/LICENSE +1 -1
- data/NEWS +105 -2
- 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 +5 -7
- 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 +17 -14
- 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 +28 -5
- data/spec/paperclip/paperclip_spec.rb +3 -28
- 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 +105 -164
- 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('activemodel', '>= 4.2.0')
|
28
|
+
s.add_dependency('activesupport', '>= 4.2.0')
|
27
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.2.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
|