DRY act_as_authenticated functional testing

I’m using the acts_as_authenticated plug-in for my app. Now I need to
get my functional tests to work properly. I have not written functional
tests before so I’m unsure how to utilize setup so that all of my tests
can use the login. My tests pass if I put login_as :user inside of each
test, but that’s clearly not DRY. Can I add something to my
test_helper.rb file or create a def set in each functional test? Any
direction for this would be greatly appreciated.

Thanks.

On Jan 21, 2008, at 3:15 PM, Becca G. wrote:

Thanks.

You can either put the login_as in the setup method or have tests that
capture the behavior of not being logged in separately from the
behavior when the current user is already known. If you have some
authorization process (what a user is allowed to do) separate from the
authentication process (who is this user), then you may want to go
that route since you have three conditions: not authenticated (i.e.,
not logged in); authenticated, but unauthorized (e.g., normal user
accessing a privileged action); and authenticated and authorized.
(Note that someone can be authorized to do something even when not
authenticated such as signing up or seeing the login form.)

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

Rob B. wrote:

You can either put the login_as in the setup method or have tests that
capture the behavior of not being logged in separately from the
behavior when the current user is already known. If you have some
authorization process (what a user is allowed to do) separate from the
authentication process (who is this user), then you may want to go
that route since you have three conditions: not authenticated (i.e.,
not logged in); authenticated, but unauthorized (e.g., normal user
accessing a privileged action); and authenticated and authorized.
(Note that someone can be authorized to do something even when not
authenticated such as signing up or seeing the login form.)

Hi Rob -

Thanks for your help. I do have the authorization and authentication
processes separate from one another. I have:

def setup
login_as :quentin
end

But now the only way that I’m able to get this to work is if I include
this as the first line for all of my tests.

assert login_as(“quentin”)

If that assert line is missing, then my response changes from (:success)
to (302) - redirect.

Thanks!

On Jan 21, 2008, at 6:03 PM, Becca G. wrote:

accessing a privileged action); and authenticated and authorized.
end
Thanks!
You ought to have a bit more in your setup than that for a functional
test.

When I want to test both things, I have something like this (with
‘foo’ and ‘bar’ standing in for the application specific terms):

def test_foo_selection_on_restricted_bar
login_as :regular
get :foos, :id => 9
assert_redirected_to bar_url
end

def test_foo_selection_needs_login
get :foos, :id => 1
assert_response :redirect
end

def test_foo_selection
login_as :admin
get :foos, :id => 1
assert_response :success
end

When I just want to be logged in for every test, the setup looks like:

def setup
@controller = FoosController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
login_as :admin
end

It’s also possible that you have two definitions for setup and only
the last one is really having any effect (since its definition would
have overwritten the original one).

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

UPDATE:

Actually, I can comment out the def setup and as long as I leave in
assert login_as in each test, the tests pass. Something doesn’t seem
right.

Rob B. wrote:

You ought to have a bit more in your setup than that for a functional
test.

The tests are actually testing other controller functions, not the login
function. But I do have login tests. Is it possible to have the def
setup with the login_as :admin and also have tests that test the login.

For example I would want Test 1 - tests the login, Test 2 - tests the
controller function that needs the login.

If I have def setup with the login, will Test 1 then be useless or can I
set the login user to nil or something like that?

Thanks for all of your help!

I am also having a problem running functional tests and putting the
login_as in the setup method. I am on Rails 2.0.2 and trying to use:

def setup
super
login_as :dan
end

This does not work. In the controller being tested, current_user is
equal to :false.

However, if I put the login_as directly into each functional test
method, it works.

Anybody know why?

-Shannon

On Jan 21, 7:42 pm, Rob B. [email protected]

On Jan 21, 2008, at 7:53 PM, Becca G. wrote:

For example I would want Test 1 - tests the login, Test 2 - tests the
controller function that needs the login.

If I have def setup with the login, will Test 1 then be useless or
can I
set the login user to nil or something like that?

Thanks for all of your help!

The definition of login_as is in:
lib/authenticated_test_helper.rb

You get the effect of logging out with:
login_as nil

It can be immensely helpful to read the Ruby code that implements this
kind of thing. One reason is to see the answer to this kind of
question directly, but also you start to see how easy some of the
“magic” really is and start to craft some of your own.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

I have implemented this:

def setup
login_as :quentin
end

def test_should_get_new
get :new
assert_response :success
end

And get this error:
Expected response to be a <:success>, but was <302>

If I have the test as this it passes.
def test_should_get_new
assert login_as :quentin
get :new
assert_response :success
end

Sorry, I meant to write that I have this as def setup. I had copied and
pasted old code. Foos is replaced by name controller name

def setup
@controller = FoosController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
login_as :admin
end