carrierwave_direct 0.0.1
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.
- 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
|
+
|