Confusion about HTTP header content during functional tests

When I look at this output, I end up with the following questions:

1) Why is the request showing the first request to /account/login
instead of the request to :get_template?

2) Why is the method on that request to /account/login showing as a GET
instead of a POST?

3) Why is the Location header on the response showing to be what it
would be right after a login?

Does your login method actually do a request? that would explain everything. @request, @response etc... are not reset if you perform multiple requests from a single functional test.

Fred

Frederick Cheung wrote:

3) Why is the Location header on the response showing to be what it
would be right after a login?

Does your login method actually do a request? that would explain
everything. @request, @response etc... are not reset if you perform
multiple requests from a single functional test.

Fred

Yeah it does. Here's the login method:

  def login(user = 'blah', password = 'blah')
    old_controller = @controller
    @controller = AccountController.new
    post :login, :login => user, :password => password
    assert_response(:redirect)
    assert_equal(flash[:notice], "Logged in successfully", "Should be
logged in.")
    @controller = old_controller
  end

Thanks, Fred. Just verifying.

Wes

Well you cab either create fresh controller/request/response objects,
or (what I would do) change your login helper to just fake up the
session to make it looked like the person is logged in (play with
@request.session )

I saw that you can just manipulate the session data to handle this, and
that is simpler.

But of course, I'm stubborn and I preferred the idea of actually "doing"
the login as part of the functional test.

I have worked around it, and here's the code that does it:

def login(user = 'blah', password = 'blah')
    old_controller = @controller
    @controller = AccountController.new
    post :login, :login => user, :password => password
    assert_response(:redirect)
    assert_equal(flash[:notice], "Logged in successfully", "Should be
logged in.")
    @controller = old_controller
    reset_request_and_response
  end

  #This allows the debug_request and debug_response methods to be used
in a multi-request functional test
  #and actually show the correct information.
  def reset_request_and_response
    #Store the current request
    @previous_request = @request

    #Make new request and response objects
    @controller.request = @request = ActionController::TestRequest.new
    @response = ActionController::TestResponse.new

    #Move the session data over so we don't lose any context.
    @previous_request.session.data.each do |k, v|
      @request.session[k] = v
    end
  end

The "login" method calls "reset_request_and_response" which creates a
new TestRequest and TestResponse and moves the session data over so
that, among other things, the request knows that it is still logged in.
Then the dumps of the request and response look correct given the
request that I'm really interested in.

Also, now you could have multi-request functional tests if you wanted to
(although strictly speaking, you probably shouldn't since each test
should test only one interaction).

Wes

Also, now you could have multi-request functional tests if you wanted to

Also known as an integration test :slight_smile:

Fred