paperclip-fix 4.3.7

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 (197) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.hound.yml +1066 -0
  4. data/.rubocop.yml +1 -0
  5. data/.travis.yml +22 -0
  6. data/Appraisals +11 -0
  7. data/CONTRIBUTING.md +75 -0
  8. data/Gemfile +21 -0
  9. data/LICENSE +24 -0
  10. data/NEWS +420 -0
  11. data/README.md +979 -0
  12. data/RELEASING.md +17 -0
  13. data/Rakefile +44 -0
  14. data/UPGRADING +14 -0
  15. data/cucumber/paperclip_steps.rb +6 -0
  16. data/features/basic_integration.feature +80 -0
  17. data/features/migration.feature +94 -0
  18. data/features/rake_tasks.feature +62 -0
  19. data/features/step_definitions/attachment_steps.rb +110 -0
  20. data/features/step_definitions/html_steps.rb +15 -0
  21. data/features/step_definitions/rails_steps.rb +236 -0
  22. data/features/step_definitions/s3_steps.rb +14 -0
  23. data/features/step_definitions/web_steps.rb +107 -0
  24. data/features/support/env.rb +11 -0
  25. data/features/support/fakeweb.rb +13 -0
  26. data/features/support/file_helpers.rb +34 -0
  27. data/features/support/fixtures/boot_config.txt +15 -0
  28. data/features/support/fixtures/gemfile.txt +5 -0
  29. data/features/support/fixtures/preinitializer.txt +20 -0
  30. data/features/support/paths.rb +28 -0
  31. data/features/support/rails.rb +63 -0
  32. data/features/support/selectors.rb +19 -0
  33. data/gemfiles/3.2.gemfile +19 -0
  34. data/gemfiles/4.1.gemfile +19 -0
  35. data/gemfiles/4.2.gemfile +19 -0
  36. data/lib/generators/paperclip/USAGE +8 -0
  37. data/lib/generators/paperclip/paperclip_generator.rb +30 -0
  38. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +15 -0
  39. data/lib/paperclip/attachment.rb +608 -0
  40. data/lib/paperclip/attachment_registry.rb +59 -0
  41. data/lib/paperclip/callbacks.rb +40 -0
  42. data/lib/paperclip/content_type_detector.rb +79 -0
  43. data/lib/paperclip/deprecations.rb +42 -0
  44. data/lib/paperclip/errors.rb +32 -0
  45. data/lib/paperclip/file_command_content_type_detector.rb +30 -0
  46. data/lib/paperclip/filename_cleaner.rb +16 -0
  47. data/lib/paperclip/geometry.rb +158 -0
  48. data/lib/paperclip/geometry_detector_factory.rb +48 -0
  49. data/lib/paperclip/geometry_parser_factory.rb +31 -0
  50. data/lib/paperclip/glue.rb +17 -0
  51. data/lib/paperclip/has_attached_file.rb +109 -0
  52. data/lib/paperclip/helpers.rb +56 -0
  53. data/lib/paperclip/interpolations/plural_cache.rb +18 -0
  54. data/lib/paperclip/interpolations.rb +197 -0
  55. data/lib/paperclip/io_adapters/abstract_adapter.rb +47 -0
  56. data/lib/paperclip/io_adapters/attachment_adapter.rb +36 -0
  57. data/lib/paperclip/io_adapters/data_uri_adapter.rb +22 -0
  58. data/lib/paperclip/io_adapters/empty_string_adapter.rb +18 -0
  59. data/lib/paperclip/io_adapters/file_adapter.rb +22 -0
  60. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +15 -0
  61. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -0
  62. data/lib/paperclip/io_adapters/nil_adapter.rb +34 -0
  63. data/lib/paperclip/io_adapters/registry.rb +32 -0
  64. data/lib/paperclip/io_adapters/stringio_adapter.rb +33 -0
  65. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +42 -0
  66. data/lib/paperclip/io_adapters/uri_adapter.rb +63 -0
  67. data/lib/paperclip/locales/de.yml +18 -0
  68. data/lib/paperclip/locales/en.yml +18 -0
  69. data/lib/paperclip/locales/es.yml +18 -0
  70. data/lib/paperclip/locales/ja.yml +18 -0
  71. data/lib/paperclip/locales/pt-BR.yml +18 -0
  72. data/lib/paperclip/locales/zh-CN.yml +18 -0
  73. data/lib/paperclip/locales/zh-HK.yml +18 -0
  74. data/lib/paperclip/locales/zh-TW.yml +18 -0
  75. data/lib/paperclip/logger.rb +21 -0
  76. data/lib/paperclip/matchers/have_attached_file_matcher.rb +54 -0
  77. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +100 -0
  78. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +59 -0
  79. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +96 -0
  80. data/lib/paperclip/matchers.rb +64 -0
  81. data/lib/paperclip/media_type_spoof_detector.rb +89 -0
  82. data/lib/paperclip/missing_attachment_styles.rb +79 -0
  83. data/lib/paperclip/processor.rb +48 -0
  84. data/lib/paperclip/processor_helpers.rb +50 -0
  85. data/lib/paperclip/rails_environment.rb +25 -0
  86. data/lib/paperclip/railtie.rb +31 -0
  87. data/lib/paperclip/schema.rb +83 -0
  88. data/lib/paperclip/storage/filesystem.rb +90 -0
  89. data/lib/paperclip/storage/fog.rb +241 -0
  90. data/lib/paperclip/storage/s3.rb +440 -0
  91. data/lib/paperclip/storage.rb +3 -0
  92. data/lib/paperclip/style.rb +109 -0
  93. data/lib/paperclip/tempfile.rb +43 -0
  94. data/lib/paperclip/tempfile_factory.rb +23 -0
  95. data/lib/paperclip/thumbnail.rb +121 -0
  96. data/lib/paperclip/url_generator.rb +72 -0
  97. data/lib/paperclip/validators/attachment_content_type_validator.rb +88 -0
  98. data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
  99. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
  100. data/lib/paperclip/validators/attachment_presence_validator.rb +30 -0
  101. data/lib/paperclip/validators/attachment_size_validator.rb +115 -0
  102. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +27 -0
  103. data/lib/paperclip/validators.rb +74 -0
  104. data/lib/paperclip/version.rb +3 -0
  105. data/lib/paperclip.rb +213 -0
  106. data/lib/tasks/paperclip.rake +127 -0
  107. data/paperclip.gemspec +51 -0
  108. data/shoulda_macros/paperclip.rb +134 -0
  109. data/spec/database.yml +4 -0
  110. data/spec/paperclip/attachment_definitions_spec.rb +13 -0
  111. data/spec/paperclip/attachment_processing_spec.rb +82 -0
  112. data/spec/paperclip/attachment_registry_spec.rb +130 -0
  113. data/spec/paperclip/attachment_spec.rb +1494 -0
  114. data/spec/paperclip/content_type_detector_spec.rb +48 -0
  115. data/spec/paperclip/deprecations_spec.rb +65 -0
  116. data/spec/paperclip/file_command_content_type_detector_spec.rb +26 -0
  117. data/spec/paperclip/filename_cleaner_spec.rb +14 -0
  118. data/spec/paperclip/geometry_detector_spec.rb +39 -0
  119. data/spec/paperclip/geometry_parser_spec.rb +73 -0
  120. data/spec/paperclip/geometry_spec.rb +255 -0
  121. data/spec/paperclip/glue_spec.rb +44 -0
  122. data/spec/paperclip/has_attached_file_spec.rb +142 -0
  123. data/spec/paperclip/integration_spec.rb +667 -0
  124. data/spec/paperclip/interpolations_spec.rb +262 -0
  125. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +78 -0
  126. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +139 -0
  127. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +83 -0
  128. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
  129. data/spec/paperclip/io_adapters/file_adapter_spec.rb +131 -0
  130. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +104 -0
  131. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
  132. data/spec/paperclip/io_adapters/nil_adapter_spec.rb +25 -0
  133. data/spec/paperclip/io_adapters/registry_spec.rb +35 -0
  134. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +64 -0
  135. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +146 -0
  136. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +127 -0
  137. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
  138. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +99 -0
  139. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
  140. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
  141. data/spec/paperclip/media_type_spoof_detector_spec.rb +79 -0
  142. data/spec/paperclip/meta_class_spec.rb +30 -0
  143. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
  144. data/spec/paperclip/paperclip_spec.rb +222 -0
  145. data/spec/paperclip/plural_cache_spec.rb +37 -0
  146. data/spec/paperclip/processor_helpers_spec.rb +57 -0
  147. data/spec/paperclip/processor_spec.rb +26 -0
  148. data/spec/paperclip/rails_environment_spec.rb +33 -0
  149. data/spec/paperclip/rake_spec.rb +103 -0
  150. data/spec/paperclip/schema_spec.rb +248 -0
  151. data/spec/paperclip/storage/filesystem_spec.rb +79 -0
  152. data/spec/paperclip/storage/fog_spec.rb +535 -0
  153. data/spec/paperclip/storage/s3_live_spec.rb +182 -0
  154. data/spec/paperclip/storage/s3_spec.rb +1526 -0
  155. data/spec/paperclip/style_spec.rb +255 -0
  156. data/spec/paperclip/tempfile_factory_spec.rb +33 -0
  157. data/spec/paperclip/thumbnail_spec.rb +500 -0
  158. data/spec/paperclip/url_generator_spec.rb +211 -0
  159. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
  160. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
  161. data/spec/paperclip/validators/attachment_presence_validator_spec.rb +85 -0
  162. data/spec/paperclip/validators/attachment_size_validator_spec.rb +229 -0
  163. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +52 -0
  164. data/spec/paperclip/validators_spec.rb +164 -0
  165. data/spec/spec_helper.rb +43 -0
  166. data/spec/support/assertions.rb +71 -0
  167. data/spec/support/deprecations.rb +9 -0
  168. data/spec/support/fake_model.rb +25 -0
  169. data/spec/support/fake_rails.rb +12 -0
  170. data/spec/support/fixtures/12k.png +0 -0
  171. data/spec/support/fixtures/50x50.png +0 -0
  172. data/spec/support/fixtures/5k.png +0 -0
  173. data/spec/support/fixtures/animated +0 -0
  174. data/spec/support/fixtures/animated.gif +0 -0
  175. data/spec/support/fixtures/animated.unknown +0 -0
  176. data/spec/support/fixtures/bad.png +1 -0
  177. data/spec/support/fixtures/empty.html +1 -0
  178. data/spec/support/fixtures/empty.xlsx +0 -0
  179. data/spec/support/fixtures/fog.yml +8 -0
  180. data/spec/support/fixtures/rotated.jpg +0 -0
  181. data/spec/support/fixtures/s3.yml +8 -0
  182. data/spec/support/fixtures/spaced file.jpg +0 -0
  183. data/spec/support/fixtures/spaced file.png +0 -0
  184. data/spec/support/fixtures/text.txt +1 -0
  185. data/spec/support/fixtures/twopage.pdf +0 -0
  186. data/spec/support/fixtures/uppercase.PNG +0 -0
  187. data/spec/support/matchers/accept.rb +5 -0
  188. data/spec/support/matchers/exist.rb +5 -0
  189. data/spec/support/matchers/have_column.rb +23 -0
  190. data/spec/support/mock_attachment.rb +22 -0
  191. data/spec/support/mock_interpolator.rb +24 -0
  192. data/spec/support/mock_url_generator_builder.rb +27 -0
  193. data/spec/support/model_reconstruction.rb +60 -0
  194. data/spec/support/rails_helpers.rb +7 -0
  195. data/spec/support/test_data.rb +13 -0
  196. data/spec/support/version_helper.rb +9 -0
  197. metadata +606 -0
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Plural cache' do
4
+ it 'caches pluralizations' do
5
+ cache = Paperclip::Interpolations::PluralCache.new
6
+ symbol = :box
7
+
8
+ first = cache.pluralize_symbol(symbol)
9
+ second = cache.pluralize_symbol(symbol)
10
+ expect(first).to equal(second)
11
+ end
12
+
13
+ it 'caches pluralizations and underscores' do
14
+ class BigBox ; end
15
+ cache = Paperclip::Interpolations::PluralCache.new
16
+ klass = BigBox
17
+
18
+ first = cache.underscore_and_pluralize_class(klass)
19
+ second = cache.underscore_and_pluralize_class(klass)
20
+ expect(first).to equal(second)
21
+ end
22
+
23
+ it 'pluralizes words' do
24
+ cache = Paperclip::Interpolations::PluralCache.new
25
+ symbol = :box
26
+
27
+ expect(cache.pluralize_symbol(symbol)).to eq("boxes")
28
+ end
29
+
30
+ it 'pluralizes and underscore class names' do
31
+ class BigBox ; end
32
+ cache = Paperclip::Interpolations::PluralCache.new
33
+ klass = BigBox
34
+
35
+ expect(cache.underscore_and_pluralize_class(klass)).to eq("big_boxes")
36
+ end
37
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::ProcessorHelpers do
4
+ describe '.load_processor' do
5
+ context 'when the file exists in lib/paperclip' do
6
+ it 'loads it correctly' do
7
+ pathname = Pathname.new('my_app')
8
+ main_path = 'main_path'
9
+ alternate_path = 'alternate_path'
10
+
11
+ Rails.stubs(:root).returns(pathname)
12
+ File.expects(:expand_path).with(pathname.join('lib/paperclip', 'custom.rb')).returns(main_path)
13
+ File.expects(:expand_path).with(pathname.join('lib/paperclip_processors', 'custom.rb')).returns(alternate_path)
14
+ File.expects(:exist?).with(main_path).returns(true)
15
+ File.expects(:exist?).with(alternate_path).returns(false)
16
+
17
+ Paperclip.expects(:require).with(main_path)
18
+
19
+ Paperclip.load_processor(:custom)
20
+ end
21
+ end
22
+
23
+ context 'when the file exists in lib/paperclip_processors' do
24
+ it 'loads it correctly' do
25
+ pathname = Pathname.new('my_app')
26
+ main_path = 'main_path'
27
+ alternate_path = 'alternate_path'
28
+
29
+ Rails.stubs(:root).returns(pathname)
30
+ File.expects(:expand_path).with(pathname.join('lib/paperclip', 'custom.rb')).returns(main_path)
31
+ File.expects(:expand_path).with(pathname.join('lib/paperclip_processors', 'custom.rb')).returns(alternate_path)
32
+ File.expects(:exist?).with(main_path).returns(false)
33
+ File.expects(:exist?).with(alternate_path).returns(true)
34
+
35
+ Paperclip.expects(:require).with(alternate_path)
36
+
37
+ Paperclip.load_processor(:custom)
38
+ end
39
+ end
40
+
41
+ context 'when the file does not exist in lib/paperclip_processors' do
42
+ it 'raises an error' do
43
+ pathname = Pathname.new('my_app')
44
+ main_path = 'main_path'
45
+ alternate_path = 'alternate_path'
46
+
47
+ Rails.stubs(:root).returns(pathname)
48
+ File.stubs(:expand_path).with(pathname.join('lib/paperclip', 'custom.rb')).returns(main_path)
49
+ File.stubs(:expand_path).with(pathname.join('lib/paperclip_processors', 'custom.rb')).returns(alternate_path)
50
+ File.stubs(:exist?).with(main_path).returns(false)
51
+ File.stubs(:exist?).with(alternate_path).returns(false)
52
+
53
+ assert_raises(LoadError) { Paperclip.processor(:custom) }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::Processor do
4
+ it "instantiates and call #make when sent #make to the class" do
5
+ processor = mock
6
+ processor.expects(:make).with()
7
+ Paperclip::Processor.expects(:new).with(:one, :two, :three).returns(processor)
8
+ Paperclip::Processor.make(:one, :two, :three)
9
+ end
10
+
11
+ context "Calling #convert" do
12
+ it "runs the convert command with Cocaine" do
13
+ Paperclip.options[:log_command] = false
14
+ Cocaine::CommandLine.expects(:new).with("convert", "stuff", {}).returns(stub(:run))
15
+ Paperclip::Processor.new('filename').convert("stuff")
16
+ end
17
+ end
18
+
19
+ context "Calling #identify" do
20
+ it "runs the identify command with Cocaine" do
21
+ Paperclip.options[:log_command] = false
22
+ Cocaine::CommandLine.expects(:new).with("identify", "stuff", {}).returns(stub(:run))
23
+ Paperclip::Processor.new('filename').identify("stuff")
24
+ end
25
+ end
26
+ 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
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+ require 'rake'
3
+ load './lib/tasks/paperclip.rake'
4
+
5
+ describe Rake do
6
+ context "calling `rake paperclip:refresh:thumbnails`" do
7
+ before do
8
+ rebuild_model
9
+ Paperclip::Task.stubs(:obtain_class).returns('Dummy')
10
+ @bogus_instance = Dummy.new
11
+ @bogus_instance.id = 'some_id'
12
+ @bogus_instance.avatar.stubs(:reprocess!)
13
+ @valid_instance = Dummy.new
14
+ @valid_instance.avatar.stubs(:reprocess!)
15
+ Paperclip::Task.stubs(:log_error)
16
+ Paperclip.stubs(:each_instance_with_attachment).multiple_yields @bogus_instance, @valid_instance
17
+ end
18
+ context "when there is an exception in reprocess!" do
19
+ before do
20
+ @bogus_instance.avatar.stubs(:reprocess!).raises
21
+ end
22
+
23
+ it "catches the exception" do
24
+ assert_nothing_raised do
25
+ ::Rake::Task['paperclip:refresh:thumbnails'].execute
26
+ end
27
+ end
28
+
29
+ it "continues to the next instance" do
30
+ @valid_instance.avatar.expects(:reprocess!)
31
+ ::Rake::Task['paperclip:refresh:thumbnails'].execute
32
+ end
33
+
34
+ it "prints the exception" do
35
+ exception_msg = 'Some Exception'
36
+ @bogus_instance.avatar.stubs(:reprocess!).raises(exception_msg)
37
+ Paperclip::Task.expects(:log_error).with do |str|
38
+ str.match exception_msg
39
+ end
40
+ ::Rake::Task['paperclip:refresh:thumbnails'].execute
41
+ end
42
+
43
+ it "prints the class name" do
44
+ Paperclip::Task.expects(:log_error).with do |str|
45
+ str.match 'Dummy'
46
+ end
47
+ ::Rake::Task['paperclip:refresh:thumbnails'].execute
48
+ end
49
+
50
+ it "prints the instance ID" do
51
+ Paperclip::Task.expects(:log_error).with do |str|
52
+ str.match "ID #{@bogus_instance.id}"
53
+ end
54
+ ::Rake::Task['paperclip:refresh:thumbnails'].execute
55
+ end
56
+ end
57
+
58
+ context "when there is an error in reprocess!" do
59
+ before do
60
+ @errors = mock('errors')
61
+ @errors.stubs(:full_messages).returns([''])
62
+ @errors.stubs(:blank?).returns(false)
63
+ @bogus_instance.stubs(:errors).returns(@errors)
64
+ end
65
+
66
+ it "continues to the next instance" do
67
+ @valid_instance.avatar.expects(:reprocess!)
68
+ ::Rake::Task['paperclip:refresh:thumbnails'].execute
69
+ end
70
+
71
+ it "prints the error" do
72
+ error_msg = 'Some Error'
73
+ @errors.stubs(:full_messages).returns([error_msg])
74
+ Paperclip::Task.expects(:log_error).with do |str|
75
+ str.match error_msg
76
+ end
77
+ ::Rake::Task['paperclip:refresh:thumbnails'].execute
78
+ end
79
+
80
+ it "prints the class name" do
81
+ Paperclip::Task.expects(:log_error).with do |str|
82
+ str.match 'Dummy'
83
+ end
84
+ ::Rake::Task['paperclip:refresh:thumbnails'].execute
85
+ end
86
+
87
+ it "prints the instance ID" do
88
+ Paperclip::Task.expects(:log_error).with do |str|
89
+ str.match "ID #{@bogus_instance.id}"
90
+ end
91
+ ::Rake::Task['paperclip:refresh:thumbnails'].execute
92
+ end
93
+ end
94
+ end
95
+
96
+ context "Paperclip::Task.log_error method" do
97
+ it "prints its argument to STDERR" do
98
+ msg = 'Some Message'
99
+ $stderr.expects(:puts).with(msg)
100
+ Paperclip::Task.log_error(msg)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,248 @@
1
+ require 'spec_helper'
2
+ require 'paperclip/schema'
3
+ require 'active_support/testing/deprecation'
4
+
5
+ describe Paperclip::Schema do
6
+ include ActiveSupport::Testing::Deprecation
7
+
8
+ before do
9
+ rebuild_class
10
+ end
11
+
12
+ after do
13
+ Dummy.connection.drop_table :dummies rescue nil
14
+ end
15
+
16
+ context "within table definition" do
17
+ context "using #has_attached_file" do
18
+ before do
19
+ ActiveSupport::Deprecation.silenced = false
20
+ end
21
+ it "creates attachment columns" do
22
+ Dummy.connection.create_table :dummies, force: true do |t|
23
+ ActiveSupport::Deprecation.silence do
24
+ t.has_attached_file :avatar
25
+ end
26
+ end
27
+
28
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
29
+
30
+ expect(columns).to include(['avatar_file_name', :string])
31
+ expect(columns).to include(['avatar_content_type', :string])
32
+ expect(columns).to include(['avatar_file_size', :integer])
33
+ expect(columns).to include(['avatar_updated_at', :datetime])
34
+ end
35
+
36
+ it "displays deprecation warning" do
37
+ Dummy.connection.create_table :dummies, force: true do |t|
38
+ assert_deprecated do
39
+ t.has_attached_file :avatar
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ context "using #attachment" do
46
+ before do
47
+ Dummy.connection.create_table :dummies, force: true do |t|
48
+ t.attachment :avatar
49
+ end
50
+ end
51
+
52
+ it "creates attachment columns" do
53
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
54
+
55
+ expect(columns).to include(['avatar_file_name', :string])
56
+ expect(columns).to include(['avatar_content_type', :string])
57
+ expect(columns).to include(['avatar_file_size', :integer])
58
+ expect(columns).to include(['avatar_updated_at', :datetime])
59
+ end
60
+ end
61
+
62
+ context "using #attachment with options" do
63
+ before do
64
+ Dummy.connection.create_table :dummies, force: true do |t|
65
+ t.attachment :avatar, default: 1, file_name: { default: 'default' }
66
+ end
67
+ end
68
+
69
+ it "sets defaults on columns" do
70
+ defaults_columns = ["avatar_file_name", "avatar_content_type", "avatar_file_size"]
71
+ columns = Dummy.columns.select { |e| defaults_columns.include? e.name }
72
+
73
+ expect(columns).to have_column("avatar_file_name").with_default("default")
74
+ expect(columns).to have_column("avatar_content_type").with_default("1")
75
+ expect(columns).to have_column("avatar_file_size").with_default(1)
76
+ end
77
+ end
78
+ end
79
+
80
+ context "within schema statement" do
81
+ before do
82
+ Dummy.connection.create_table :dummies, force: true
83
+ end
84
+
85
+ context "migrating up" do
86
+ context "with single attachment" do
87
+ before do
88
+ Dummy.connection.add_attachment :dummies, :avatar
89
+ end
90
+
91
+ it "creates attachment columns" do
92
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
93
+
94
+ expect(columns).to include(['avatar_file_name', :string])
95
+ expect(columns).to include(['avatar_content_type', :string])
96
+ expect(columns).to include(['avatar_file_size', :integer])
97
+ expect(columns).to include(['avatar_updated_at', :datetime])
98
+ end
99
+ end
100
+
101
+ context "with single attachment and options" do
102
+ before do
103
+ Dummy.connection.add_attachment :dummies, :avatar, default: '1', file_name: { default: 'default' }
104
+ end
105
+
106
+ it "sets defaults on columns" do
107
+ defaults_columns = ["avatar_file_name", "avatar_content_type", "avatar_file_size"]
108
+ columns = Dummy.columns.select { |e| defaults_columns.include? e.name }
109
+
110
+ expect(columns).to have_column("avatar_file_name").with_default("default")
111
+ expect(columns).to have_column("avatar_content_type").with_default("1")
112
+ expect(columns).to have_column("avatar_file_size").with_default(1)
113
+ end
114
+ end
115
+
116
+ context "with multiple attachments" do
117
+ before do
118
+ Dummy.connection.add_attachment :dummies, :avatar, :photo
119
+ end
120
+
121
+ it "creates attachment columns" do
122
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
123
+
124
+ expect(columns).to include(['avatar_file_name', :string])
125
+ expect(columns).to include(['avatar_content_type', :string])
126
+ expect(columns).to include(['avatar_file_size', :integer])
127
+ expect(columns).to include(['avatar_updated_at', :datetime])
128
+ expect(columns).to include(['photo_file_name', :string])
129
+ expect(columns).to include(['photo_content_type', :string])
130
+ expect(columns).to include(['photo_file_size', :integer])
131
+ expect(columns).to include(['photo_updated_at', :datetime])
132
+ end
133
+ end
134
+
135
+ context "with multiple attachments and options" do
136
+ before do
137
+ Dummy.connection.add_attachment :dummies, :avatar, :photo, default: '1', file_name: { default: 'default' }
138
+ end
139
+
140
+ it "sets defaults on columns" do
141
+ defaults_columns = ["avatar_file_name", "avatar_content_type", "avatar_file_size", "photo_file_name", "photo_content_type", "photo_file_size"]
142
+ columns = Dummy.columns.select { |e| defaults_columns.include? e.name }
143
+
144
+ expect(columns).to have_column("avatar_file_name").with_default("default")
145
+ expect(columns).to have_column("avatar_content_type").with_default("1")
146
+ expect(columns).to have_column("avatar_file_size").with_default(1)
147
+ expect(columns).to have_column("photo_file_name").with_default("default")
148
+ expect(columns).to have_column("photo_content_type").with_default("1")
149
+ expect(columns).to have_column("photo_file_size").with_default(1)
150
+ end
151
+ end
152
+
153
+ context "with no attachment" do
154
+ it "raises an error" do
155
+ assert_raises ArgumentError do
156
+ Dummy.connection.add_attachment :dummies
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ context "migrating down" do
163
+ before do
164
+ Dummy.connection.change_table :dummies do |t|
165
+ t.column :avatar_file_name, :string
166
+ t.column :avatar_content_type, :string
167
+ t.column :avatar_file_size, :integer
168
+ t.column :avatar_updated_at, :datetime
169
+ end
170
+ end
171
+
172
+ context "using #drop_attached_file" do
173
+ before do
174
+ ActiveSupport::Deprecation.silenced = false
175
+ end
176
+ it "removes the attachment columns" do
177
+ ActiveSupport::Deprecation.silence do
178
+ Dummy.connection.drop_attached_file :dummies, :avatar
179
+ end
180
+
181
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
182
+
183
+ expect(columns).to_not include(['avatar_file_name', :string])
184
+ expect(columns).to_not include(['avatar_content_type', :string])
185
+ expect(columns).to_not include(['avatar_file_size', :integer])
186
+ expect(columns).to_not include(['avatar_updated_at', :datetime])
187
+ end
188
+
189
+ it "displays a deprecation warning" do
190
+ assert_deprecated do
191
+ Dummy.connection.drop_attached_file :dummies, :avatar
192
+ end
193
+ end
194
+ end
195
+
196
+ context "using #remove_attachment" do
197
+ context "with single attachment" do
198
+ before do
199
+ Dummy.connection.remove_attachment :dummies, :avatar
200
+ end
201
+
202
+ it "removes the attachment columns" do
203
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
204
+
205
+ expect(columns).to_not include(['avatar_file_name', :string])
206
+ expect(columns).to_not include(['avatar_content_type', :string])
207
+ expect(columns).to_not include(['avatar_file_size', :integer])
208
+ expect(columns).to_not include(['avatar_updated_at', :datetime])
209
+ end
210
+ end
211
+
212
+ context "with multiple attachments" do
213
+ before do
214
+ Dummy.connection.change_table :dummies do |t|
215
+ t.column :photo_file_name, :string
216
+ t.column :photo_content_type, :string
217
+ t.column :photo_file_size, :integer
218
+ t.column :photo_updated_at, :datetime
219
+ end
220
+
221
+ Dummy.connection.remove_attachment :dummies, :avatar, :photo
222
+ end
223
+
224
+ it "removes the attachment columns" do
225
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
226
+
227
+ expect(columns).to_not include(['avatar_file_name', :string])
228
+ expect(columns).to_not include(['avatar_content_type', :string])
229
+ expect(columns).to_not include(['avatar_file_size', :integer])
230
+ expect(columns).to_not include(['avatar_updated_at', :datetime])
231
+ expect(columns).to_not include(['photo_file_name', :string])
232
+ expect(columns).to_not include(['photo_content_type', :string])
233
+ expect(columns).to_not include(['photo_file_size', :integer])
234
+ expect(columns).to_not include(['photo_updated_at', :datetime])
235
+ end
236
+ end
237
+
238
+ context "with no attachment" do
239
+ it "raises an error" do
240
+ assert_raises ArgumentError do
241
+ Dummy.connection.remove_attachment :dummies
242
+ end
243
+ end
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::Storage::Filesystem do
4
+ context "Filesystem" do
5
+ context "normal file" do
6
+ before do
7
+ rebuild_model styles: { thumbnail: "25x25#" }
8
+ @dummy = Dummy.create!
9
+
10
+ @file = File.open(fixture_file('5k.png'))
11
+ @dummy.avatar = @file
12
+ end
13
+
14
+ after { @file.close }
15
+
16
+ it "allows file assignment" do
17
+ assert @dummy.save
18
+ end
19
+
20
+ it "stores the original" do
21
+ @dummy.save
22
+ assert_file_exists(@dummy.avatar.path)
23
+ end
24
+
25
+ it "stores the thumbnail" do
26
+ @dummy.save
27
+ assert_file_exists(@dummy.avatar.path(:thumbnail))
28
+ end
29
+
30
+ it "is rewinded after flush_writes" do
31
+ @dummy.avatar.instance_eval "def after_flush_writes; end"
32
+
33
+ files = @dummy.avatar.queued_for_write.values
34
+ @dummy.save
35
+ assert files.none?(&:eof?), "Expect all the files to be rewinded."
36
+ end
37
+
38
+ it "is removed after after_flush_writes" do
39
+ paths = @dummy.avatar.queued_for_write.values.map(&:path)
40
+ @dummy.save
41
+ assert paths.none?{ |path| File.exist?(path) },
42
+ "Expect all the files to be deleted."
43
+ end
44
+
45
+ it 'copies the file to a known location with copy_to_local_file' do
46
+ tempfile = Tempfile.new("known_location")
47
+ @dummy.avatar.copy_to_local_file(:original, tempfile.path)
48
+ tempfile.rewind
49
+ assert_equal @file.read, tempfile.read
50
+ tempfile.close
51
+ end
52
+ end
53
+
54
+ context "with file that has space in file name" do
55
+ before do
56
+ rebuild_model styles: { thumbnail: "25x25#" }
57
+ @dummy = Dummy.create!
58
+
59
+ @file = File.open(fixture_file('spaced file.png'))
60
+ @dummy.avatar = @file
61
+ @dummy.save
62
+ end
63
+
64
+ after { @file.close }
65
+
66
+ it "stores the file" do
67
+ assert_file_exists(@dummy.avatar.path)
68
+ end
69
+
70
+ it "returns a replaced version for path" do
71
+ assert_match /.+\/spaced_file\.png/, @dummy.avatar.path
72
+ end
73
+
74
+ it "returns a replaced version for url" do
75
+ assert_match /.+\/spaced_file\.png/, @dummy.avatar.url
76
+ end
77
+ end
78
+ end
79
+ end