Skip to content
This repository
Browse code

Added form helper

  • Loading branch information...
commit f451be17a8f7449ac9f2145ced3b93a80dc2932b 1 parent 55dc6f6
David Wilkie authored
2  carrierwave_direct.gemspec
@@ -14,7 +14,6 @@ Gem::Specification.new do |s|
14 14 s.rubyforge_project = "carrierwave_direct"
15 15
16 16 s.add_dependency "carrierwave"
17   - s.add_dependency "activemodel"
18 17 s.add_dependency "uuid"
19 18 s.add_dependency "fog"
20 19
@@ -22,6 +21,7 @@ Gem::Specification.new do |s|
22 21 s.add_development_dependency "timecop"
23 22 s.add_development_dependency "rails"
24 23 s.add_development_dependency "sqlite3"
  24 + s.add_development_dependency "capybara"
25 25
26 26 s.files = `git ls-files`.split("\n")
27 27 s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
7 lib/carrierwave_direct.rb
@@ -30,6 +30,13 @@ class Railtie < Rails::Railtie
30 30 require 'carrierwave_direct/orm/activerecord'
31 31 end
32 32 end
  33 +
  34 + initializer "carrierwave_direct.action_view" do
  35 + ActiveSupport.on_load :action_view do
  36 + require 'carrierwave_direct/form_builder'
  37 + require 'carrierwave_direct/action_view_extensions/form_helper'
  38 + end
  39 + end
33 40 end
34 41 end
35 42 end
36 lib/carrierwave_direct/action_view_extensions/form_helper.rb
... ... @@ -0,0 +1,36 @@
  1 +# encoding: utf-8
  2 +
  3 +module CarrierWaveDirect
  4 +
  5 + module ActionViewExtensions
  6 + # This module creates direct upload forms to post to cloud services
  7 + #
  8 + # Example:
  9 + #
  10 + # direct_upload_form_for @video_uploader do |f|
  11 + # f.file_field :video
  12 + # f.submit
  13 + # end
  14 + #
  15 + module FormHelper
  16 +
  17 + def direct_upload_form_for(record, *args, &block)
  18 + options = args.extract_options!
  19 + form_for(
  20 + record,
  21 + *(args << options.merge(
  22 + :builder => CarrierWaveDirect::FormBuilder,
  23 + :url => record.direct_fog_url,
  24 + :html => {:multipart => true},
  25 + :authenticity_token => false,
  26 + :include_id => false
  27 + )),
  28 + &block
  29 + )
  30 + end
  31 + end
  32 + end
  33 +end
  34 +
  35 +ActionView::Base.send :include, CarrierWaveDirect::ActionViewExtensions::FormHelper
  36 +
17 lib/carrierwave_direct/form_builder.rb
... ... @@ -0,0 +1,17 @@
  1 +# encoding: utf-8
  2 +
  3 +module CarrierWaveDirect
  4 + class FormBuilder < ActionView::Helpers::FormBuilder
  5 + def file_field(method, options = {})
  6 + options.merge!(:name => "file")
  7 + hidden_field(:key, :name => "key") <<
  8 + hidden_field(:aws_access_key_id, :name => "AWSAccessKeyId") <<
  9 + hidden_field(:acl, :name => "acl") <<
  10 + hidden_field(:success_action_redirect, :name => "success_action_redirect") <<
  11 + hidden_field(:policy, :name => "policy") <<
  12 + hidden_field(:signature, :name => "signature") <<
  13 + super
  14 + end
  15 + end
  16 +end
  17 +
28 spec/action_view_extensions/form_helper_spec.rb
... ... @@ -0,0 +1,28 @@
  1 +# encoding: utf-8
  2 +
  3 +require 'spec_helper'
  4 +
  5 +describe CarrierWaveDirect::ActionViewExtensions::FormHelper do
  6 + include FormBuilderHelpers
  7 +
  8 + describe "#direct_upload_form_for" do
  9 + it "should yield an instance of CarrierWaveDirect::FormBuilder" do
  10 + direct_upload_form_for(direct_uploader) do |f|
  11 + f.should be_instance_of(CarrierWaveDirect::FormBuilder)
  12 + end
  13 + end
  14 +
  15 + context "the form" do
  16 + before do
  17 + direct_uploader.stub(:direct_fog_url).and_return("http://example.com")
  18 + end
  19 +
  20 + it "should post to the uploader's #direct_fog_url as a multipart form" do
  21 + form.should submit_to(
  22 + :action => "http://example.com", :method => "post", :enctype => "multipart/form-data"
  23 + )
  24 + end
  25 + end
  26 + end
  27 +end
  28 +
59 spec/form_builder_spec.rb
... ... @@ -0,0 +1,59 @@
  1 +# encoding: utf-8
  2 +
  3 +require 'spec_helper'
  4 +
  5 +describe CarrierWaveDirect::FormBuilder do
  6 + include FormBuilderHelpers
  7 +
  8 + describe "#file_field" do
  9 +
  10 + def form_with_file_field
  11 + form {|f| f.file_field :video }
  12 + end
  13 +
  14 + hidden_fields = [
  15 + :key,
  16 + {:aws_access_key_id => "AWSAccessKeyId"},
  17 + :acl,
  18 + :success_action_redirect,
  19 + :policy,
  20 + :signature
  21 + ]
  22 +
  23 + # http://aws.amazon.com/articles/1434?_encoding=UTF8
  24 + context "form" do
  25 +
  26 + hidden_fields.each do |input|
  27 + if input.is_a?(Hash)
  28 + key = input.keys.first
  29 + name = input[key]
  30 + else
  31 + key = name = input
  32 + end
  33 +
  34 + it "should have a hidden field for '#{name}'" do
  35 + direct_uploader.stub(key).and_return(key.to_s)
  36 + form_with_file_field.should have_input(
  37 + :direct_uploader,
  38 + key,
  39 + :type => :hidden,
  40 + :name => name,
  41 + :value => key,
  42 + :required => false
  43 + )
  44 + end
  45 + end
  46 +
  47 + it "should have an input for a file to upload" do
  48 + form_with_file_field.should have_input(
  49 + :direct_uploader,
  50 + :video,
  51 + :type => :file,
  52 + :name => :file,
  53 + :required => false
  54 + )
  55 + end
  56 + end
  57 + end
  58 +end
  59 +
36 spec/support/form_builder_helpers.rb
... ... @@ -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 +
45 spec/support/view_helpers.rb
... ... @@ -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 comments on commit f451be1

Please sign in to comment.
Something went wrong with that request. Please try again.