Forum: Ruby on Rails Setting session data within Integration Test

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
72ea925c0ca3d19fdd2f12fa76681624?d=identicon&s=25 Stephan Wehner (stephanwehner)
on 2007-07-30 20:17
How do I manipulate the session data in an integration test?

We have a controller that manipulates session data, and I want to see,
passing in certain session data, what comes out.

The session is available in integration tests through module
ActionController::TestProcess

def session
  @response.session
end

So if I perform


 session[:new_key] = 'new_value'
 session.update

 get '/some_controller/some_action'

 assert_nil session[:new_key]

this will pass, in other words, it is not possible to manipulate the
session used for the __next__ request in this manner. One can only
inspect the session

What can I do?

Stephan
D69d23d8e811e8ab2a8593380d6ede63?d=identicon&s=25 Jeff Emminger (jemminger)
on 2007-07-31 00:14
(Received via mailing list)
shouldn't that be @request.session, not @response.session?


On Jul 30, 2:17 pm, Stephan Wehner <rails-mailing-l...@andreas-s.net>
72ea925c0ca3d19fdd2f12fa76681624?d=identicon&s=25 Stephan Wehner (stephanwehner)
on 2007-07-31 00:25
Jeff Emminger wrote:
> shouldn't that be @request.session, not @response.session?
>

Thanks for your reply, I'm not clear what you are referring to. The
snippet

def session
  @response.session
end

that I pasted is from the module, ActionController::TestProcess

Either way, I set @request.session[:new_key] = 'new_value' and it
doesn't survive calling

  get '/some_controller/some_action'

The integration test re-initializes the session object for each request.

Still stuck --

Stephan
D69d23d8e811e8ab2a8593380d6ede63?d=identicon&s=25 Jeff Emminger (jemminger)
on 2007-07-31 01:27
(Received via mailing list)
ah... i actually haven't used integration tests yet anyway ;-)

came across this though, seems to deal with simulating multiple users
in an integration test... perhaps it will give you some ideas
http://weblog.jamisbuck.org/2006/3/9/integration-t...


On Jul 30, 6:25 pm, Stephan Wehner <rails-mailing-l...@andreas-s.net>
72ea925c0ca3d19fdd2f12fa76681624?d=identicon&s=25 Stephan Wehner (stephanwehner)
on 2007-07-31 01:57
Jeff Emminger wrote:
> ah... i actually haven't used integration tests yet anyway ;-)
>
> came across this though, seems to deal with simulating multiple users
> in an integration test... perhaps it will give you some ideas
> http://weblog.jamisbuck.org/2006/3/9/integration-t...
>
>
> On Jul 30, 6:25 pm, Stephan Wehner <rails-mailing-l...@andreas-s.net>

Well, thanks -- they talk about sessions as in "user sessions" ("Bob
logs in, Bob does this, Stacey logs in, Stacey does that...). Whereas
I'm looking at the  CGI::Session object that is stored on the server
side, and available as @response.session / @request.session or just
session.

Stephan
2db1af11af9216b58741aed3b45ce066?d=identicon&s=25 Gary Winklosky (gwinklosky)
on 2007-08-08 19:23
I ran into the same problem and never really found a good answer via the
test objects.  The only solution I saw was to actually update the
session via a controller.  I defined a new action in one of my
controllers from within test_helper (so the action does not exist when
actually runnning the application).  I also had to create an entry in
routes.  Maybe there's a better way to update routes while testing.


So from my integration test I can do the following and verfiy:
    assert(session[:fake].nil?, "starts empty")
    v = 'Yuck'
    get '/user_session', :fake => v
    assert_equal(v, session[:fake], "value was set")

    assert(session[:foo].nil?, "starts empty")
    v_id = '2'
    get '/user_session', :foo_id => v_id
    assert_equal(v, session[:fake], "previous value still set")
    assert(!session[:foo].nil?, , "object entry exists")
    assert_equal(v_id.to_i, session[:foo].id, "correct object set")


<test_helper.rb>
ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) +
"/../config/environment")
require 'test_help'
require 'my_controller'

# Need to be able to set session values for integration tests
class MyController
  def user_session
    ignore = ['action', 'controller']
    params.each do | key, value|
      unless ignore.include?(key)
        if (pos = key.index('_id')).nil?
          session[key.to_sym] = value
        else
          new_key = key[0,pos]
          find_class = new_key.classify.constantize
          session[new_key.to_sym] = find_class.find(value.to_i)
        end
      end
    end
    redirect_to "/"
  end
end

class Test::Unit::TestCase
<rest of standard test_helper follows>


Added to routes.rb:
  map.user_session 'user_session', :controller => 'my', :action =>
'user_session'
72ea925c0ca3d19fdd2f12fa76681624?d=identicon&s=25 Stephan Wehner (stephanwehner)
on 2007-08-08 19:55
Gary Winklosky wrote:
> I ran into the same problem and never really found a good answer via the
> test objects.  The only solution I saw was to actually update the
> session via a controller.  I defined a new action in one of my
> controllers from within test_helper (so the action does not exist when
> actually runnning the application).  I also had to create an entry in
> routes.  Maybe there's a better way to update routes while testing.

Yes, I took the same route, although it seems wrong.

I also couldn't figure out what happens to the session objects during
integration testing; except it looked like they were copied from one
application call to the next and not reused.

Here is the class I added to test/integration. In my case I was
interested in setting a timestamp. So there is a separate method for
that, "set_time_value".

One might like to have a method "set_session_value" available in an
IntegrationTest. This method could just invoke the get
'/session_set/...'
This would hide this rather clumsy implementation.


------- BEGIN FILE test/integration/session_set_controller.rb
------------
ActionController::Routing.possible_controllers << 'session_set'

class SessionSetController < ApplicationController

  #
  # Found it impossible to manipulate session values from within an
integration test.
  #
  # Add
  #
  #   require File.dirname(__FILE__) + '/session_set_controller'
  #
  # Invoke
  #
  #   get '/session_set/set_value, :key=>'your_key',
:value=>'your_value'
  #
  def set_value
    session[params[:key].to_sym] = params[:value]
    render :nothing => true
  end

  def set_time_value
    session[params[:key].to_sym] = Time.parse(params[:value])
    render :nothing => true
  end
end
------- END FILE test/integration/session_set_controller.rb ------------


Related Note: I find the use of the term "session" within integration
tests a bit unfortunate (open_session, etc), since there are also these
session objects, which are however different. Maybe replace by
"user_session" ?


Stephan
2db1af11af9216b58741aed3b45ce066?d=identicon&s=25 Gary Winklosky (gwinklosky)
on 2007-08-14 17:47
I did see how to get something into the request's env for integration
testing:

get '/next_page', nil, {"HTTP_REFERER" =>
'http://localhost:20/last_page'}
6856d20b5d6cbdb827cdccca7f557979?d=identicon&s=25 goodwill (Guest)
on 2008-08-23 10:20
(Received via mailing list)
Hey any luck on this issue you have mentioned before? I come across
the same thing.

On Jul 31 2007, 2:17 am, Stephan Wehner <rails-mailing-l...@andreas-
This topic is locked and can not be replied to.