Testing Controllers that require logged-in user / authentication

43 views
Skip to first unread message

Tim Griffin

unread,
May 1, 2013, 7:58:59 AM5/1/13
to hobo...@googlegroups.com
Hi all;

Being one of those RonR/Hoboists learning a lot of testing after having written the application (>cough<), I'm experiencing a little head-scratching about testing a controller other than the UsersController. 

Could anyone enlighten me as to how to properly test a controller in Hobo that requires a user to be logged in? 

For example, with a TitlesController, the #index action in my application is only available to an authenticated user. So, I want to test as follows:

describe "TitlesController" do 

  it "Authenticated user must see Titles index" do
    # User needs to be logged in. How? 
    
    get :index
    it { must render_template(:index) }    
    it { must respond_with(:success) } 
  end

end

But, anything I do inside the it..do..end block works with the context of the TitlesController.

So, even if I do this:

  it "Authenticated user must see Titles index" do
    post :login, :controller => :users, :login => "me...@nowhere.com", :password => "Test123"
    get :index

or

  it "Authenticated user must see Titles index" do
    post "http://localhost:3000/login", :login => "ne...@nowhere.com", :password => "Test123"
    get :index


the post directives pretty much get garbled thinking that the login post is for the TitlesController:

     0001 Authenticated user must see Titles index                                ERROR
        No route matches {:login=>"m...@nowhere.com", :password=>"Test123", :controller=>"titles", :action=>"http://localhost:3000/login"}


So, what's the best way to get the user authenticated within a specific controller test? 

I know I can do this:

  it "Authenticated user must see Titles index" do
    session = ActionDispatch::Integration::Session.new(Rails.application)
    session.post ('http://localhost:3000/login'), :login => "m...@nowhere.com", :password => "Test123"
    session.get('http://localhost:3000/titles')
    titles_html = session.response.body
    assert(titles_html ... )
  end


But, is building my own session in each test the only way to circumvent the assumed context of the TitlesController for a login? 

Many thanks,
Tim




Ignacio Huerta

unread,
May 1, 2013, 8:13:36 AM5/1/13
to hobo...@googlegroups.com, Tim Griffin
Hi Tim,

We usually use this in our integration tests to make a faster login:

visit '/dev/set_current_user?login=tecnicos%40unoycero.com'

So I guess you could try this in your controller tests:

get '/dev/set_current_user?login=ew%40nowhere.com'

About the "set_current_user" URL. This is used by Hobo in the user
changer select. This appears only in development mode and allows you to
change user quickly. It turns out that it works in test mode too, and
for us it has been really helpful.

Regards,
Ignacio

El 01/05/13 13:58, Tim Griffin escribi�:
> Hi all;
>
> Being one of those RonR/Hoboists learning a lot of testing
> /after/ having written the application (>cough<), I'm experiencing a
> little head-scratching about testing a controller other than the
> UsersController.
>
> Could anyone enlighten me as to how to properly test a controller in
> Hobo that requires a user to be logged in?
>
> For example, with a TitlesController, the #index action in my
> application is only available to an authenticated user. So, I want to
> test as follows:
>
> describe "TitlesController" do
>
> it "Authenticated user must see Titles index" do
> # User needs to be logged in. How?
> get :index
> it { must render_template(:index) }
> it { must respond_with(:success) }
> end
>
> end
>
> But, anything I do inside the it..do..end block works with the context
> of the TitlesController.
>
> So, even if I do this:
>
> it "Authenticated user must see Titles index" do
> post :login, :controller => :users, :login => "m
> <mailto:tim.g...@enwood.ca>e...@nowhere.com", :password => "Test123"
> get :index
>
> or
>
> it "Authenticated user must see Titles index" do
> post "http://localhost:3000/login", :login => "n
> <mailto:tim.g...@enwood.ca>e...@nowhere.com", :password => "Test123"
> get :index
>
>
> the post directives pretty much get garbled thinking that the login post
> is for the TitlesController:
>
> 0001 Authenticated user must see Titles index
> ERROR
> No route matches {:login=>"m...@nowhere.com",
> :password=>"Test123", :controller=>"titles",
> :action=>"http://localhost:3000/login <http://localhost:3000/login>"}
>
>
> So, what's the best way to get the user authenticated within a specific
> controller test?
>
> I know I can do this:
>
> it "Authenticated user must see Titles index" do
> session = ActionDispatch::Integration::Session.new(Rails.application)
> session.post ('http://localhost:3000/login'), :login =>
> "m...@nowhere.com", :password => "Test123"
> session.get('http://localhost:3000/titles')
> titles_html = session.response.body
> assert(titles_html ... )
> end
>
>
> But, is building my own session in each test the only way to circumvent
> the assumed context of the TitlesController for a login?
>
> Many thanks,
> Tim
>
>
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Hobo Users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to hobousers+...@googlegroups.com.
> To post to this group, send email to hobo...@googlegroups.com.
> Visit this group at http://groups.google.com/group/hobousers?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

