ruby-on-railsrubytestingwebrat

How do I catch redirections to other domains when testing with Webrat?


In my Rails app, I have a form which redirects through a foreign service, Amazon FPS. The form POSTs to an action in my app which redirects to Amazon, who collect information and then redirect back to my app.

I'm testing this workflow with Webrat. Obviously I can't test Amazon, so I want to check that the redirection to Amazon happens and then simulate Amazon's redirection back into my app, effectively mocking out Amazon from the test.

However, when Webrat submits the form, it calls ActionController::Integration::Session#request_via_redirect, which follows all redirections until it gets a response which is not a redirect. This includes the redirect to Amazon. Rails ignores the domain and requests the path from the local app, which fails.

What I'm looking for is a way to stop Webrat/Rails from making requests for URLs on other domains and allowing me to verify the redirection.


Solution

  • Solution: make my own way.

    class ActionController::Integration::Session
      # Intercepts a request to a foreign domain.  Use this to stub
      # a service which the user is bounced through, such as an
      # OpenID provider.  The block should return a new URL to
      # request.  This is the URL which the foreign service would
      # redirect the browser to if we were really using it.
      # 
      # Currently, the return URL can only be requested with a GET.
      # 
      #   stub_request 'foreign.host.com' do |path|
      #     return_from_bounce_url
      #   end
      def stub_request(host, &block)
        @request_stubs ||= {}
        @request_stubs[host] = block
      end
    
      def process_with_stubs(method, path, parameters = nil, headers = nil)
        @request_stubs ||= {}
    
        if @request_stubs.key? self.host
          url = @request_stubs[host].call(path)
          process_without_stubs(method, url, parameters, headers)
        else
          process_without_stubs(method, path, parameters, headers)
        end
      end
      alias_method_chain :process, :stubs
    end