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,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::FileAdapter do
4
+ context "a new instance" do
5
+ context "with normal file" do
6
+ before do
7
+ @file = File.new(fixture_file("5k.png"))
8
+ @file.binmode
9
+ end
10
+
11
+ after do
12
+ @file.close
13
+ @subject.close if @subject
14
+ end
15
+
16
+ context 'doing normal things' do
17
+ before do
18
+ @subject = Paperclip.io_adapters.for(@file)
19
+ end
20
+
21
+ it 'uses the original filename to generate the tempfile' do
22
+ assert @subject.path.ends_with?(".png")
23
+ end
24
+
25
+ it "gets the right filename" do
26
+ assert_equal "5k.png", @subject.original_filename
27
+ end
28
+
29
+ it "forces binmode on tempfile" do
30
+ assert @subject.instance_variable_get("@tempfile").binmode?
31
+ end
32
+
33
+ it "gets the content type" do
34
+ assert_equal "image/png", @subject.content_type
35
+ end
36
+
37
+ it "returns content type as a string" do
38
+ expect(@subject.content_type).to be_a String
39
+ end
40
+
41
+ it "gets the file's size" do
42
+ assert_equal 4456, @subject.size
43
+ end
44
+
45
+ it "returns false for a call to nil?" do
46
+ assert ! @subject.nil?
47
+ end
48
+
49
+ it "generates a MD5 hash of the contents" do
50
+ expected = Digest::MD5.file(@file.path).to_s
51
+ assert_equal expected, @subject.fingerprint
52
+ end
53
+
54
+ it "reads the contents of the file" do
55
+ expected = @file.read
56
+ assert expected.length > 0
57
+ assert_equal expected, @subject.read
58
+ end
59
+ end
60
+
61
+ context "file with multiple possible content type" do
62
+ before do
63
+ MIME::Types.stubs(:type_for).returns([MIME::Type.new('image/x-png'), MIME::Type.new('image/png')])
64
+ @subject = Paperclip.io_adapters.for(@file)
65
+ end
66
+
67
+ it "prefers officially registered mime type" do
68
+ assert_equal "image/png", @subject.content_type
69
+ end
70
+
71
+ it "returns content type as a string" do
72
+ expect(@subject.content_type).to be_a String
73
+ end
74
+ end
75
+
76
+ context "file with content type derived from file contents on *nix" do
77
+ before do
78
+ MIME::Types.stubs(:type_for).returns([])
79
+ Paperclip.stubs(:run).returns("application/vnd.ms-office\n")
80
+ Paperclip::ContentTypeDetector.any_instance
81
+ .stubs(:type_from_mime_magic).returns("application/vnd.ms-office")
82
+
83
+ @subject = Paperclip.io_adapters.for(@file)
84
+ end
85
+
86
+ it "returns content type without newline character" do
87
+ assert_equal "application/vnd.ms-office", @subject.content_type
88
+ end
89
+ end
90
+ end
91
+
92
+ context "filename with restricted characters" do
93
+ before do
94
+ @file = File.open(fixture_file("animated.gif")) do |file|
95
+ StringIO.new(file.read)
96
+ end
97
+ @file.stubs(:original_filename).returns('image:restricted.gif')
98
+ @subject = Paperclip.io_adapters.for(@file)
99
+ end
100
+
101
+ after do
102
+ @file.close
103
+ @subject.close
104
+ end
105
+
106
+ it "does not generate filenames that include restricted characters" do
107
+ assert_equal 'image_restricted.gif', @subject.original_filename
108
+ end
109
+
110
+ it "does not generate paths that include restricted characters" do
111
+ expect(@subject.path).to_not match(/:/)
112
+ end
113
+ end
114
+
115
+ context "empty file" do
116
+ before do
117
+ @file = Tempfile.new("file_adapter_test")
118
+ @subject = Paperclip.io_adapters.for(@file)
119
+ end
120
+
121
+ after do
122
+ @file.close
123
+ @subject.close
124
+ end
125
+
126
+ it "provides correct mime-type" do
127
+ assert_match %r{.*/x-empty}, @subject.content_type
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::HttpUrlProxyAdapter do
4
+ before do
5
+ @open_return = StringIO.new("xxx")
6
+ @open_return.stubs(:content_type).returns("image/png")
7
+ @open_return.stubs(:meta).returns({})
8
+ Paperclip::HttpUrlProxyAdapter.any_instance.
9
+ stubs(:download_content).returns(@open_return)
10
+ end
11
+
12
+ context "a new instance" do
13
+ before do
14
+ @url = "http://thoughtbot.com/images/thoughtbot-logo.png"
15
+ @subject = Paperclip.io_adapters.for(@url)
16
+ end
17
+
18
+ after do
19
+ @subject.close
20
+ end
21
+
22
+ it "returns a file name" do
23
+ assert_equal "thoughtbot-logo.png", @subject.original_filename
24
+ end
25
+
26
+ it 'closes open handle after reading' do
27
+ assert_equal true, @open_return.closed?
28
+ end
29
+
30
+ it "returns a content type" do
31
+ assert_equal "image/png", @subject.content_type
32
+ end
33
+
34
+ it "returns the size of the data" do
35
+ assert_equal @open_return.size, @subject.size
36
+ end
37
+
38
+ it "generates an MD5 hash of the contents" do
39
+ assert_equal Digest::MD5.hexdigest("xxx"), @subject.fingerprint
40
+ end
41
+
42
+ it "generates correct fingerprint after read" do
43
+ fingerprint = Digest::MD5.hexdigest(@subject.read)
44
+ assert_equal fingerprint, @subject.fingerprint
45
+ end
46
+
47
+ it "generates same fingerprint" do
48
+ assert_equal @subject.fingerprint, @subject.fingerprint
49
+ end
50
+
51
+ it "returns the data contained in the StringIO" do
52
+ assert_equal "xxx", @subject.read
53
+ end
54
+
55
+ it 'accepts a content_type' do
56
+ @subject.content_type = 'image/png'
57
+ assert_equal 'image/png', @subject.content_type
58
+ end
59
+
60
+ it 'accepts an original_filename' do
61
+ @subject.original_filename = 'image.png'
62
+ assert_equal 'image.png', @subject.original_filename
63
+ end
64
+ end
65
+
66
+ context "a url with query params" do
67
+ before do
68
+ @url = "https://github.com/thoughtbot/paperclip?file=test"
69
+ @subject = Paperclip.io_adapters.for(@url)
70
+ end
71
+
72
+ after do
73
+ @subject.close
74
+ end
75
+
76
+ it "returns a file name" do
77
+ assert_equal "paperclip", @subject.original_filename
78
+ end
79
+ end
80
+
81
+ context "a url with restricted characters in the filename" do
82
+ before do
83
+ @url = "https://github.com/thoughtbot/paper:clip.jpg"
84
+ @subject = Paperclip.io_adapters.for(@url)
85
+ end
86
+
87
+ after do
88
+ begin
89
+ @subject.close
90
+ rescue Exception
91
+ true
92
+ end
93
+ end
94
+
95
+ it "does not generate filenames that include restricted characters" do
96
+ assert_equal "paper_clip.jpg", @subject.original_filename
97
+ end
98
+
99
+ it "does not generate paths that include restricted characters" do
100
+ expect(@subject.path).to_not match(/:/)
101
+ end
102
+ end
103
+
104
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::IdentityAdapter do
4
+ it "responds to #new by returning the argument" do
5
+ adapter = Paperclip::IdentityAdapter.new
6
+ assert_equal :target, adapter.new(:target)
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::NilAdapter do
4
+ context 'a new instance' do
5
+ before do
6
+ @subject = Paperclip.io_adapters.for(nil)
7
+ end
8
+
9
+ it "gets the right filename" do
10
+ assert_equal "", @subject.original_filename
11
+ end
12
+
13
+ it "gets the content type" do
14
+ assert_equal "", @subject.content_type
15
+ end
16
+
17
+ it "gets the file's size" do
18
+ assert_equal 0, @subject.size
19
+ end
20
+
21
+ it "returns true for a call to nil?" do
22
+ assert @subject.nil?
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::AttachmentRegistry do
4
+ context "for" do
5
+ before do
6
+ class AdapterTest
7
+ def initialize(target); end
8
+ end
9
+ @subject = Paperclip::AdapterRegistry.new
10
+ @subject.register(AdapterTest){|t| Symbol === t }
11
+ end
12
+
13
+ it "returns the class registered for the adapted type" do
14
+ assert_equal AdapterTest, @subject.for(:target).class
15
+ end
16
+ end
17
+
18
+ context "registered?" do
19
+ before do
20
+ class AdapterTest
21
+ def initialize(target); end
22
+ end
23
+ @subject = Paperclip::AdapterRegistry.new
24
+ @subject.register(AdapterTest){|t| Symbol === t }
25
+ end
26
+
27
+ it "returns true when the class of this adapter has been registered" do
28
+ assert @subject.registered?(AdapterTest.new(:target))
29
+ end
30
+
31
+ it "returns false when the adapter has not been registered" do
32
+ assert ! @subject.registered?(Object)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::StringioAdapter do
4
+ context "a new instance" do
5
+ before do
6
+ @contents = "abc123"
7
+ @stringio = StringIO.new(@contents)
8
+ @subject = Paperclip.io_adapters.for(@stringio)
9
+ end
10
+
11
+ it "returns a file name" do
12
+ assert_equal "data", @subject.original_filename
13
+ end
14
+
15
+ it "returns a content type" do
16
+ assert_equal "text/plain", @subject.content_type
17
+ end
18
+
19
+ it "returns the size of the data" do
20
+ assert_equal 6, @subject.size
21
+ end
22
+
23
+ it "returns the length of the data" do
24
+ assert_equal 6, @subject.length
25
+ end
26
+
27
+ it "generates an MD5 hash of the contents" do
28
+ assert_equal Digest::MD5.hexdigest(@contents), @subject.fingerprint
29
+ end
30
+
31
+ it "generates correct fingerprint after read" do
32
+ fingerprint = Digest::MD5.hexdigest(@subject.read)
33
+ assert_equal fingerprint, @subject.fingerprint
34
+ end
35
+
36
+ it "generates same fingerprint" do
37
+ assert_equal @subject.fingerprint, @subject.fingerprint
38
+ end
39
+
40
+ it "returns the data contained in the StringIO" do
41
+ assert_equal "abc123", @subject.read
42
+ end
43
+
44
+ it 'accepts a content_type' do
45
+ @subject.content_type = 'image/png'
46
+ assert_equal 'image/png', @subject.content_type
47
+ end
48
+
49
+ it 'accepts an original_filename' do
50
+ @subject.original_filename = 'image.png'
51
+ assert_equal 'image.png', @subject.original_filename
52
+ end
53
+
54
+ it "does not generate filenames that include restricted characters" do
55
+ @subject.original_filename = 'image:restricted.png'
56
+ assert_equal 'image_restricted.png', @subject.original_filename
57
+ end
58
+
59
+ it "does not generate paths that include restricted characters" do
60
+ @subject.original_filename = 'image:restricted.png'
61
+ expect(@subject.path).to_not match(/:/)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::UploadedFileAdapter do
4
+ context "a new instance" do
5
+ context "with UploadedFile responding to #tempfile" do
6
+ before do
7
+ Paperclip::UploadedFileAdapter.content_type_detector = nil
8
+
9
+ class UploadedFile < OpenStruct; end
10
+ tempfile = File.new(fixture_file("5k.png"))
11
+ tempfile.binmode
12
+
13
+ @file = UploadedFile.new(
14
+ original_filename: "5k.png",
15
+ content_type: "image/x-png-by-browser\r",
16
+ head: "",
17
+ tempfile: tempfile,
18
+ path: tempfile.path
19
+ )
20
+ @subject = Paperclip.io_adapters.for(@file)
21
+ end
22
+
23
+ it "gets the right filename" do
24
+ assert_equal "5k.png", @subject.original_filename
25
+ end
26
+
27
+ it "forces binmode on tempfile" do
28
+ assert @subject.instance_variable_get("@tempfile").binmode?
29
+ end
30
+
31
+ it "gets the content type" do
32
+ assert_equal "image/x-png-by-browser", @subject.content_type
33
+ end
34
+
35
+ it "gets the file's size" do
36
+ assert_equal 4456, @subject.size
37
+ end
38
+
39
+ it "returns false for a call to nil?" do
40
+ assert ! @subject.nil?
41
+ end
42
+
43
+ it "generates a MD5 hash of the contents" do
44
+ expected = Digest::MD5.file(@file.tempfile.path).to_s
45
+ assert_equal expected, @subject.fingerprint
46
+ end
47
+
48
+ it "reads the contents of the file" do
49
+ expected = @file.tempfile.read
50
+ assert expected.length > 0
51
+ assert_equal expected, @subject.read
52
+ end
53
+ end
54
+
55
+ context "with UploadedFile that has restricted characters" do
56
+ before do
57
+ Paperclip::UploadedFileAdapter.content_type_detector = nil
58
+
59
+ class UploadedFile < OpenStruct; end
60
+ @file = UploadedFile.new(
61
+ original_filename: "image:restricted.gif",
62
+ content_type: "image/x-png-by-browser",
63
+ head: "",
64
+ path: fixture_file("5k.png")
65
+ )
66
+ @subject = Paperclip.io_adapters.for(@file)
67
+ end
68
+
69
+ it "does not generate paths that include restricted characters" do
70
+ expect(@subject.path).to_not match(/:/)
71
+ end
72
+
73
+ it "does not generate filenames that include restricted characters" do
74
+ assert_equal 'image_restricted.gif', @subject.original_filename
75
+ end
76
+ end
77
+
78
+ context "with UploadFile responding to #path" do
79
+ before do
80
+ Paperclip::UploadedFileAdapter.content_type_detector = nil
81
+
82
+ class UploadedFile < OpenStruct; end
83
+ @file = UploadedFile.new(
84
+ original_filename: "5k.png",
85
+ content_type: "image/x-png-by-browser",
86
+ head: "",
87
+ path: fixture_file("5k.png")
88
+ )
89
+ @subject = Paperclip.io_adapters.for(@file)
90
+ end
91
+
92
+ it "gets the right filename" do
93
+ assert_equal "5k.png", @subject.original_filename
94
+ end
95
+
96
+ it "forces binmode on tempfile" do
97
+ assert @subject.instance_variable_get("@tempfile").binmode?
98
+ end
99
+
100
+ it "gets the content type" do
101
+ assert_equal "image/x-png-by-browser", @subject.content_type
102
+ end
103
+
104
+ it "gets the file's size" do
105
+ assert_equal 4456, @subject.size
106
+ end
107
+
108
+ it "returns false for a call to nil?" do
109
+ assert ! @subject.nil?
110
+ end
111
+
112
+ it "generates a MD5 hash of the contents" do
113
+ expected = Digest::MD5.file(@file.path).to_s
114
+ assert_equal expected, @subject.fingerprint
115
+ end
116
+
117
+ it "reads the contents of the file" do
118
+ expected_file = File.new(@file.path)
119
+ expected_file.binmode
120
+ expected = expected_file.read
121
+ assert expected.length > 0
122
+ assert_equal expected, @subject.read
123
+ end
124
+
125
+ context "don't trust client-given MIME type" do
126
+ before do
127
+ Paperclip::UploadedFileAdapter.content_type_detector =
128
+ Paperclip::FileCommandContentTypeDetector
129
+
130
+ class UploadedFile < OpenStruct; end
131
+ @file = UploadedFile.new(
132
+ original_filename: "5k.png",
133
+ content_type: "image/x-png-by-browser",
134
+ head: "",
135
+ path: fixture_file("5k.png")
136
+ )
137
+ @subject = Paperclip.io_adapters.for(@file)
138
+ end
139
+
140
+ it "gets the content type" do
141
+ assert_equal "image/png", @subject.content_type
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::UriAdapter do
4
+ let(:content_type) { "image/png" }
5
+ let(:meta) { {} }
6
+
7
+ before do
8
+ @open_return = StringIO.new("xxx")
9
+ @open_return.stubs(:content_type).returns(content_type)
10
+ @open_return.stubs(:meta).returns(meta)
11
+ Paperclip::UriAdapter.any_instance.
12
+ stubs(:download_content).returns(@open_return)
13
+ end
14
+
15
+ context "a new instance" do
16
+ before do
17
+ @uri = URI.parse("http://thoughtbot.com/images/thoughtbot-logo.png")
18
+ @subject = Paperclip.io_adapters.for(@uri)
19
+ end
20
+
21
+ it "returns a file name" do
22
+ assert_equal "thoughtbot-logo.png", @subject.original_filename
23
+ end
24
+
25
+ it 'closes open handle after reading' do
26
+ assert_equal true, @open_return.closed?
27
+ end
28
+
29
+ it "returns a content type" do
30
+ assert_equal "image/png", @subject.content_type
31
+ end
32
+
33
+ it "returns the size of the data" do
34
+ assert_equal @open_return.size, @subject.size
35
+ end
36
+
37
+ it "generates an MD5 hash of the contents" do
38
+ assert_equal Digest::MD5.hexdigest("xxx"), @subject.fingerprint
39
+ end
40
+
41
+ it "generates correct fingerprint after read" do
42
+ fingerprint = Digest::MD5.hexdigest(@subject.read)
43
+ assert_equal fingerprint, @subject.fingerprint
44
+ end
45
+
46
+ it "generates same fingerprint" do
47
+ assert_equal @subject.fingerprint, @subject.fingerprint
48
+ end
49
+
50
+ it "returns the data contained in the StringIO" do
51
+ assert_equal "xxx", @subject.read
52
+ end
53
+
54
+ it 'accepts a content_type' do
55
+ @subject.content_type = 'image/png'
56
+ assert_equal 'image/png', @subject.content_type
57
+ end
58
+
59
+ it 'accepts an orgiginal_filename' do
60
+ @subject.original_filename = 'image.png'
61
+ assert_equal 'image.png', @subject.original_filename
62
+ end
63
+
64
+ end
65
+
66
+ context "a directory index url" do
67
+ let(:content_type) { "text/html" }
68
+
69
+ before do
70
+ @uri = URI.parse("http://thoughtbot.com")
71
+ @subject = Paperclip.io_adapters.for(@uri)
72
+ end
73
+
74
+ it "returns a file name" do
75
+ assert_equal "index.html", @subject.original_filename
76
+ end
77
+
78
+ it "returns a content type" do
79
+ assert_equal "text/html", @subject.content_type
80
+ end
81
+ end
82
+
83
+ context "a url with query params" do
84
+ before do
85
+ @uri = URI.parse("https://github.com/thoughtbot/paperclip?file=test")
86
+ @subject = Paperclip.io_adapters.for(@uri)
87
+ end
88
+
89
+ it "returns a file name" do
90
+ assert_equal "paperclip", @subject.original_filename
91
+ end
92
+ end
93
+
94
+ context "a url with content disposition headers" do
95
+ let(:file_name) { "test_document.pdf" }
96
+ let(:meta) do
97
+ {
98
+ "content-disposition" => "attachment; filename=\"#{file_name}\";",
99
+ }
100
+ end
101
+
102
+ before do
103
+ @uri = URI.parse("https://github.com/thoughtbot/paperclip?file=test")
104
+ @subject = Paperclip.io_adapters.for(@uri)
105
+ end
106
+
107
+ it "returns a file name" do
108
+ assert_equal file_name, @subject.original_filename
109
+ end
110
+ end
111
+
112
+ context "a url with restricted characters in the filename" do
113
+ before do
114
+ @uri = URI.parse("https://github.com/thoughtbot/paper:clip.jpg")
115
+ @subject = Paperclip.io_adapters.for(@uri)
116
+ end
117
+
118
+ it "does not generate filenames that include restricted characters" do
119
+ assert_equal "paper_clip.jpg", @subject.original_filename
120
+ end
121
+
122
+ it "does not generate paths that include restricted characters" do
123
+ expect(@subject.path).to_not match(/:/)
124
+ end
125
+ end
126
+
127
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'paperclip/matchers'
3
+
4
+ describe Paperclip::Shoulda::Matchers::HaveAttachedFileMatcher do
5
+ extend Paperclip::Shoulda::Matchers
6
+
7
+ it "rejects the dummy class if it has no attachment" do
8
+ reset_table "dummies"
9
+ reset_class "Dummy"
10
+ matcher = self.class.have_attached_file(:avatar)
11
+ expect(matcher).to_not accept(Dummy)
12
+ end
13
+
14
+ it 'accepts the dummy class if it has an attachment' do
15
+ rebuild_model
16
+ matcher = self.class.have_attached_file(:avatar)
17
+ expect(matcher).to accept(Dummy)
18
+ end
19
+ end