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