cloudfuji_paperclip 2.4.6

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 (105) hide show
  1. data/.gitignore +22 -0
  2. data/.travis.yml +13 -0
  3. data/Appraisals +14 -0
  4. data/CONTRIBUTING.md +38 -0
  5. data/Gemfile +5 -0
  6. data/Gemfile.lock +137 -0
  7. data/LICENSE +26 -0
  8. data/README.md +444 -0
  9. data/Rakefile +41 -0
  10. data/cucumber/paperclip_steps.rb +6 -0
  11. data/features/basic_integration.feature +46 -0
  12. data/features/rake_tasks.feature +63 -0
  13. data/features/step_definitions/attachment_steps.rb +65 -0
  14. data/features/step_definitions/html_steps.rb +15 -0
  15. data/features/step_definitions/rails_steps.rb +182 -0
  16. data/features/step_definitions/s3_steps.rb +14 -0
  17. data/features/step_definitions/web_steps.rb +209 -0
  18. data/features/support/env.rb +8 -0
  19. data/features/support/fakeweb.rb +3 -0
  20. data/features/support/fixtures/.boot_config.rb.swo +0 -0
  21. data/features/support/fixtures/boot_config.txt +15 -0
  22. data/features/support/fixtures/gemfile.txt +5 -0
  23. data/features/support/fixtures/preinitializer.txt +20 -0
  24. data/features/support/paths.rb +28 -0
  25. data/features/support/rails.rb +46 -0
  26. data/features/support/selectors.rb +19 -0
  27. data/gemfiles/rails2.gemfile +9 -0
  28. data/gemfiles/rails3.gemfile +9 -0
  29. data/gemfiles/rails3_1.gemfile +9 -0
  30. data/generators/paperclip/USAGE +5 -0
  31. data/generators/paperclip/paperclip_generator.rb +27 -0
  32. data/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  33. data/init.rb +4 -0
  34. data/lib/generators/paperclip/USAGE +8 -0
  35. data/lib/generators/paperclip/paperclip_generator.rb +33 -0
  36. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  37. data/lib/paperclip/attachment.rb +468 -0
  38. data/lib/paperclip/callback_compatibility.rb +61 -0
  39. data/lib/paperclip/geometry.rb +120 -0
  40. data/lib/paperclip/interpolations.rb +174 -0
  41. data/lib/paperclip/iostream.rb +45 -0
  42. data/lib/paperclip/matchers/have_attached_file_matcher.rb +57 -0
  43. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +81 -0
  44. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +54 -0
  45. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +95 -0
  46. data/lib/paperclip/matchers.rb +64 -0
  47. data/lib/paperclip/missing_attachment_styles.rb +87 -0
  48. data/lib/paperclip/processor.rb +58 -0
  49. data/lib/paperclip/railtie.rb +31 -0
  50. data/lib/paperclip/schema.rb +39 -0
  51. data/lib/paperclip/storage/filesystem.rb +81 -0
  52. data/lib/paperclip/storage/fog.rb +174 -0
  53. data/lib/paperclip/storage/s3.rb +333 -0
  54. data/lib/paperclip/storage.rb +3 -0
  55. data/lib/paperclip/style.rb +103 -0
  56. data/lib/paperclip/thumbnail.rb +105 -0
  57. data/lib/paperclip/upfile.rb +62 -0
  58. data/lib/paperclip/url_generator.rb +64 -0
  59. data/lib/paperclip/version.rb +3 -0
  60. data/lib/paperclip.rb +487 -0
  61. data/lib/tasks/paperclip.rake +101 -0
  62. data/paperclip.gemspec +41 -0
  63. data/rails/init.rb +2 -0
  64. data/shoulda_macros/paperclip.rb +124 -0
  65. data/test/.gitignore +1 -0
  66. data/test/attachment_test.rb +1116 -0
  67. data/test/database.yml +4 -0
  68. data/test/fixtures/12k.png +0 -0
  69. data/test/fixtures/50x50.png +0 -0
  70. data/test/fixtures/5k.png +0 -0
  71. data/test/fixtures/animated.gif +0 -0
  72. data/test/fixtures/bad.png +1 -0
  73. data/test/fixtures/fog.yml +8 -0
  74. data/test/fixtures/question?mark.png +0 -0
  75. data/test/fixtures/s3.yml +8 -0
  76. data/test/fixtures/spaced file.png +0 -0
  77. data/test/fixtures/text.txt +1 -0
  78. data/test/fixtures/twopage.pdf +0 -0
  79. data/test/fixtures/uppercase.PNG +0 -0
  80. data/test/geometry_test.rb +206 -0
  81. data/test/helper.rb +177 -0
  82. data/test/integration_test.rb +654 -0
  83. data/test/interpolations_test.rb +216 -0
  84. data/test/iostream_test.rb +71 -0
  85. data/test/matchers/have_attached_file_matcher_test.rb +24 -0
  86. data/test/matchers/validate_attachment_content_type_matcher_test.rb +87 -0
  87. data/test/matchers/validate_attachment_presence_matcher_test.rb +26 -0
  88. data/test/matchers/validate_attachment_size_matcher_test.rb +51 -0
  89. data/test/paperclip_missing_attachment_styles_test.rb +80 -0
  90. data/test/paperclip_test.rb +390 -0
  91. data/test/processor_test.rb +10 -0
  92. data/test/schema_test.rb +98 -0
  93. data/test/storage/filesystem_test.rb +56 -0
  94. data/test/storage/fog_test.rb +219 -0
  95. data/test/storage/s3_live_test.rb +138 -0
  96. data/test/storage/s3_test.rb +943 -0
  97. data/test/style_test.rb +209 -0
  98. data/test/support/mock_attachment.rb +22 -0
  99. data/test/support/mock_interpolator.rb +24 -0
  100. data/test/support/mock_model.rb +2 -0
  101. data/test/support/mock_url_generator_builder.rb +27 -0
  102. data/test/thumbnail_test.rb +383 -0
  103. data/test/upfile_test.rb +53 -0
  104. data/test/url_generator_test.rb +187 -0
  105. metadata +404 -0
