carrierwave_direct 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +2 -0
- data/Changelog.md +94 -0
- data/Gemfile +1 -1
- data/README.md +53 -41
- data/lib/carrierwave_direct.rb +5 -6
- data/lib/carrierwave_direct/form_builder.rb +46 -11
- data/lib/carrierwave_direct/locale/nl.yml +9 -0
- data/lib/carrierwave_direct/test/capybara_helpers.rb +3 -3
- data/lib/carrierwave_direct/uploader.rb +75 -68
- data/lib/carrierwave_direct/uploader/configuration.rb +4 -2
- data/lib/carrierwave_direct/uploader/content_type.rb +28 -0
- data/lib/carrierwave_direct/uploader/direct_url.rb +18 -0
- data/lib/carrierwave_direct/validations/active_model.rb +2 -1
- data/lib/carrierwave_direct/version.rb +1 -1
- data/spec/action_view_extensions/form_helper_spec.rb +4 -5
- data/spec/data/sample_data.rb +40 -0
- data/spec/form_builder_spec.rb +139 -6
- data/spec/mount_spec.rb +13 -26
- data/spec/orm/activerecord_spec.rb +23 -4
- data/spec/support/form_builder_helpers.rb +1 -0
- data/spec/support/model_helpers.rb +7 -7
- data/spec/support/view_helpers.rb +11 -1
- data/spec/test/capybara_helpers_spec.rb +27 -24
- data/spec/test/helpers_spec.rb +9 -11
- data/spec/uploader/configuration_spec.rb +46 -0
- data/spec/uploader/content_type_spec.rb +40 -0
- data/spec/uploader/direct_url_spec.rb +56 -0
- data/spec/uploader_spec.rb +130 -169
- metadata +35 -23
@@ -1,7 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module CarrierWaveDirect
|
4
|
-
|
5
4
|
module Uploader
|
6
5
|
module Configuration
|
7
6
|
extend ActiveSupport::Concern
|
@@ -16,7 +15,10 @@ module CarrierWaveDirect
|
|
16
15
|
add_config :min_file_size
|
17
16
|
add_config :max_file_size
|
18
17
|
add_config :upload_expiration
|
19
|
-
|
18
|
+
|
19
|
+
add_config :will_include_content_type #alias for default_content_type
|
20
|
+
add_config :default_content_type
|
21
|
+
add_config :allowed_content_types
|
20
22
|
|
21
23
|
add_config :use_action_status
|
22
24
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CarrierWaveDirect
|
2
|
+
module Uploader
|
3
|
+
module ContentType
|
4
|
+
|
5
|
+
def content_type
|
6
|
+
default_content_type ? default_content_type : 'binary/octet-stream'
|
7
|
+
end
|
8
|
+
|
9
|
+
def content_types
|
10
|
+
types = allowed_content_types
|
11
|
+
|
12
|
+
return types if types.is_a? Array
|
13
|
+
|
14
|
+
%w(application/atom+xml application/ecmascript application/json
|
15
|
+
application/javascript application/octet-stream application/ogg
|
16
|
+
application/pdf application/postscript application/rss+xml
|
17
|
+
application/font-woff application/xhtml+xml application/xml
|
18
|
+
application/xml-dtd application/zip application/gzip audio/basic
|
19
|
+
audio/mp4 audio/mpeg audio/ogg audio/vorbis audio/vnd.rn-realaudio
|
20
|
+
audio/vnd.wave audio/webm image/gif image/jpeg image/pjpeg
|
21
|
+
image/png image/svg+xml image/tiff text/cmd text/css text/csv
|
22
|
+
text/html text/javascript text/plain text/vcard text/xml video/mpeg
|
23
|
+
video/mp4 video/ogg video/quicktime video/webm video/x-matroska
|
24
|
+
video/x-ms-wmv video/x-flv)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CarrierWaveDirect
|
2
|
+
module Uploader
|
3
|
+
module DirectUrl
|
4
|
+
|
5
|
+
def direct_fog_url(options = {})
|
6
|
+
fog_uri = CarrierWave::Storage::Fog::File.new(self, CarrierWave::Storage::Fog.new(self), nil).public_url
|
7
|
+
if options[:with_path]
|
8
|
+
uri = URI.parse(fog_uri.chomp('/'))
|
9
|
+
path = "/#{URI.decode(key)}"
|
10
|
+
uri.path += URI.escape(path)
|
11
|
+
fog_uri = uri.to_s
|
12
|
+
end
|
13
|
+
fog_uri
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -12,7 +12,8 @@ module CarrierWaveDirect
|
|
12
12
|
class UniqueFilenameValidator < ::ActiveModel::EachValidator
|
13
13
|
def validate_each(record, attribute, value)
|
14
14
|
if record.new_record? && record.errors[attribute].empty? && (record.send("has_#{attribute}_upload?") || record.send("has_remote_#{attribute}_net_url?"))
|
15
|
-
|
15
|
+
column = record.class.uploader_options[attribute].fetch(:mount_on, attribute)
|
16
|
+
if record.class.where(column => record.send(attribute).filename).exists?
|
16
17
|
record.errors.add(attribute, :carrierwave_direct_filename_taken)
|
17
18
|
end
|
18
19
|
end
|
@@ -8,28 +8,27 @@ describe CarrierWaveDirect::ActionViewExtensions::FormHelper do
|
|
8
8
|
describe "#direct_upload_form_for" do
|
9
9
|
it "should yield an instance of CarrierWaveDirect::FormBuilder" do
|
10
10
|
direct_upload_form_for(direct_uploader) do |f|
|
11
|
-
f.
|
11
|
+
expect(f).to be_instance_of(CarrierWaveDirect::FormBuilder)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
context "the form" do
|
16
16
|
before do
|
17
|
-
direct_uploader.
|
17
|
+
allow(direct_uploader).to receive(:direct_fog_url).and_return("http://example.com")
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should post to the uploader's #direct_fog_url as a multipart form" do
|
21
|
-
form.
|
21
|
+
expect(form).to submit_to(
|
22
22
|
:action => "http://example.com", :method => "post", :enctype => "multipart/form-data"
|
23
23
|
)
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should include any html options passed as through :html" do
|
27
|
-
form(:html => { :target => "_blank_iframe" }).
|
27
|
+
expect(form(:html => { :target => "_blank_iframe" })).to submit_to(
|
28
28
|
:action => "http://example.com", :method => "post", :enctype => "multipart/form-data", :target => "_blank_iframe"
|
29
29
|
)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
34
33
|
end
|
35
34
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
SAMPLE_DATA = {
|
2
|
+
:path => "upload_dir/bliind.exe",
|
3
|
+
:path_with_special_chars => "upload_dir/some file & blah.exe",
|
4
|
+
:path_with_escaped_chars => "upload_dir/some%20file%20&%20blah.exe",
|
5
|
+
:key => "some key",
|
6
|
+
:guid => "guid",
|
7
|
+
:store_dir => "store_dir",
|
8
|
+
:extension_regexp => "(avi)",
|
9
|
+
:url => "http://example.com/some_url",
|
10
|
+
:expiration => 60,
|
11
|
+
:min_file_size => 1024,
|
12
|
+
:max_file_size => 10485760,
|
13
|
+
:file_url => "http://anyurl.com/any_path/video_dir/filename.avi",
|
14
|
+
:mounted_model_name => "Porno",
|
15
|
+
:mounted_as => :video,
|
16
|
+
:filename => "filename",
|
17
|
+
:extension => ".avi",
|
18
|
+
:version => :thumb,
|
19
|
+
:s3_bucket_url => "https://s3-bucket.s3.amazonaws.com"
|
20
|
+
}
|
21
|
+
|
22
|
+
SAMPLE_DATA.merge!(
|
23
|
+
:stored_filename_base => "#{sample(:guid)}/#{sample(:filename)}"
|
24
|
+
)
|
25
|
+
|
26
|
+
SAMPLE_DATA.merge!(
|
27
|
+
:stored_filename => "#{sample(:stored_filename_base)}#{sample(:extension)}",
|
28
|
+
:stored_version_filename => "#{sample(:stored_filename_base)}_#{sample(:version)}#{sample(:extension)}"
|
29
|
+
)
|
30
|
+
|
31
|
+
SAMPLE_DATA.merge!(
|
32
|
+
:s3_key => "#{sample(:store_dir)}/#{sample(:stored_filename)}"
|
33
|
+
)
|
34
|
+
|
35
|
+
SAMPLE_DATA.merge!(
|
36
|
+
:s3_file_url => "#{sample(:s3_bucket_url)}/#{sample(:s3_key)}"
|
37
|
+
)
|
38
|
+
|
39
|
+
SAMPLE_DATA.freeze
|
40
|
+
|
data/spec/form_builder_spec.rb
CHANGED
@@ -1,6 +1,45 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
class CarrierWaveDirect::FormBuilder
|
7
|
+
attr_accessor :template, :object
|
8
|
+
|
9
|
+
public :content_choices_options
|
10
|
+
end
|
11
|
+
|
12
|
+
shared_examples_for 'hidden values form' do
|
13
|
+
hidden_fields = [
|
14
|
+
:key,
|
15
|
+
{:aws_access_key_id => "AWSAccessKeyId"},
|
16
|
+
:acl,
|
17
|
+
:success_action_redirect,
|
18
|
+
:policy,
|
19
|
+
:signature
|
20
|
+
]
|
21
|
+
|
22
|
+
hidden_fields.each do |input|
|
23
|
+
if input.is_a?(Hash)
|
24
|
+
key = input.keys.first
|
25
|
+
name = input[key]
|
26
|
+
else
|
27
|
+
key = name = input
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have a hidden field for '#{name}'" do
|
31
|
+
allow(direct_uploader).to receive(key).and_return(key.to_s)
|
32
|
+
expect(subject).to have_input(
|
33
|
+
:direct_uploader,
|
34
|
+
key,
|
35
|
+
:type => :hidden,
|
36
|
+
:name => name,
|
37
|
+
:value => key,
|
38
|
+
:required => false
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
4
43
|
|
5
44
|
describe CarrierWaveDirect::FormBuilder do
|
6
45
|
include FormBuilderHelpers
|
@@ -12,7 +51,11 @@ describe CarrierWaveDirect::FormBuilder do
|
|
12
51
|
end
|
13
52
|
|
14
53
|
def form_with_file_field_and_no_redirect
|
15
|
-
|
54
|
+
allow(@direct_uploader.class).to receive(:use_action_status).and_return(true)
|
55
|
+
|
56
|
+
form do |f|
|
57
|
+
f.file_field :video
|
58
|
+
end
|
16
59
|
end
|
17
60
|
|
18
61
|
default_hidden_fields = [
|
@@ -34,6 +77,8 @@ describe CarrierWaveDirect::FormBuilder do
|
|
34
77
|
|
35
78
|
# http://aws.amazon.com/articles/1434?_encoding=UTF8
|
36
79
|
context "form" do
|
80
|
+
let(:subject) {form_with_default_file_field}
|
81
|
+
it_should_behave_like 'hidden values form'
|
37
82
|
|
38
83
|
default_hidden_fields.each do |input|
|
39
84
|
if input.is_a?(Hash)
|
@@ -44,8 +89,8 @@ describe CarrierWaveDirect::FormBuilder do
|
|
44
89
|
end
|
45
90
|
|
46
91
|
it "should have a hidden field for '#{name}'" do
|
47
|
-
direct_uploader.
|
48
|
-
form_with_default_file_field.
|
92
|
+
allow(direct_uploader).to receive(key).and_return(key.to_s)
|
93
|
+
expect(form_with_default_file_field).to have_input(
|
49
94
|
:direct_uploader,
|
50
95
|
key,
|
51
96
|
:type => :hidden,
|
@@ -65,8 +110,8 @@ describe CarrierWaveDirect::FormBuilder do
|
|
65
110
|
end
|
66
111
|
|
67
112
|
it "should have a hidden field for '#{name}'" do
|
68
|
-
direct_uploader.
|
69
|
-
form_with_file_field_and_no_redirect.
|
113
|
+
allow(direct_uploader).to receive(key).and_return(key.to_s)
|
114
|
+
expect(form_with_file_field_and_no_redirect).to have_input(
|
70
115
|
:direct_uploader,
|
71
116
|
key,
|
72
117
|
:type => :hidden,
|
@@ -78,7 +123,7 @@ describe CarrierWaveDirect::FormBuilder do
|
|
78
123
|
end
|
79
124
|
|
80
125
|
it "should have an input for a file to upload" do
|
81
|
-
form_with_default_file_field.
|
126
|
+
expect(form_with_default_file_field).to have_input(
|
82
127
|
:direct_uploader,
|
83
128
|
:video,
|
84
129
|
:type => :file,
|
@@ -88,4 +133,92 @@ describe CarrierWaveDirect::FormBuilder do
|
|
88
133
|
end
|
89
134
|
end
|
90
135
|
end
|
136
|
+
|
137
|
+
describe "#content_type_select" do
|
138
|
+
context "form" do
|
139
|
+
let(:subject) do
|
140
|
+
form do |f|
|
141
|
+
f.content_type_select
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
before do
|
146
|
+
allow(direct_uploader.class).to receive(:will_include_content_type).and_return(true)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should select the default content type' do
|
150
|
+
allow(direct_uploader).to receive(:content_type).and_return('video/mp4')
|
151
|
+
expect(subject).to have_content_type 'video/mp4', true
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should include the default content types' do
|
155
|
+
allow(direct_uploader).to receive(:content_types).and_return(['text/foo','text/bar'])
|
156
|
+
expect(subject).to have_content_type 'text/foo', false
|
157
|
+
expect(subject).to have_content_type 'text/bar', false
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should select the passed in content type' do
|
161
|
+
dom = form {|f| f.content_type_select nil, 'video/mp4'}
|
162
|
+
expect(dom).to have_content_type 'video/mp4', true
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should include most content types' do
|
166
|
+
%w(application/atom+xml application/ecmascript application/json application/javascript application/octet-stream application/ogg application/pdf application/postscript application/rss+xml application/font-woff application/xhtml+xml application/xml application/xml-dtd application/zip application/gzip audio/basic audio/mp4 audio/mpeg audio/ogg audio/vorbis audio/vnd.rn-realaudio audio/vnd.wave audio/webm image/gif image/jpeg image/pjpeg image/png image/svg+xml image/tiff text/cmd text/css text/csv text/html text/javascript text/plain text/vcard text/xml video/mpeg video/mp4 video/ogg video/quicktime video/webm video/x-matroska video/x-ms-wmv video/x-flv).each do |type|
|
167
|
+
expect(subject).to have_content_type type
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "#content_type_label" do
|
174
|
+
context "form" do
|
175
|
+
let(:subject) do
|
176
|
+
form do |f|
|
177
|
+
f.content_type_label
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe 'full form' do
|
185
|
+
let(:dom) do
|
186
|
+
form do |f|
|
187
|
+
f.content_type_label <<
|
188
|
+
f.content_type_select <<
|
189
|
+
f.file_field(:video)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
before do
|
194
|
+
allow(direct_uploader).to receive('key').and_return('foo')
|
195
|
+
allow(direct_uploader.class).to receive(:will_include_content_type).and_return(true)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should only include the hidden values once' do
|
199
|
+
expect(dom).to have_input(
|
200
|
+
:direct_uploader,
|
201
|
+
'key',
|
202
|
+
:type => :hidden,
|
203
|
+
:name => 'key',
|
204
|
+
:value => 'foo',
|
205
|
+
:required => false,
|
206
|
+
:count => 1
|
207
|
+
)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should include Content-Type twice' do
|
211
|
+
expect(dom).to have_input(
|
212
|
+
:direct_uploader,
|
213
|
+
:content_type,
|
214
|
+
:type => :hidden,
|
215
|
+
:name => 'Content-Type',
|
216
|
+
:value => 'binary/octet-stream',
|
217
|
+
:required => false,
|
218
|
+
:count => 1
|
219
|
+
)
|
220
|
+
|
221
|
+
expect(dom).to have_selector :xpath, './/select[@name="Content-Type"]', :count => 1
|
222
|
+
end
|
223
|
+
end
|
91
224
|
end
|
data/spec/mount_spec.rb
CHANGED
@@ -17,43 +17,30 @@ describe CarrierWaveDirect::Mount do
|
|
17
17
|
it_should_have_accessor(:remote_video_net_url)
|
18
18
|
|
19
19
|
describe "#has_video_upload?" do
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
it "should return false" do
|
24
|
-
subject.should_not have_video_upload
|
25
|
-
end
|
20
|
+
it "returns false when video does not have a key" do
|
21
|
+
allow(subject.video).to receive(:has_key?).and_return(false)
|
22
|
+
expect(subject).to_not have_video_upload
|
26
23
|
end
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
it "should return true" do
|
32
|
-
subject.should have_video_upload
|
33
|
-
end
|
25
|
+
it "returns true when video has a key" do
|
26
|
+
allow(subject.video).to receive(:has_key?).and_return(true)
|
27
|
+
expect(subject).to have_video_upload
|
34
28
|
end
|
35
29
|
end
|
36
30
|
|
37
31
|
describe "#has_remote_video_net_url?" do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
it "should return false" do
|
42
|
-
subject.should_not have_remote_video_net_url
|
43
|
-
end
|
32
|
+
it "returns false when remote_video_net_url is nil" do
|
33
|
+
subject.remote_video_net_url = nil
|
34
|
+
expect(subject).to_not have_remote_video_net_url
|
44
35
|
end
|
45
36
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
it "should return true" do
|
50
|
-
subject.should have_remote_video_net_url
|
51
|
-
end
|
37
|
+
it "returns true when remote_video_net_url is not nil" do
|
38
|
+
subject.remote_video_net_url = :not_nil
|
39
|
+
expect(subject).to have_remote_video_net_url
|
52
40
|
end
|
53
41
|
end
|
54
42
|
|
55
|
-
it_should_delegate(:key, :to => "video#key", :accessible => {"has_video_upload?" => false})
|
56
|
-
|
43
|
+
it_should_delegate(:key, :to => "video#key", :accessible => { "has_video_upload?" => false })
|
57
44
|
end
|
58
45
|
end
|
59
46
|
|
@@ -15,10 +15,15 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
15
15
|
create_table :parties, :force => true do |t|
|
16
16
|
t.column :video, :string
|
17
17
|
end
|
18
|
+
|
19
|
+
create_table :dances, :force => true do |t|
|
20
|
+
t.column :location, :string
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
def self.down
|
21
25
|
drop_table :parties
|
26
|
+
drop_table :dances
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
@@ -26,6 +31,9 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
26
31
|
mount_uploader :video, DirectUploader
|
27
32
|
end
|
28
33
|
|
34
|
+
class Dance < ActiveRecord::Base
|
35
|
+
end
|
36
|
+
|
29
37
|
ActiveRecord::Base.establish_connection(dbconfig)
|
30
38
|
|
31
39
|
# turn off migration output
|
@@ -61,17 +69,17 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
61
69
|
|
62
70
|
shared_examples_for "an invalid filename" do
|
63
71
|
it "should not be valid on create" do
|
64
|
-
subject.
|
72
|
+
expect(subject).to_not be_valid
|
65
73
|
end
|
66
74
|
|
67
75
|
it "should be valid on update" do
|
68
76
|
subject.save(:validate => false)
|
69
|
-
subject.
|
77
|
+
expect(subject).to be_valid
|
70
78
|
end
|
71
79
|
|
72
80
|
it "should use i18n for the error messages" do
|
73
81
|
subject.valid?
|
74
|
-
subject.errors[:video].
|
82
|
+
expect(subject.errors[:video]).to eq [
|
75
83
|
I18n.t("errors.messages.carrierwave_direct_filename_invalid") +
|
76
84
|
I18n.t("errors.messages.carrierwave_direct_allowed_extensions", :extensions => %w{avi mp4}.to_sentence)
|
77
85
|
]
|
@@ -96,7 +104,7 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
96
104
|
end
|
97
105
|
end
|
98
106
|
|
99
|
-
subject.errors[:remote_video_net_url].
|
107
|
+
expect(subject.errors[:remote_video_net_url]).to eq [ messages ]
|
100
108
|
end
|
101
109
|
end
|
102
110
|
|
@@ -150,6 +158,17 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
150
158
|
mount_uploader
|
151
159
|
end
|
152
160
|
|
161
|
+
context "mount_on: option is used" do
|
162
|
+
let(:dance) { Dance.new }
|
163
|
+
|
164
|
+
before { Dance.mount_uploader(:non_existing_column, DirectUploader, mount_on: :location) }
|
165
|
+
before { dance.non_existing_column.key = sample_key}
|
166
|
+
|
167
|
+
it "uses the column it's mounted on for checking uniqueness" do
|
168
|
+
expect { dance.valid? }.to_not raise_error
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
153
172
|
context "another Party with a duplicate video filename" do
|
154
173
|
before do
|
155
174
|
subject.video.key = sample_key
|