提交 118a720a 编写于 作者: B Bob Remeika 提交者: Stefan Penner

Took first stab at reimplementing form_remote_tag helpers

上级 0955f579
......@@ -2,26 +2,41 @@ module ActionView
module Helpers
module AjaxHelper
include UrlHelper
def link_to_remote(name, url, options = {})
html = options.delete(:html) || {}
def form_remote_tag(options = {}, &block)
attributes = {}
attributes.merge!(extract_remote_attributes!(options))
attributes.merge!(options)
url = attributes.delete(:url)
form_tag(attributes.delete(:action) || url_for(url), attributes, &block)
end
def extract_remote_attributes!(options)
attributes = options.delete(:html) || {}
update = options.delete(:update)
if update.is_a?(Hash)
html["data-update-success"] = update[:success]
html["data-update-failure"] = update[:failure]
attributes["data-update-success"] = update[:success]
attributes["data-update-failure"] = update[:failure]
else
html["data-update-success"] = update
attributes["data-update-success"] = update
end
html["data-update-position"] = options.delete(:position)
html["data-method"] = options.delete(:method)
html["data-remote"] = "true"
html.merge!(options)
attributes["data-update-position"] = options.delete(:position)
attributes["data-method"] = options.delete(:method)
attributes["data-remote"] = true
attributes
end
def link_to_remote(name, url, options = {})
attributes = {}
attributes.merge!(extract_remote_attributes!(options))
attributes.merge!(options)
url = url_for(url) if url.is_a?(Hash)
link_to(name, url, html)
link_to(name, url, attributes)
end
def button_to_remote(name, options = {}, html_options = {})
......@@ -72,17 +87,6 @@ def observe_field(name, options = {})
SCRIPT
end
# TODO: Move to javascript helpers - BR
class JSFunction
def initialize(statements, *arguments)
@statements, @arguments = statements, arguments
end
def as_json(options = nil)
"function(#{@arguments.join(", ")}) {#{@statements}}"
end
end
module Rails2Compatibility
def set_callbacks(options, html)
[:complete, :failure, :success, :interactive, :loaded, :loading].each do |type|
......@@ -111,7 +115,20 @@ def button_to_remote(name, options = {}, html_options = {})
super
end
end
private
# TODO: Move to javascript helpers - BR
class JSFunction
def initialize(statements, *arguments)
@statements, @arguments = statements, arguments
end
def as_json(options = nil)
"function(#{@arguments.join(", ")}) {#{@statements}}"
end
end
end
end
end
\ No newline at end of file
......@@ -2,7 +2,22 @@
class AjaxTestCase < ActiveSupport::TestCase
include ActionView::Helpers::AjaxHelper
# TODO: Ask Katz: Should these be included by the AjaxHelper? - BR
include ActionView::Helpers::TagHelper
include ActionView::Helpers::FormTagHelper
# TODO: Replace with the real url_for method - BR
def url_for(url)
case url
when Hash
"/url/hash"
when String
url
else
raise TypeError.new("Unsupported url type (#{url.class}) for this test helper")
end
end
def assert_html(html, matches)
matches.each do |match|
......@@ -10,6 +25,12 @@ def assert_html(html, matches)
end
end
def assert_html_not_present(html, matches)
matches.each do |match|
assert_no_match Regexp.new(Regexp.escape(match)), html
end
end
def extract_json_from_data_element(data_element)
root = HTML::Document.new(data_element).root
script = root.find(:tag => "script")
......@@ -98,6 +119,108 @@ def link(options)
end
end
class FormRemoteTagTest < AjaxTestCase
def protect_against_forgery?
false
end
def request_forgery_protection_token
"token_name"
end
def form_authenticity_token
"t0k3n"
end
def authenticity_input_attributes
%w(input type="hidden" name="token_name" value="t0k3n")
end
# TODO: Play with using assert_dom_equal
test "basic" do
assert_html form_remote_tag(:update => "#glass_of_beer", :url => { :action => :fast }),
%w(form action="/url/hash" method="post" data-remote="true" data-update-success="#glass_of_beer")
end
test "when protect_against_forgery? is true" do
def protect_against_forgery?
true
end
expected_form_attributes = %w(form action="/url/hash" method="post" data-remote="true" data-update-success="#glass_of_beer")
expected_patterns = expected_form_attributes + authenticity_input_attributes
assert_equal true, protect_against_forgery?
assert_html form_remote_tag(:update => "#glass_of_beer", :url => { :action => :fast }), expected_patterns
end
test ":action is used when it is present" do
html = form_remote_tag(:update => "#glass_of_beer", :action => "foo")
assert_html html, %w(form action="foo" method="post" data-remote="true" data-update-success="#glass_of_beer")
assert_no_match /url="foo"/, html
end
test ":url is used when :action is not present" do
html = form_remote_tag(:update => "#glass_of_beer", :url => "bar")
assert_html html, %w(form action="bar" method="post" data-remote="true" data-update-success="#glass_of_beer")
assert_no_match /url="bar"/, html
end
test "when protect_against_forgery? is false" do
assert_equal false, protect_against_forgery?
assert_html_not_present form_remote_tag(:update => "#glass_of_beer", :url => { :action => :fast }),
authenticity_input_attributes
end
test "update callbacks" do
assert_html form_remote_tag(:update => { :success => "#glass_of_beer" }, :url => { :action => :fast }),
%w(form action="/url/hash" method="post" data-remote="true" data-update-success="#glass_of_beer")
assert_html form_remote_tag(:update => { :failure => "#glass_of_water" }, :url => { :action => :fast }),
%w(form action="/url/hash" method="post" data-remote="true" data-update-failure="#glass_of_water")
assert_html form_remote_tag(:update => { :success => "#glass_of_beer", :failure => "#glass_of_water" }, :url => { :action => :fast }),
%w(form action="/url/hash" method="post" data-remote="true" data-update-success="#glass_of_beer" data-update-failure="#glass_of_water")
end
test "using a :method option" do
expected_form_attributes = %w(form action="/url/hash" method="post" data-remote="true" data-update-success="#glass_of_beer")
# TODO: Ask Katz: Why does rails do this? Some web servers don't allow PUT or DELETE from what I remember... - BR
expected_input_attributes = %w(input name="_method" type="hidden" value="put")
assert_html form_remote_tag(:update => "#glass_of_beer", :url => { :action => :fast }, :html => { :method => :put }),
expected_form_attributes + expected_input_attributes
end
# FIXME: This test is janky as hell. We are essentially rewriting capture and concat and they don't really work right
# because output is out of order. This test passes because it's only doing a regex match on the buffer, but this really
# needs to be fixed by using the real helper methods that rails provides. capture, concat, url_for etc. should be
# implemented by their *real* methods or we need to find a better workaround so that our tests aren't written so
# poorly. - BR
test "form_remote_tag with block in erb" do
def capture(*args, &block)
@buffer = []
block.call(*args) if block_given?
end
def concat(str)
@buffer << str
end
expected_form_attributes = %w(form action="/url/hash" method="post" data-remote="true" data-update-success="#glass_of_beer" /form)
expected_inner_html = %w(w00t!)
form_remote_tag(:update => "#glass_of_beer", :url => { :action => :fast }) { concat expected_inner_html }
assert_html @buffer.to_s,
expected_form_attributes + expected_inner_html
end
end
class ButtonToRemoteTest < AjaxTestCase
def button(options, html = {})
button_to_remote("Remote outpost", options, html)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册