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.

This entry was posted on Monday, April 16th, 2007 at 12:41 pm and is filed under Ruby on Rails and Software Development, Writing Reliable, Bug-Free Code. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

One Response to “form_test_helper and AJAX”

  1. Anonymous Says:

    Eagerly looking forward to your contribution!
    Jason

Leave a Reply