SitePoint Sponsor

User Tag List

Results 1 to 22 of 22
  1. #1
    SitePoint Member skrolikowski's Avatar
    Join Date
    Nov 2006
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    test_should_redirect_after_login_with_return_url

    On page 271 Testing Redirection After Login, I'm confused about the test_should_redirect_after_login_with_return_url test.

    Here's the code from both the Book and Code Archive:
    Code:
    def test_should_redirect_after_login_with_return_url
      post :login, { :login => 'patrick', :password => 'sekrit' },
          :return_to => '/story/new'
      assert_redirected_to '/story/new'
    end
    When I run the test I get the error below:
    Code:
     1) Failure:
    test_should_redirect_after_login_with_return_url(AccountControllerTest)
    [/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_controller/assertions/response_assertions.rb:86:in `assert_redirected_to'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.2/lib/action_controller/assertions/response_assertions.rb:35:in `assert_redirected_to'
    ./test/functional/account_controller_test.rb:40:in `test_should_redirect_after_login_with_return_url']:
    response is not a redirection to all of the options supplied
    (redirection is <{"controller"=>"story"}>), difference: <{"action"=>"new"}>
    Not sure what the other stuff means, but the highlighted (red) code I think is what's important.
    So I changed the test to:
    Code:
    def test_should_redirect_after_login_with_return_url
      post :login, { :login => 'patrick', :password => 'sekrit' },
          :return_to => '/story/new'
      assert_redirected_to :controller => 'story'
    end
    And now it works failure-free. What gives?
    I know it's not correct even though it says it is.
    Did anyone else have this problem?

  2. #2
    SitePoint Addict myrdhrin's Avatar
    Join Date
    Jul 2004
    Location
    Montreal
    Posts
    211
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you read the documentation for assert_redirected_to you'll see this assertion takes the parameters of a URL, not the actual text.

    There is a reason that seems obvious to me in this. The actual URL shown in the browser will be calculated based on your route.rb file and might not match your test (that's why you're setting the post using the action name and other parameters, not the actual URL).

    With that in mind, I hope you're generating the URL for return_to using the url_for helper and not hardcoding it directly in your view.

    BTW, your latest test works because it says, as long as I'm redirected to the controller story it's good.

    Since you also want to test for the action new you probably want to use the following instead:
    Code:
    assert_redirected_to :controller => 'story', :action=>'new'
    Jean-Marc (aka Myrdhrin)
    M2i3 - blog - Protect your privacy with Zliki

  3. #3
    SitePoint Member skrolikowski's Avatar
    Join Date
    Nov 2006
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myrdhrin View Post

    Since you also want to test for the action new you probably want to use the following instead:
    Code:
    assert_redirected_to :controller => 'story', :action=>'new'
    I tried this and get the same failure.

    Here's the login method used for the account controller:
    Code:
    def login
      if request.post?
        @current_user = User.find_by_login_and_password(
          params[:login], params[:password])
        unless @current_user.nil?
          session[:user_id] = @current_user.id
          unless session[:return_to].blank?
            redirect_to session[:return_to]
            session[:return_to] = nil
          else
            redirect_to :controller => 'story'
          end
        end
      end
    end
    If I change the highlighted (in red) line to:
    Code:
    redirect_to :controller => '/story/new'
    The failure goes away, but I know this isn't the correct action to take.

  4. #4
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe it redirects to session[:return_to]? You can use breakpointer to check. (or dirty way: replace the call to redirect_to session[:return_to] with redirect_to :controller => 'story' and check if the error goes away) BTW, where are you redirected if you log-in using your web browser?

  5. #5
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i am in the same situation. We wait for an author answer

  6. #6
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Could someone post the full code + steps required to get this problem?

  7. #7
    SitePoint Addict myrdhrin's Avatar
    Join Date
    Jul 2004
    Location
    Montreal
    Posts
    211
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skrolikowski View Post
    I tried this and get the same failure.

    you mention redirecting only to :controller => 'story'

    if I'm not mistaken this will actually redirect to:
    :controller=>'story',:action=>'index'
    Jean-Marc (aka Myrdhrin)
    M2i3 - blog - Protect your privacy with Zliki

  8. #8
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You're right.

    So the problem is that session[:return_to] is reset somewhere. Is there a before filter where this happens? In this thread there is such a before filter: http://www.sitepoint.com/forums/showthread.php?t=463518, but it's not this one because that would redirect to /account/login and not to /story...

  9. #9
    SitePoint Enthusiast
    Join Date
    Sep 2005
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    unless session[:return_to].blank?
      redirect_to session[:return_to]
      session[:return_to] = nil
    else
      redirect_to :controller => 'story'
    end
    I'm new to ruby so feel free to tell me to shut up if i'm way off target, but is it possible that our test is not setting the 'return_to' session variable properly? That is the only reason i can see that we'd be sent to the index action of the story controller. Are all POST submissions automatically stored as session variables or is there another way?

  10. #10
    SitePoint Enthusiast
    Join Date
    Sep 2005
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    bah, disregard, that last post. found in the docs how the 'post' test works and it should indeed be setting the return_to session var. here's the full code as requested:

    account_controller.rb
    Code:
    class AccountController < ApplicationController
      def login
        if request.post?
          @current_user = User.find_by_login_and_password(
            params[:login], params[:password])
          unless @current_user.nil?
            session[:user_id] = @current_user.id
            unless session[:return_to].blank?
              redirect_to session[:return_to]
              session[:return_to] = nil
            else
              redirect_to :controller => 'story'
            end
          end
        end
      end
    
      def logout
        session[:user_id] = @current_user = nil
      end
    end
    application.rb
    Code:
    class ApplicationController < ActionController::Base
      before_filter :fetch_logged_in_user
      protected
      def fetch_logged_in_user
        return if session[:user_id].blank?
        @current_user = User.find_by_id(session[:user_id])
      end
      
      def logged_in?
        ! @current_user.blank?
      end
      helper_method :logged_in?
      
      def login_required
        return true if logged_in?
        session[:return_to] = request.request_uri
        redirect_to :controller => "/account", :action => "login" and return false
      end
    end
    and for good measure, here is story_controller.rb
    Code:
    class StoryController < ApplicationController
      before_filter :login_required, :only => :new
      def index
        @story = Story.find(:first, :order => 'RAND()')
      end
      
      def new
        @story = Story.new(params[:story])
        @story.user = @current_user
        if request.post? and @story.save
          flash[:notice] = 'Story submission succeeded'
          redirect_to :action => 'index'
        end
      end
      
      def show
        @story = Story.find_by_permalink(params[:permalink])
      end
      
      def vote
        @story = Story.find(params[:id])
        @story.votes.create
    
        respond_to do |wants|
          wants.html { redirect_to :action => 'show', :permalink => @story.permalink }
          wants.js   { render }
        end
      end
    end

  11. #11
    SitePoint Member
    Join Date
    Mar 2007
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I had the same problem and I was able to solve it by modifying the session parameters part as follow:

    Code:
    def test_should_redirect_after_login_with_return_url
      post :login, { :login => 'patrick', :password => 'sekrit' },
          'return_to' => '/story/new'
      assert_redirected_to '/story/new'
    end
    No idea why it works this way. Any ideas?

  12. #12
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jfchevrette View Post
    I had the same problem and I was able to solve it by modifying the session parameters part as follow:

    Code:
    def test_should_redirect_after_login_with_return_url
      post :login, { :login => 'patrick', :password => 'sekrit' },
          'return_to' => '/story/new'
      assert_redirected_to '/story/new'
    end
    No idea why it works this way. Any ideas?
    surely that parameter need to be a string object and not a symbol

    anyway that corrects the problem also to me but i have one last failure:

    1) Failure:
    default_test(StoryControllerTest) [/usr/lib/ruby/gems/1.8/gems/rake-0.7.1/lib/ra ke/rake_test_loader.rb:5]:
    No tests were specified.

  13. #13
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    another question....i don't understand why sometimes the redirect_to method is called with a controller parameter like ":controller => "controllername" and other times as ":controller => "/controllername"

  14. #14
    SitePoint Member skrolikowski's Avatar
    Join Date
    Nov 2006
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Skyblaze, where is your:
    Code:
    protected
    def get_with_user(action, parameters = nil, session = nil, flash = nil)
      get action, parameters, :user_id => users(:patrick).id
    end
    def post_with_user(action, parameters = nil, session = nil, flash = nil)
      post action, parameters, :user_id => users(:patrick).id
    end
    placed in your story_controller_test.rb?

    I noticed if I place it above all your tests (and after my def setup) I get this default_test failure too.

  15. #15
    SitePoint Member skrolikowski's Avatar
    Join Date
    Nov 2006
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Fenrir2 View Post
    Maybe it redirects to session[:return_to]? You can use breakpointer to check. (or dirty way: replace the call to redirect_to session[:return_to] with redirect_to :controller => 'story' and check if the error goes away) BTW, where are you redirected if you log-in using your web browser?
    Sorry I didn't get back earlier. I am redirected to the home page (/story/index.rhtml) page. Here's my login method:
    Code:
    def login
      if request.post?
        @current_user = User.find_by_login_and_password(
          params[:login], params[:password])
        unless @current_user.nil?
          session[:user_id] = @current_user.id
          unless session[:return_to].blank?
            redirect_to session[:return_to]
            session[:return_to] = nil
          else
            redirect_to :controller => 'story'
          end
        end
      end
    end
    Quote Originally Posted by jfchevrette View Post
    I had the same problem and I was able to solve it by modifying the session parameters part as follow:

    Code:
    def test_should_redirect_after_login_with_return_url
      post :login, { :login => 'patrick', :password => 'sekrit' },
          'return_to' => '/story/new'
      assert_redirected_to '/story/new'
    end
    No idea why it works this way. Any ideas?

    I don't think this is a solid correction, because you can also replace :login and : password with 'login' and 'password' respectively without getting a failure message.

  16. #16
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skrolikowski View Post
    Skyblaze, where is your:
    Code:
    protected
    def get_with_user(action, parameters = nil, session = nil, flash = nil)
      get action, parameters, :user_id => users(:patrick).id
    end
    def post_with_user(action, parameters = nil, session = nil, flash = nil)
      post action, parameters, :user_id => users(:patrick).id
    end
    placed in your story_controller_test.rb?

    I noticed if I place it above all your tests (and after my def setup) I get this default_test failure too.
    yes but if i put those private methods at the end of the file i get lots of error 'cause other actions don't find those methods..

  17. #17
    SitePoint Wizard bronze trophy
    Join Date
    Oct 2001
    Location
    Vancouver BC Canada
    Posts
    2,030
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    I'm in the same boat with the same troubles.

    The protected methods don't seem to work at all for me regardless of where they are. I think they belong at the bottom but of course they don't work regardless.

    If I find anything that works I'll post it.

    I should mention that although the functional tests are not working, the actual code works quite well in server/browser testing so it doesn't appear to be the login code. It seems to me that the test code is flawed.
    Andrew Wasson | www.lunadesign.org
    Principal / Internet Development

  18. #18
    SitePoint Member skrolikowski's Avatar
    Join Date
    Nov 2006
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Skyblaze View Post
    yes but if i put those private methods at the end of the file i get lots of error 'cause other actions don't find those methods..
    I'm with you there. No matter where I put it I get at least one failure error. I think I'm going to stick with just PHP. Ruby is starting to give me a major headache.

  19. #19
    SitePoint Member skrolikowski's Avatar
    Join Date
    Nov 2006
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by awasson View Post
    I'm in the same boat with the same troubles.

    The protected methods don't seem to work at all for me regardless of where they are. I think they belong at the bottom but of course they don't work regardless.

    If I find anything that works I'll post it.

    I should mention that although the functional tests are not working, the actual code works quite well in server/browser testing so it doesn't appear to be the login code. It seems to me that the test code is flawed.
    I agree with you that the actual code works flawlessly and
    the functional tests are where the problems are at.
    I'll fill you in if I find anything out as well.

  20. #20
    SitePoint Wizard bronze trophy
    Join Date
    Oct 2001
    Location
    Vancouver BC Canada
    Posts
    2,030
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skrolikowski View Post
    I'm with you there. No matter where I put it I get at least one failure error. I think I'm going to stick with just PHP. Ruby is starting to give me a major headache.
    No don't give just yet. You're not alone on in this problem.

    The reason you're getting errors is because the protected methods don't work or at least within the scope of the testing framework they don't. I've been too busy to do anymore on this myself and probably won't until tomorrow evening but I'm going to rewrite the tests that fail with get_with_user and post_with_user without the "methods" and see how it works.
    Andrew Wasson | www.lunadesign.org
    Principal / Internet Development

  21. #21
    SitePoint Member skrolikowski's Avatar
    Join Date
    Nov 2006
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've been searching Google and found that lots of people are having similar problems, including this

    "I found similar brittleness with follow_redirect method. The functional
    test support is not very robust, breaks often, and fails to work as
    advertised."

  22. #22
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    yes but the code works perfectly and i don't return on php just to waste hours of development


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •