The blog of Rahoul Baruah from 3hv Ltd

What's going on?

My name is Rahoul Baruah (aka Baz) and I'm a software developer in Leeds (England).

This is a log of things I've discovered while writing software in Ruby on Rails. In other words, geek stuff.

However, I've decided to put this blog on ice - I would ask you to check out my business blog here (or subscribe here).

16 April, 2007

form_test_helper and AJAX

I have been using Jason Garber's form_test_helper plugin. Basically, if you've ever had it where you rename a parameter in a form - change your test accordingly (post :action, :id => 1, :name => 'George' becoming post :action, :id => 1, :first_name => 'George') and forget to update your view, form_test_helper is for you. Instead you ask your controller to render your form and then call submit_form, supplying it the parameters you want. It parses your form, looks for the fields and then submits it to the Url embedded in the form tag. So the above would fail unless you actually had a field named first_name in your UI. Anyway, I thoroughly recommend it for avoiding embarrassing bugs.

However, it does not work with xhr requests. So, in Jason's absence (he's away at the moment), I'll show you the changes needed here. It's nowhere near complete but it does the trick for me.

Grab the plugin and edit vendor/plugins/form_test_helper/lib/form_test_helper.rb.

Around line 444-ish:


# Alias for select_form when called with a block.
# Shortcut for select_form(name).submit(args) without block.
def submit_form(*args, &block)
@ix_xhr = false
internal_submit_form(*args, &block)
end

# As submit_form but sends an XHR request
def submit_form_xhr(*args, &block)
@ix_xhr = true
internal_submit_form(*args, &block)
end

def internal_submit_form(*args, &block)
if block_given?
select_form(*args, &block)
else
selector = args[0].is_a?(Hash) ? nil : args.shift
select_form(selector).submit(*args)
end
end


And around line 480-ish:


def make_request(method, path, params={}, referring_uri=nil)
if self.kind_of?(ActionController::IntegrationTest)
self.send(method, path, params.stringify_keys, {:referer => referring_uri})
else
params.merge!(ActionController::Routing::Routes.recognize_path(path, :method => method))
if params[:controller] && params[:controller] != current_controller = self.instance_eval("@controller").controller_name
raise "Can't follow links outside of current controller (from #{current_controller} to #{params[:controller]})"
end
self.instance_eval("@request").env["HTTP_REFERER"] ||= referring_uri # facilitate testing of redirect_to :back
if @is_xhr
self.xhr(method, params.delete(:action), params.stringify_keys)
else
self.send(method, params.delete(:action), params.stringify_keys)
end
end
end


As I say, it's a bit of an ugly hack but it works for me. I will submit it to Jason once I have tidied it up.

1 comment:

Anonymous said...

Eagerly looking forward to your contribution!
Jason

eXTReMe Tracker