carrierwave_direct 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +356 -0
- data/Rakefile +12 -0
- data/carrierwave_direct.gemspec +31 -0
- data/lib/carrierwave_direct.rb +44 -0
- data/lib/carrierwave_direct/action_view_extensions/form_helper.rb +36 -0
- data/lib/carrierwave_direct/form_builder.rb +17 -0
- data/lib/carrierwave_direct/locale/en.rb +20 -0
- data/lib/carrierwave_direct/locale/en.yml +7 -0
- data/lib/carrierwave_direct/mount.rb +38 -0
- data/lib/carrierwave_direct/orm/activerecord.rb +55 -0
- data/lib/carrierwave_direct/test/capybara_helpers.rb +58 -0
- data/lib/carrierwave_direct/test/helpers.rb +32 -0
- data/lib/carrierwave_direct/uploader.rb +142 -0
- data/lib/carrierwave_direct/uploader/configuration.rb +38 -0
- data/lib/carrierwave_direct/validations/active_model.rb +126 -0
- data/lib/carrierwave_direct/version.rb +6 -0
- data/spec/action_view_extensions/form_helper_spec.rb +28 -0
- data/spec/form_builder_spec.rb +59 -0
- data/spec/mount_spec.rb +57 -0
- data/spec/orm/activerecord_spec.rb +551 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/carrier_wave_config.rb +9 -0
- data/spec/support/direct_uploader.rb +4 -0
- data/spec/support/form_builder_helpers.rb +36 -0
- data/spec/support/global_helpers.rb +6 -0
- data/spec/support/model_helpers.rb +80 -0
- data/spec/support/mounted_class.rb +6 -0
- data/spec/support/uploader_helpers.rb +8 -0
- data/spec/support/view_helpers.rb +45 -0
- data/spec/test/capybara_helpers_spec.rb +160 -0
- data/spec/test/helpers_spec.rb +105 -0
- data/spec/uploader_spec.rb +461 -0
- metadata +168 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'action_view'
|
4
|
+
require 'action_view/template'
|
5
|
+
|
6
|
+
require 'carrierwave_direct/form_builder'
|
7
|
+
require 'carrierwave_direct/action_view_extensions/form_helper'
|
8
|
+
|
9
|
+
module FormBuilderHelpers
|
10
|
+
include ActionView::Helpers::FormHelper
|
11
|
+
include CarrierWaveDirect::ActionViewExtensions::FormHelper
|
12
|
+
include ActionView::Context
|
13
|
+
include ActionController::RecordIdentifier
|
14
|
+
|
15
|
+
include ViewHelpers
|
16
|
+
|
17
|
+
def direct_uploader
|
18
|
+
defined?(super) ? super : @direct_uploader ||= MountedClass.new.video
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.included(base)
|
22
|
+
DirectUploader.send(:include, ActiveModel::Conversion)
|
23
|
+
DirectUploader.extend ActiveModel::Naming
|
24
|
+
end
|
25
|
+
|
26
|
+
def protect_against_forgery?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def form(&block)
|
31
|
+
blk = block_given? ? block : Proc.new {|f|}
|
32
|
+
direct_upload_form_for(direct_uploader, &blk)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module ModelHelpers
|
2
|
+
def self.included(base)
|
3
|
+
base.extend ClassMethods
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def it_should_be_accessible(name, sample_data, options = {})
|
8
|
+
describe "when initialized with .new(:#{name} => '#{sample_data}')" do
|
9
|
+
|
10
|
+
let(:accessor_value) do
|
11
|
+
subject.class.send(:new, { name => sample_data }).send(name)
|
12
|
+
end
|
13
|
+
|
14
|
+
if options[:accessible]
|
15
|
+
if options[:accessible] == true
|
16
|
+
it "should == '#{sample_data}'" do
|
17
|
+
accessor_value.should == sample_data
|
18
|
+
end
|
19
|
+
else
|
20
|
+
it "##{options[:accessible].keys.first} should be #{options[:accessible].values.first}" do
|
21
|
+
subject.send(options[:accessible].keys.first).should == options[:accessible].values.first
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
it "should be nil" do
|
26
|
+
accessor_value.should be_nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def it_should_delegate(name, options = {})
|
33
|
+
sample_data = "sample_#{name.to_s}"
|
34
|
+
delegation_object, delegation_method = options[:to].split("#")
|
35
|
+
|
36
|
+
describe "##{name} = '#{sample_data}'" do
|
37
|
+
it "should set the #{delegation_object}'s #{delegation_method}" do
|
38
|
+
subject.send("#{name}=", sample_data)
|
39
|
+
subject.send(delegation_object).send(delegation_method).should == sample_data
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "##{name}" do
|
44
|
+
it "should return the #{delegation_method} from the #{delegation_object}" do
|
45
|
+
subject.send(delegation_object).send("#{delegation_method}=", sample_data)
|
46
|
+
subject.send(name).should == sample_data
|
47
|
+
end
|
48
|
+
|
49
|
+
it_should_be_accessible(name, sample_data, options)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def it_should_have_accessor(name, options = {})
|
54
|
+
if name.is_a?(Hash)
|
55
|
+
key = name.keys.first
|
56
|
+
sample_data = name[key]
|
57
|
+
name = key
|
58
|
+
else
|
59
|
+
sample_data = "sample_#{name.to_s}"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should respond to ##{name}=" do
|
63
|
+
subject.should respond_to("#{name}=")
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "##{name}" do
|
67
|
+
context "where the #{name} is set to '#{sample_data}'" do
|
68
|
+
before { subject.send("#{name}=", sample_data) }
|
69
|
+
|
70
|
+
it "should == '#{sample_data}'" do
|
71
|
+
subject.send(name).should == sample_data
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it_should_be_accessible(name, sample_data, options)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'capybara/rspec'
|
2
|
+
|
3
|
+
module ViewHelpers
|
4
|
+
include Capybara::RSpecMatchers
|
5
|
+
|
6
|
+
def parent_selector
|
7
|
+
defined?(super) ? super : @parent_selector ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def have_parent_selector(options = {})
|
11
|
+
have_selector(:xpath, parent_selector_xpath, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def parent_selector_xpath
|
15
|
+
xpath = parent_selector.join("/")
|
16
|
+
xpath = ".//#{xpath}" unless xpath[0..2] == ".//"
|
17
|
+
xpath
|
18
|
+
end
|
19
|
+
|
20
|
+
def submit_to(options = {})
|
21
|
+
xpath_attributes = to_xpath_attributes(options)
|
22
|
+
parent_selector << "form[#{xpath_attributes}]"
|
23
|
+
have_parent_selector
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_xpath_attributes(options = {})
|
27
|
+
attributes = []
|
28
|
+
|
29
|
+
options.each do |key, value|
|
30
|
+
attributes << ((value == false) ? "not(@#{key})" : "@#{key}='#{value}'")
|
31
|
+
end
|
32
|
+
|
33
|
+
attributes.join(" and ")
|
34
|
+
end
|
35
|
+
|
36
|
+
def have_input(resource_name, input, options = {})
|
37
|
+
options[:type] ||= input
|
38
|
+
options[:id] ||= "#{resource_name}_#{input}"
|
39
|
+
options[:name] ||= "#{resource_name}[#{input}]"
|
40
|
+
options[:required] ||= "required" unless options[:required] == false
|
41
|
+
parent_selector << "input[#{to_xpath_attributes(options)}]"
|
42
|
+
have_parent_selector
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe CarrierWaveDirect::Test::CapybaraHelpers do
|
6
|
+
class ExampleSpec
|
7
|
+
include CarrierWaveDirect::Test::CapybaraHelpers
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:subject) { ExampleSpec.new }
|
11
|
+
let(:page) { mock("Page").as_null_object }
|
12
|
+
let(:selector) { mock("Selector") }
|
13
|
+
|
14
|
+
def stub_page
|
15
|
+
subject.stub(:page).and_return(page)
|
16
|
+
end
|
17
|
+
|
18
|
+
def find_element_value(css, value)
|
19
|
+
page.stub(:find).with(css).and_return(selector)
|
20
|
+
selector.stub(:value).and_return(value)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#attach_file_for_direct_upload" do
|
24
|
+
context "'path/to/file.ext'" do
|
25
|
+
it "should attach a file with the locator => 'file'" do
|
26
|
+
subject.should_receive(:attach_file).with("file", "path/to/file.ext")
|
27
|
+
subject.attach_file_for_direct_upload "path/to/file.ext"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#upload_directly" do
|
33
|
+
let(:uploader) { DirectUploader.new }
|
34
|
+
|
35
|
+
def upload_directly(options = {})
|
36
|
+
options[:button_locator] ||= ""
|
37
|
+
button_locator = options.delete(:button_locator)
|
38
|
+
subject.upload_directly(uploader, button_locator, options)
|
39
|
+
end
|
40
|
+
|
41
|
+
def stub_common
|
42
|
+
stub_page
|
43
|
+
find_element_value("input[@name='success_action_redirect']", "http://example.com")
|
44
|
+
subject.stub(:visit)
|
45
|
+
end
|
46
|
+
|
47
|
+
before do
|
48
|
+
subject.stub(:click_button)
|
49
|
+
end
|
50
|
+
|
51
|
+
shared_examples_for "submitting the form" do
|
52
|
+
let(:options) { {} }
|
53
|
+
|
54
|
+
it "should submit the form" do
|
55
|
+
subject.should_receive(:click_button).with("Upload!")
|
56
|
+
upload_directly(options.merge(:button_locator => "Upload!"))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
shared_examples_for ":success => false" do
|
61
|
+
let(:options) { { :success => false } }
|
62
|
+
|
63
|
+
it "should not redirect" do
|
64
|
+
subject.should_not_receive(:visit)
|
65
|
+
upload_directly(options)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "passing no options" do
|
70
|
+
before do
|
71
|
+
stub_common
|
72
|
+
subject.stub(:find_key).and_return("upload_dir/guid/$filename")
|
73
|
+
subject.stub(:find_upload_path).and_return("path/to/file.ext")
|
74
|
+
end
|
75
|
+
|
76
|
+
it_should_behave_like "submitting the form"
|
77
|
+
|
78
|
+
it "should redirect to the page's success_action_redirect url" do
|
79
|
+
subject.should_receive(:visit).with(/^http:\/\/example.com/)
|
80
|
+
upload_directly
|
81
|
+
end
|
82
|
+
|
83
|
+
context "the redirect url's params" do
|
84
|
+
it "should include the bucket name" do
|
85
|
+
subject.should_receive(:visit).with(/bucket=/)
|
86
|
+
upload_directly
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should include an etag" do
|
90
|
+
subject.should_receive(:visit).with(/etag=/)
|
91
|
+
upload_directly
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should include the key derived from the form" do
|
95
|
+
subject.should_receive(:visit).with(/key=upload_dir%2Fguid%2Ffile.ext/)
|
96
|
+
upload_directly
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "with options" do
|
102
|
+
context ":redirect_key => 'some redirect key'" do
|
103
|
+
before do
|
104
|
+
stub_common
|
105
|
+
end
|
106
|
+
|
107
|
+
context "the redirect url's params" do
|
108
|
+
it "should include the key from the :redirect_key option" do
|
109
|
+
subject.should_receive(:visit).with(/key=some\+redirect\+key/)
|
110
|
+
upload_directly(:redirect_key => "some redirect key")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context ":success => false" do
|
116
|
+
let(:options) { { :success => false } }
|
117
|
+
|
118
|
+
it_should_behave_like "submitting the form" do
|
119
|
+
let(:options) { { :success => false } }
|
120
|
+
end
|
121
|
+
|
122
|
+
it_should_behave_like ":success => false"
|
123
|
+
end
|
124
|
+
|
125
|
+
context ":fail => true" do
|
126
|
+
it_should_behave_like "submitting the form" do
|
127
|
+
let(:options) { { :fail => true } }
|
128
|
+
end
|
129
|
+
|
130
|
+
it_should_behave_like ":success => false" do
|
131
|
+
let(:options) { { :fail => true } }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#find_key" do
|
138
|
+
before do
|
139
|
+
stub_page
|
140
|
+
find_element_value("input[@name='key']", "key")
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should try to find the key on the page" do
|
144
|
+
subject.find_key.should == "key"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "#find_upload_path" do
|
149
|
+
before do
|
150
|
+
stub_page
|
151
|
+
find_element_value("input[@name='file']", "upload path")
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should try to find the upload path on the page" do
|
155
|
+
subject.find_upload_path.should == "upload path"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe CarrierWaveDirect::Test::Helpers do
|
6
|
+
include CarrierWaveDirect::Test::Helpers
|
7
|
+
|
8
|
+
describe "#sample_key" do
|
9
|
+
context "passing an instance of DirectUploader mounted as a video" do
|
10
|
+
let(:direct_uploader) { MountedClass.new.video }
|
11
|
+
|
12
|
+
context "where its extension white list returns" do
|
13
|
+
|
14
|
+
shared_examples_for "returning the default extension" do
|
15
|
+
it "should return '*/guid/filename.extension'" do
|
16
|
+
sample_key(direct_uploader).should =~ /#{GUID_REGEXP}\/filename\.extension$/
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "['exe', 'bmp']" do
|
21
|
+
before do
|
22
|
+
direct_uploader.stub(:extension_white_list).and_return(%w{exe bmp})
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return '*/guid/filename.exe'" do
|
26
|
+
sample_key(direct_uploader).should =~ /#{GUID_REGEXP}\/filename\.exe$/
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "[]" do
|
31
|
+
before do
|
32
|
+
direct_uploader.stub(:extension_white_list).and_return([])
|
33
|
+
end
|
34
|
+
|
35
|
+
it_should_behave_like "returning the default extension"
|
36
|
+
end
|
37
|
+
|
38
|
+
context "nil" do
|
39
|
+
before do
|
40
|
+
direct_uploader.stub(:extension_white_list).and_return(nil)
|
41
|
+
end
|
42
|
+
|
43
|
+
it_should_behave_like "returning the default extension"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
context "with no options" do
|
49
|
+
it "should return '*/guid/filename.extension'" do
|
50
|
+
sample_key(
|
51
|
+
direct_uploader,
|
52
|
+
).should =~ /#{GUID_REGEXP}\/filename\.extension$/
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with options" do
|
57
|
+
shared_examples_for "an invalid key" do
|
58
|
+
it "should return 'filename.extension'" do
|
59
|
+
key_parts = sample_key(direct_uploader, options).split("/")
|
60
|
+
key_parts.pop
|
61
|
+
key_parts.last.should_not =~ /^#{GUID_REGEXP}$/
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
shared_examples_for "a custom filename" do
|
66
|
+
it "should return '*/guid/some_file.reg'" do
|
67
|
+
sample_key(direct_uploader, options).should =~ /#{GUID_REGEXP}\/some_file\.reg$/
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context ":invalid => true" do
|
72
|
+
it_should_behave_like "an invalid key" do
|
73
|
+
let(:options) { { :invalid => true } }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context ":valid => false" do
|
78
|
+
it_should_behave_like "an invalid key" do
|
79
|
+
let(:options) { { :valid => false } }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context ":base => 'upload_dir/porno/movie/${filename}'" do
|
84
|
+
it "should return 'upload_dir/porno/movie/guid/filename.extension'" do
|
85
|
+
sample_key(
|
86
|
+
direct_uploader,
|
87
|
+
:base => "upload_dir/porno/movie/${filename}"
|
88
|
+
).should == "upload_dir/porno/movie/filename.extension"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
context ":filename => 'some_file.reg'" do
|
92
|
+
it_should_behave_like "a custom filename" do
|
93
|
+
let(:options) { { :filename => "some_file.reg" } }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
context ":filename => 'some_file', :extension => 'reg'" do
|
97
|
+
it_should_behave_like "a custom filename" do
|
98
|
+
let(:options) { { :filename => "some_file", :extension => "reg" } }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|