# Functional tests and dealing with login before\_filter

**URL:** <https://www.ruby-forum.com/t/functional-tests-and-dealing-with-login-before-filter/53258>\
**Category:** Rails\
**Created:** [January 30, 2006, 6:13pm UTC](https://www.ruby-forum.com/t/functional-tests-and-dealing-with-login-before-filter/53258 "2006-01-30T18:13:39Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 30, 2006, 6:13pm UTC](https://www.ruby-forum.com/t/functional-tests-and-dealing-with-login-before-filter/53258/1 "2006-01-30T18:13:39Z")

</div>

Hi all,

I’m curious as to how you do functional testing on the controllers if,  
within  
the ApplicationController, I have a before\_filter :authorize, :except =\>  
:login, where the private authorize method checks for session[:user].

I can’t do “post :login”, because that method is in a different  
controller.

I tried setting session[:user] directly in the setup method, but that  
gave me  
strange errors:

fixtures :regions  
def setup  
…  
# I tried a few different things here…  
session[:user] = { :attributes =\> {:user =\> “foo”} }  
end

TypeError: Symbol as array index  
regions\_controller\_test.rb:16:in `[]=' regions_controller_test.rb:16:in`setup\_without\_fixtures’

/opt/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active\_record/fixtures.rb:523:in  
`setup’

Any advice appreciated.

Thanks,

Dan

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 30, 2006, 6:44pm UTC](https://www.ruby-forum.com/t/functional-tests-and-dealing-with-login-before-filter/53258/2 "2006-01-30T18:44:12Z")

</div>

On Jan 30, 2006, at 9:09 AM, Daniel B. wrote:

> fixtures :regions  
> def setup  
> …
> 
> # I tried a few different things here…
> 
> session[:user] = { :attributes =\> {:user =\> “foo”} }

For whatever reason the session object only works after a request,  
not before. Its totally lame.

I use a util\_set\_user method since some of my actions should behave  
differently for logged in and logged out people:

def util\_set\_user(user)  
@request.session[:userid] = user.id  
end

But you can also set the session on the third argument to get/post:

def process(action, parameters = nil, session = nil, flash = nil)

from actionpack/action\_controller/test\_process.rb

Wonderfully, its not documented in the api documentation as you would  
expect, but instead is buried in a manual under the unhelpful title  
“Testing Your Controllers: An Anatomy Lesson”.

[http://manuals.rubyonrails.com/read/chapter/28#page72](http://manuals.rubyonrails.com/read/chapter/28#page72)

–  
Eric H. - removed\_email\_address@domain.invalid - [http://segment7.net](http://segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 31, 2006, 3:19am UTC](https://www.ruby-forum.com/t/functional-tests-and-dealing-with-login-before-filter/53258/3 "2006-01-31T03:19:44Z")

</div>

On Mon, Jan 30, 2006 at 10:09:18AM -0700, Daniel B. wrote:

> I can’t do “post :login”, because that method is in a different controller.

Yeah, that’s a bit sucky. I handled it with this tasteless hack  
(wrapped in  
a login method in test\_helper.rb):

```
realctl = @controller
@controller = LoginController.new
post :index, { 'loginname' => user, 'password' => pass }
@controller = realctl

```

But it leaves me with some grave reservations. A way to post to a  
different  
controller would be ideal, but I don’t think

I kinda like Eric’s suggestion of passing the session in manually, but  
that’s icky in a couple of different ways:

- You’ve got a fair chunk of code you’ll (but you can work around that  
with  
helpers);

- You’re tying your implementation of logging in in your tests (setting  
a  
particular session value) to the mechanics of login detection far closer  
than is comfortable.

It’s definitely a thorny issue, though.

- Matt

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 31, 2006, 4:23am UTC](https://www.ruby-forum.com/t/functional-tests-and-dealing-with-login-before-filter/53258/4 "2006-01-31T04:23:02Z")

</div>

On Jan 31, 2006, at 11:18 , Matthew P. wrote:

> I kinda like Eric’s suggestion of passing the session in manually, but  
> that’s icky in a couple of different ways:
> 
> - You’ve got a fair chunk of code you’ll (but you can work around  
> that with  
> helpers);

I added a small method in test\_helper.rb to set the session for me,  
passing it the member (user) that is supposed to be logged in.

def set\_session\_for(member)  
@request.session[:member\_id] = member.id  
end

I then can call set\_session\_for in my test methods to have them  
logged in. Works well for me.

> - You’re tying your implementation of logging in in your tests  
> (setting a  
> particular session value) to the mechanics of login detection far  
> closer  
> than is comfortable.

I rationalize this by testing logging by thoroughly testing my  
login\_controller. And the before\_filter is just checking for that  
particular session value to be set anyway (if it’s similar to the  
examples in AWDwR). Perhaps you could abstract this out a bit by  
naming the helper method log\_in(member) and then keep the code that  
does sets up the log in (in this case setting a session parameter) in  
the log\_in helper method. Then you only have to change the guts of  
one method if your log in implementation changes.

Michael G.  
grzm myrealbox com

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 31, 2006, 8:15pm UTC](https://www.ruby-forum.com/t/functional-tests-and-dealing-with-login-before-filter/53258/5 "2006-01-31T20:15:42Z")

</div>

On Jan 30, 2006, at 7:22 PM, Michael G. wrote:

> I added a small method in test\_helper.rb to set the session for me,  
> passing it the member (user) that is supposed to be logged in.
> 
> def set\_session\_for(member)  
> @request.session[:member\_id] = member.id  
> end
> 
> I then can call set\_session\_for in my test methods to have them  
> logged in. Works well for me.

Yes, this is what I do. One line isn’t too much.

> naming the helper method log\_in(member) and then keep the code that  
> does sets up the log in (in this case setting a session parameter)  
> in the log\_in helper method. Then you only have to change the guts  
> of one method if your log in implementation changes.

Yes. By properly abstracting (set\_session\_for) and properly testing  
the login code you will get a clear indication why all your logged-in  
tests are failing.

This way if you change the login code all your tests requiring a  
valid session will fail but you only have to fix your tests in one  
place. (If you’re constantly changing how valid sessions are  
represented you’re doing something very wrong.)

You don’t want to test your login code for every logged-in action,  
that’s why you wrote a test for your filters. I create a test-only  
DummyController for testing login and other filters which gives me a  
clear indication what is broken with which filter.

When I’m testing an action that requires the user to be logged in I  
want to test the the action, not that the login filter works.

PS: If you can’t figure out what part of your login system is broken  
from your tests you _obviously_ don’t have enough tests.

–  
Eric H. - removed\_email\_address@domain.invalid - [http://segment7.net](http://segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)