--
Ignacio Huerta Arteche
http://www.ihuerta.net
Tel�fono: 0034 645 70 77 35
Email realizado con software libre

Tim Griffin

unread,
May 1, 2013, 9:50:49 AM5/1/13
to hobo...@googlegroups.com

Thanks for the suggestion, Ignacio, but that request is still assumed to be a request against the TitlesController:

  it "Authenticated user must see Titles index" do
    get '/dev/set_current_user?login=me%40nowhere.com'    
    
    get :index
    it { must render_template(:index) }    
  end


TitlesController
     0001 Authenticated user must see Titles index                       ERROR
        No route matches {:controller=>"titles", :action=>"/dev/set_current_user?login=me%40nowhere.com"}
        STDERR:

Tim

Ignacio Huerta

unread,
May 1, 2013, 11:03:00 AM5/1/13
to hobo...@googlegroups.com, Tim Griffin
Oh, that's a pity. Maybe you could play with the session or mock some
user methods. I think devise has some helpers for this, but I don't know
any in Hobo.

Maybe someone else on the list has some experience with this problem and
can help.

Regards,
Ignacio

El 01/05/13 15:50, Tim Griffin escribi�:
>
> Thanks for the suggestion, Ignacio, but that request is still assumed to
> be a request against the TitlesController:
>
> it "Authenticated user must see Titles index" do
> get '/dev/set_current_user?login=me%40nowhere.com'
> get :index
> it { must render_template(:index) }
> end
>
>
> TitlesController
> 0001 Authenticated user must see Titles index
> ERROR
> No route matches {:controller=>"titles",
> :action=>"/dev/set_current_user?login=me%40nowhere.com"}
> STDERR:
>
> Tim
>
>
>
> On Wednesday, May 1, 2013 7:58:59 AM UTC-4, Tim Griffin wrote:
>
> Hi all;
>
> Being one of those RonR/Hoboists learning a lot of testing
> /after/ having written the application (>cough<), I'm experiencing a
> little head-scratching about testing a controller other than the
> UsersController.
>
> Could anyone enlighten me as to how to properly test a controller in
> Hobo that requires a user to be logged in?
>
> For example, with a TitlesController, the #index action in my
> application is only available to an authenticated user. So, I want
> to test as follows:
>
> describe "TitlesController" do
>
> it "Authenticated user must see Titles index" do
> # User needs to be logged in. How?
> get :index
> it { must render_template(:index) }
> it { must respond_with(:success) }
> end
>
> end
>
> But, anything I do inside the it..do..end block works with the
> context of the TitlesController.
>
> So, even if I do this:
>
> it "Authenticated user must see Titles index" do
> post :login, :controller => :users, :login => "m
> <mailto:tim.g...@enwood.ca>e...@nowhere.com <mailto:e...@nowhere.com>",
> :password => "Test123"
> get :index
>
> or
>
> it "Authenticated user must see Titles index" do
> post "http://localhost:3000/login", :login => "n
> <mailto:tim.g...@enwood.ca>e...@nowhere.com
> <mailto:e...@nowhere.com>", :password => "Test123"
> get :index
>
>
> the post directives pretty much get garbled thinking that the login
> post is for the TitlesController:
>
> 0001 Authenticated user must see Titles index
> ERROR
> No route matches {:login=>"m...@nowhere.com
> <mailto:m...@nowhere.com>", :password=>"Test123",
> :controller=>"titles", :action=>"http://localhost:3000/login
> <http://localhost:3000/login>"}
>
>
> So, what's the best way to get the user authenticated within a
> specific controller test?
>
> I know I can do this:
>
> it "Authenticated user must see Titles index" do
> session =
> ActionDispatch::Integration::Session.new(Rails.application)
> session.post ('http://localhost:3000/login'), :login =>
> "m...@nowhere.com <mailto:m...@nowhere.com>", :password => "Test123"
> session.get('http://localhost:3000/titles
> <http://localhost:3000/titles>')
> titles_html = session.response.body
> assert(titles_html ... )
> end
>
>
> But, is building my own session in each test the only way to
> circumvent the assumed context of the TitlesController for a login?
>
> Many thanks,
> Tim
>
>
>
>
Reply all
Reply to author
Forward
0 new messages