@@ -0,0 +1,219 @@
1
+ require './test/helper'
2
+ require 'fog'
3
+
4
+ Fog.mock!
5
+
6
+ class FogTest < Test::Unit::TestCase
7
+ context "" do
8
+
9
+ context "with credentials provided in a path string" do
10
+ setup do
11
+ rebuild_model :styles => { :medium => "300x300>", :thumb => "100x100>" },
12
+ :storage => :fog,
13
+ :url => '/:attachment/:filename',
14
+ :fog_directory => "paperclip",
15
+ :fog_credentials => fixture_file('fog.yml')
16
+ @dummy = Dummy.new
17
+ @dummy.avatar = File.new(fixture_file('5k.png'), 'rb')
18
+ end
19
+
20
+ should "have the proper information loading credentials from a file" do
21
+ assert_equal @dummy.avatar.fog_credentials[:provider], 'AWS'
22
+ end
23
+ end
24
+
25
+ context "with credentials provided in a File object" do
26
+ setup do
27
+ rebuild_model :styles => { :medium => "300x300>", :thumb => "100x100>" },
28
+ :storage => :fog,
29
+ :url => '/:attachment/:filename',
30
+ :fog_directory => "paperclip",
31
+ :fog_credentials => File.open(fixture_file('fog.yml'))
32
+ @dummy = Dummy.new
33
+ @dummy.avatar = File.new(fixture_file('5k.png'), 'rb')
34
+ end
35
+
36
+ should "have the proper information loading credentials from a file" do
37
+ assert_equal @dummy.avatar.fog_credentials[:provider], 'AWS'
38
+ end
39
+ end
40
+
41
+ context "with default values for path and url" do
42
+ setup do
43
+ rebuild_model :styles => { :medium => "300x300>", :thumb => "100x100>" },
44
+ :storage => :fog,
45
+ :url => '/:attachment/:filename',
46
+ :fog_directory => "paperclip",
47
+ :fog_credentials => {
48
+ :provider => 'AWS',
49
+ :aws_access_key_id => 'AWS_ID',
50
+ :aws_secret_access_key => 'AWS_SECRET'
51
+ }
52
+ @dummy = Dummy.new
53
+ @dummy.avatar = File.new(fixture_file('5k.png'), 'rb')
54
+ end
55
+ should "be able to interpolate the path without blowing up" do
56
+ assert_equal File.expand_path(File.join(File.dirname(__FILE__), "../../public/avatars/5k.png")),
57
+ @dummy.avatar.path
58
+ end
59
+
60
+ should "clean up file objects" do
61
+ File.stubs(:exist?).returns(true)
62
+ Paperclip::Tempfile.any_instance.expects(:close).at_least_once()
63
+ Paperclip::Tempfile.any_instance.expects(:unlink).at_least_once()
64
+
65
+ @dummy.save!
66
+ end
67
+ end
68
+
69
+ setup do
70
+ @fog_directory = 'papercliptests'
71
+
72
+ @credentials = {
73
+ :provider => 'AWS',
74
+ :aws_access_key_id => 'ID',
75
+ :aws_secret_access_key => 'SECRET'
76
+ }
77
+
78
+ @connection = Fog::Storage.new(@credentials)
79
+ @connection.directories.create(
80
+ :key => @fog_directory
81
+ )
82
+
83
+ @options = {
84
+ :fog_directory => @fog_directory,
85
+ :fog_credentials => @credentials,
86
+ :fog_host => nil,
87
+ :fog_file => {:cache_control => 1234},
88
+ :path => ":attachment/:basename.:extension",
89
+ :storage => :fog
90
+ }
91
+
92
+ rebuild_model(@options)
93
+ end
94
+
95
+ should "be extended by the Fog module" do
96
+ assert Dummy.new.avatar.is_a?(Paperclip::Storage::Fog)
97
+ end
98
+
99
+ context "when assigned" do
100
+ setup do
101
+ @file = File.new(fixture_file('5k.png'), 'rb')
102
+ @dummy = Dummy.new
103
+ @dummy.avatar = @file
104
+ end
105
+
106
+ teardown do
107
+ @file.close
108
+ directory = @connection.directories.new(:key => @fog_directory)
109
+ directory.files.each {|file| file.destroy}
110
+ directory.destroy
111
+ end
112
+
113
+ context "without a bucket" do
114
+ setup do
115
+ @connection.directories.get(@fog_directory).destroy
116
+ end
117
+
118
+ should "create the bucket" do
119
+ assert @dummy.save
120
+ assert @connection.directories.get(@fog_directory)
121
+ end
122
+ end
123
+
124
+ context "with a bucket" do
125
+ should "succeed" do
126
+ assert @dummy.save
127
+ end
128
+ end
129
+
130
+ context "without a fog_host" do
131
+ setup do
132
+ rebuild_model(@options.merge(:fog_host => nil))
133
+ @dummy = Dummy.new
134
+ @dummy.avatar = StringIO.new('.')
135
+ @dummy.save
136
+ end
137
+
138
+ should "provide a public url" do
139
+ assert !@dummy.avatar.url.nil?
140
+ end
141
+ end
142
+
143
+ context "with a fog_host" do
144
+ setup do
145
+ rebuild_model(@options.merge(:fog_host => 'http://example.com'))
146
+ @dummy = Dummy.new
147
+ @dummy.avatar = StringIO.new('.')
148
+ @dummy.save
149
+ end
150
+
151
+ should "provide a public url" do
152
+ assert @dummy.avatar.url =~ /^http:\/\/example\.com\/avatars\/stringio\.txt\?\d*$/
153
+ end
154
+ end
155
+
156
+ context "with a fog_host that includes a wildcard placeholder" do
157
+ setup do
158
+ rebuild_model(
159
+ :fog_directory => @fog_directory,
160
+ :fog_credentials => @credentials,
161
+ :fog_host => 'http://img%d.example.com',
162
+ :path => ":attachment/:basename.:extension",
163
+ :storage => :fog
164
+ )
165
+ @dummy = Dummy.new
166
+ @dummy.avatar = StringIO.new('.')
167
+ @dummy.save
168
+ end
169
+
170
+ should "provide a public url" do
171
+ assert @dummy.avatar.url =~ /^http:\/\/img[0123]\.example\.com\/avatars\/stringio\.txt\?\d*$/
172
+ end
173
+ end
174
+
175
+ context "with fog_public set to false" do
176
+ setup do
177
+ rebuild_model(@options.merge(:fog_public => false))
178
+ @dummy = Dummy.new
179
+ @dummy.avatar = StringIO.new('.')
180
+ @dummy.save
181
+ end
182
+
183
+ should 'set the @fog_public instance variable to false' do
184
+ assert_equal false, @dummy.avatar.instance_variable_get('@options')[:fog_public]
185
+ assert_equal false, @dummy.avatar.fog_public
186
+ end
187
+ end
188
+
189
+ context "with a valid bucket name for a subdomain" do
190
+ should "provide an url in subdomain style" do
191
+ assert_match /^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png\?\d*$/, @dummy.avatar.url
192
+ end
193
+ end
194
+
195
+ context "with an invalid bucket name for a subdomain" do
196
+ setup do
197
+ rebuild_model(@options.merge(:fog_directory => "this_is_invalid"))
198
+ @dummy = Dummy.new
199
+ @dummy.avatar = @file
200
+ @dummy.save
201
+ end
202
+
203
+ should "not match the bucket-subdomain restrictions" do
204
+ invalid_subdomains = %w(this_is_invalid in iamareallylongbucketnameiamareallylongbucketnameiamareallylongbu invalid- inval..id inval-.id inval.-id -invalid 192.168.10.2)
205
+ invalid_subdomains.each do |name|
206
+ assert_no_match Paperclip::Storage::Fog::AWS_BUCKET_SUBDOMAIN_RESTRICTON_REGEX, name
207
+ end
208
+ end
209
+
210
+ should "provide an url in folder style" do
211
+ assert_match /^https:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png\?\d*$/, @dummy.avatar.url
212
+ end
213
+
214
+ end
215
+
216
+ end
217
+
218
+ end
219
+ end
@@ -0,0 +1,138 @@
1
+ require './test/helper'
2
+ require 'aws'
3
+
4
+ unless ENV["S3_BUCKET"].blank?
5
+ class S3LiveTest < Test::Unit::TestCase
6
+
7
+ context "Generating an expiring url on a nonexistant attachment" do
8
+ setup do
9
+ rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
10
+ :storage => :s3,
11
+ :bucket => ENV["S3_BUCKET"],
12
+ :path => ":class/:attachment/:id/:style.:extension",
13
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "fixtures", "s3.yml"))
14
+
15
+ @dummy = Dummy.new
16
+ end
17
+ should "return nil" do
18
+ assert_nil @dummy.avatar.expiring_url
19
+ end
20
+ end
21
+
22
+ context "Using S3 for real, an attachment with S3 storage" do
23
+ setup do
24
+ rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
25
+ :storage => :s3,
26
+ :bucket => ENV["S3_BUCKET"],
27
+ :path => ":class/:attachment/:id/:style.:extension",
28
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "fixtures", "s3.yml"))
29
+
30
+ Dummy.delete_all
31
+ @dummy = Dummy.new
32
+ end
33
+
34
+ should "be extended by the S3 module" do
35
+ assert Dummy.new.avatar.is_a?(Paperclip::Storage::S3)
36
+ end
37
+
38
+ context "when assigned" do
39
+ setup do
40
+ @file = File.new(fixture_file('5k.png'), 'rb')
41
+ @dummy.avatar = @file
42
+ end
43
+
44
+ teardown do
45
+ @file.close
46
+ @dummy.destroy
47
+ end
48
+
49
+ should "still return a Tempfile when sent #to_file" do
50
+ assert_equal Paperclip::Tempfile, @dummy.avatar.to_file.class
51
+ end
52
+
53
+ context "and saved" do
54
+ setup do
55
+ @dummy.save
56
+ end
57
+
58
+ should "be on S3" do
59
+ assert true
60
+ end
61
+
62
+ should "generate a tempfile with the right name" do
63
+ file = @dummy.avatar.to_file
64
+ assert_match /^original.*\.png$/, File.basename(file.path)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ context "An attachment that uses S3 for storage and has spaces in file name" do
71
+ setup do
72
+ rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
73
+ :storage => :s3,
74
+ :bucket => ENV["S3_BUCKET"],
75
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "fixtures", "s3.yml"))
76
+
77
+ Dummy.delete_all
78
+ @dummy = Dummy.new
79
+ @dummy.avatar = File.new(fixture_file('spaced file.png'), 'rb')
80
+ @dummy.save
81
+ end
82
+
83
+ should "return an unescaped version for path" do
84
+ assert_match /.+\/spaced file\.png/, @dummy.avatar.path
85
+ end
86
+
87
+ should "return an escaped version for url" do
88
+ assert_match /.+\/spaced%20file\.png/, @dummy.avatar.url
89
+ end
90
+
91
+ should "be accessible" do
92
+ assert_success_response @dummy.avatar.url
93
+ end
94
+
95
+ should "be destoryable" do
96
+ url = @dummy.avatar.url
97
+ @dummy.destroy
98
+ assert_not_found_response url
99
+ end
100
+ end
101
+
102
+ context "An attachment that uses S3 for storage and has a question mark in file name" do
103
+ setup do
104
+ rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
105
+ :storage => :s3,
106
+ :bucket => ENV["S3_BUCKET"],
107
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "fixtures", "s3.yml"))
108
+
109
+ Dummy.delete_all
110
+ @dummy = Dummy.new
111
+ @dummy.avatar = File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', 'question?mark.png'), 'rb')
112
+ @dummy.save
113
+ end
114
+
115
+ should "return an unescaped version for path" do
116
+ assert_match /.+\/question\?mark\.png/, @dummy.avatar.path
117
+ end
118
+
119
+ should "return an escaped version for url" do
120
+ assert_match /.+\/question%3Fmark\.png/, @dummy.avatar.url
121
+ end
122
+
123
+ should "be accessible" do
124
+ assert_success_response @dummy.avatar.url
125
+ end
126
+
127
+ should "be accessible with an expiring url" do
128
+ assert_success_response @dummy.avatar.expiring_url
129
+ end
130
+
131
+ should "be destroyable" do
132
+ url = @dummy.avatar.url
133
+ @dummy.destroy
134
+ assert_not_found_response url
135
+ end
136
+ end
137
+ end
138
+ end