How can I set the session in a functional test?


#1

Hey :slight_smile:

I need to simulate a login in my functional test, otherwise I can’t GET
nor
POST to the action.

I need to set the session key “logged_in_user_id”.

I tried this inside the setup() method:

session[‘logged_in_user_id’] = 1

But that throws: TypeError: can’t convert String into Integer

Any ideas?

Thanks,
Rob


#2

On Tue, Jun 06, 2006 at 03:13:57AM +0200, Robert MannI wrote:

But that throws: TypeError: can’t convert String into Integer

Any ideas?

If you try “puts session.class” you’ll note that it’s not a session
object
until after you’ve run your session-manipulating request. From memory,
if
you put “session = ActionController::TestSession.new” before you fiddle
with
the session, it’ll all work OK – unless the first get/post you call in
your
test unconditionally resets the session, but I don’t think it does.

  • Matt


How many Apple Newton users does it take to change a lightbulb?
Foux. There to eat lemons, axe gravy soup.
– Seen on the 'net


#3

Cool, seems to work, thanks :))


#4

On Jun 5, 2006, at 09:45 PM, Matthew P. wrote:

the session, it’ll all work OK – unless the first get/post you
call in your
test unconditionally resets the session, but I don’t think it does.

Hmm… I suppose that’s one way to go, but it’s definitely not the
proscribed way of setting session object values when running
Functional Tests. If you hop on over to the Rails api and do a little
digging (or run a search on this list for the answer that I provided
a couple of weeks ago :wink: you’ll see that you can pass both session
and params values into the controller action when you make the get or
post calls.

The basic syntax looks like this:

get/post/put/delete/head(action, parameters=nil, session=nil,
flash=nil)

Examples:
get :index
post :login, :user => {:name => “fred”, :password => “abracadabra”}

So, for your logged_in_user_id you could use something as simple as:

get :action, {}, {:logged_in_user_id => 1}

-Brian


#5

Well, thanks for the help but, even though that new solution you
proposed is
cleaner, I’d have to put in the session hash into every single get() and
post() method of my functional tests.

Not very DRY, so I was wondering, how do the other people out there do
it?

Rob


#6

On Mon, Jun 05, 2006 at 10:32:27PM -0400, Brian H. wrote:

get/post/put/delete/head(action, parameters=nil, session=nil,
flash=nil)

You are completely correct, and that is a much better way to do it than
my
bodgy hack. I claim too much influence from other, less-capable,
languages
and environments, which led me to try the hack rather than finding the
elegance.

  • Matt

#7

So the solution proposed above is not a hack after all?

“Hmm… I suppose that’s one way to go, but it’s definitely not the
proscribed way of setting session object values when running
Functional Tests.”

Thanks,
Rob


#8

On Jun 5, 2006, at 11:31 PM, Robert MannI wrote:

Well, thanks for the help but, even though that new solution you
proposed is cleaner, I’d have to put in the session hash into every
single get() and post() method of my functional tests.

Not very DRY, so I was wondering, how do the other people out there
do it?

If it doesn’t change, define it once and pass it repeatedly.

If it does change, then there’s no way to dry it out anyway.


– Tom M.


#9

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Jun 5, 2006, at 11:51 PM, Robert MannI wrote:

So the solution proposed above is not a hack after all?

“Hmm… I suppose that’s one way to go, but it’s definitely not the
proscribed way of setting session object values when running
Functional Tests.”

No, I meant like this:

def test_logout
sess_vals = { :user_id => 1 }
get :logout1, { }, sess_vals
get :logout2, { }, sess_vals
end

If the session doesn’t even change between tests, then you can
set it in the setup method.


  • – Tom M.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (Darwin)

iD8DBQFEhTZKzaKkuvKwKvcRAnp8AKCJtSg0bbuesN4ZUadLnL/cDaNQwQCfQDwk
z5cZiKkpRSJY1LilVBvFRw8=
=oFtD
-----END PGP SIGNATURE-----


#10

Just do:

my_session = {:foo => “bar”}
get :my_action, {}, my_session
get :my_other_action, {}, my_session

hth,
phil


#11

On Tue, 6 Jun 2006 08:31:57 +0200, Robert MannI wrote:

Not very DRY, so I was wondering, how do the other people out there do it?

I have a login method in the helpers that puts a proper key-value in
the @request.session hash before calling the “admin-only” pages with
get or posts.
I’m using user_engine + login_engine for the authentication .


#12

On Jun 6, 2006, at 03:32 PM, Pete wrote:

get :index

end
end

While I realize this works, this is completely the wrong way to set a
session value for a functional test request. Please read my posts on
this, so you can see the proper way to set not only session values,
but parameters and flash values as well. It’s built-in to the get,
post, delete, put and head methods…

-Brian


#13

this is what I generally use…

class MyTest < Test::Unit::TestCase

attr_reader :session

def setup
@session = ActionController::TestSession.new
end

def test_it

get :index
# ...

end
end

Enrico F. schrieb:


#14

I still don’t get this.

Why are the default functional tests so loosely ugly? The setup() method
by
default does this:

@controller = MyController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new

When I put a breakpoint in there, I can access three (3!!) session
accessors:

@controller.session # returns nil
@request.session # returns #ActionController::TestSession:...
@response.session # returns []

What is happening here? This is smelly, maybe I don’t get it.

And I know get/post/head etc have a session parameter in their argument
list, but I don’t see why I should do:

sess_vals = { :logged_in_user_id => 1 }
get :do_something, {  }, sess_vals
get :do_something_else, {  }, sess_vals

for each of my actions. I just want to set the logged in user once,
and
then go on with my life. Is there any correct/clean way to do this?
Everyone seems to be using something else.

Thanks alot for the help,
Rob


#15

What I’ve been doing is adding this to test_helper.rb:

Get a login so methods protected by authentication can be tested

def get_logged_in
@request.session[:user] = User.find_first
assert_not_nil @request.session[:user]
@request.session[:user].logged_in_at = Time.now
@request.session[:user].save
end

Then my test methods can go like:

def test_foo
get :bar
assert_redirect
get_logged_in
get :bar
assert :success
end

My get_logged_in method assumes a test database with a user in it. You
could
just as easily create a fixture and load from there.

I read the post about this not being the way to set a session. I
understand
that the session hash is passed to the get and post methods, but I’ve
found
this workaround reliable thus far. Of course I’m all ears if what I’m
doing
is brittle and will come back to bite me later.

HTH

View this message in context:
http://www.nabble.com/How-can-I-set-the-session-in-a-functional-test--t1738777.html#a4873272
Sent from the RubyOnRails Users forum at Nabble.com.