carrierwave_direct 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +21 -0
  4. data/README.md +356 -0
  5. data/Rakefile +12 -0
  6. data/carrierwave_direct.gemspec +31 -0
  7. data/lib/carrierwave_direct.rb +44 -0
  8. data/lib/carrierwave_direct/action_view_extensions/form_helper.rb +36 -0
  9. data/lib/carrierwave_direct/form_builder.rb +17 -0
  10. data/lib/carrierwave_direct/locale/en.rb +20 -0
  11. data/lib/carrierwave_direct/locale/en.yml +7 -0
  12. data/lib/carrierwave_direct/mount.rb +38 -0
  13. data/lib/carrierwave_direct/orm/activerecord.rb +55 -0
  14. data/lib/carrierwave_direct/test/capybara_helpers.rb +58 -0
  15. data/lib/carrierwave_direct/test/helpers.rb +32 -0
  16. data/lib/carrierwave_direct/uploader.rb +142 -0
  17. data/lib/carrierwave_direct/uploader/configuration.rb +38 -0
  18. data/lib/carrierwave_direct/validations/active_model.rb +126 -0
  19. data/lib/carrierwave_direct/version.rb +6 -0
  20. data/spec/action_view_extensions/form_helper_spec.rb +28 -0
  21. data/spec/form_builder_spec.rb +59 -0
  22. data/spec/mount_spec.rb +57 -0
  23. data/spec/orm/activerecord_spec.rb +551 -0
  24. data/spec/spec_helper.rb +5 -0
  25. data/spec/support/carrier_wave_config.rb +9 -0
  26. data/spec/support/direct_uploader.rb +4 -0
  27. data/spec/support/form_builder_helpers.rb +36 -0
  28. data/spec/support/global_helpers.rb +6 -0
  29. data/spec/support/model_helpers.rb +80 -0
  30. data/spec/support/mounted_class.rb +6 -0
  31. data/spec/support/uploader_helpers.rb +8 -0
  32. data/spec/support/view_helpers.rb +45 -0
  33. data/spec/test/capybara_helpers_spec.rb +160 -0
  34. data/spec/test/helpers_spec.rb +105 -0
  35. data/spec/uploader_spec.rb +461 -0
  36. metadata +168 -0
@@ -0,0 +1,5 @@
1
+ require 'carrierwave_direct'
2
+ require 'json'
3
+ require 'timecop'
4
+ Dir[ File.dirname(__FILE__) << "/support/**/*.rb"].each {|file| require file }
5
+
@@ -0,0 +1,9 @@
1
+ CarrierWave.configure do |config|
2
+ config.fog_credentials = {
3
+ :provider => 'AWS',
4
+ :aws_access_key_id => 'AWS_ACCESS_KEY_ID',
5
+ :aws_secret_access_key => 'AWS_SECRET_ACCESS_KEY'
6
+ }
7
+ config.fog_directory = 'AWS_FOG_DIRECTORY' # bucket name
8
+ end
9
+
@@ -0,0 +1,4 @@
1
+ class DirectUploader < CarrierWave::Uploader::Base
2
+ include CarrierWaveDirect::Uploader
3
+ end
4
+
@@ -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,6 @@
1
+ GUID_REGEXP = "[a-f\\d\\-]+"
2
+
3
+ def sample(data)
4
+ SAMPLE_DATA[data]
5
+ end
6
+
@@ -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,6 @@
1
+ class MountedClass
2
+ extend CarrierWave::Mount
3
+ extend CarrierWaveDirect::Mount
4
+ mount_uploader :video, DirectUploader
5
+ end
6
+
@@ -0,0 +1,8 @@
1
+ module UploaderHelpers
2
+ include CarrierWaveDirect::Test::Helpers
3
+
4
+ def sample_key(options = {})
5
+ super(MountedClass.new.video, options)
6
+ end
7
+ end
8
+
@@ -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
+