Webrat and RESTful Authentication

12 views
Skip to first unread message

GS

unread,
May 18, 2009, 4:59:38 AM5/18/09
to webrat
How does Webrat work with the a session and/or cookie object?

I'm attempting to test that i can log in as a user and then travel to
a nested resource for that user...

the two applicable step definitions i've defined are:

Given /^I am (.+) (.+) and I am on the account_(.+) page$/ do |
first_name, last_name, route_frag|
@current_account = Account.create!(:first_name =>
first_name, :last_name => last_name, :email =>
"te...@ttkb.net", :password => "tpass123", :title => "Ms.", :login =>
"te...@ttkb.net")
visit new_session_path
fill_in :email, @current_account.email
fill_in :password, @current_account.password
click_button 'Adult Login'
s = "/accounts/" + @current_account.id.to_s + "/#{route_frag}"
visit s
end

Given /^I am (.+) (.+) and I am on the new_account_(.+) page$/ do |
first_name, last_name, route_frag|
@current_account = Account.create!(:first_name =>
first_name, :last_name => last_name, :email =>
"te...@ttkb.net", :password => "tpass123", :title => "Ms.", :login =>
"te...@ttkb.net")
visit new_session_path
fill_in :email, @current_account.email
fill_in :password, @current_account.password
check :remember_me
click_button 'Adult Login'
s = "/accounts/" + @current_account.id.to_s + "/#{route_frag}/new"
visit s
end


But when I am not clear how Webrat handles logins, or if it persists a
session between scenarios...

when i try to use these step definitions i get:
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.has_role? (NoMethodError)

which is basically throwing an error when it comes across the variable
"current_account" which gets defined as AuthenticatedSystem.rb:
def current_account
@current_account ||= (login_from_session || login_from_cookie)
unless @current_account == false
end

What am I doing wrong?


GS

unread,
May 18, 2009, 7:36:25 PM5/18/09
to webrat
if my original post was too much, maybe..just more simply,

how do I simulate going to a route that requires getting the id of the
current user?
and is that enough if the user is logged in?
if i create a user in a webrat step, for how long is that user around
in my test db? the current scenario? the whole feature?

any answers or pointing me to references would be appreciated.

-gabe

doug livesey

unread,
May 18, 2009, 7:46:07 PM5/18/09
to web...@googlegroups.com
This is one that I've been struggling with as well.
Initially, I tried (with some help, I should add) adding stubs to my features, but they were not clearing down properly, so for now I'm having to run a step called something like 'Given I am logged in as "superuser"' which actually goes through the login procedure. Worse, I've had to add rudimentary login functionality to apps that didn't have it (with a plugin, so not too bad) to simulate this.
So, sorry, I'm not giving any help but sympathy, really, and adding my voice to the appeal for guidance on this issue.
   Doug.

Matt Wynne

unread,
May 19, 2009, 3:55:06 AM5/19/09
to web...@googlegroups.com

On 19 May 2009, at 00:36, GS wrote:

>
> if my original post was too much, maybe..just more simply,
>
> how do I simulate going to a route that requires getting the id of the
> current user?
> and is that enough if the user is logged in?
> if i create a user in a webrat step, for how long is that user around
> in my test db? the current scenario? the whole feature?

You're talking about a Cucumber scenario, right? In that case, the
session will be around for the life of the scenario. This is a really
nice thing, as you can assume that one scenario doesn't leak state
into another.

At songkick, we have hundreds of scenarios that run in a feature with
the following step at the top:

Background:
Given I am logged into my account

That step is implemented like this:

Given /^I am logged into my account$/ do
@me = Factory(:user, :password => 'valid_password')
visit new_session_path
fill_in :username, @me.username
fill_in :password, 'valid_password'
click_button 'Log in'
end

We like this solution, as there's absolutely no coupling to any
implementation of sessions within the code, and we get the added
benefit of knowing that we're testing the path a real user will use to
log into the site.

The @me instance variable lives for as long as the current scenario,
no longer. It isn't a reference to the actual instance of User that
the controllers will use, but a representation of the same object in
the testing space, which I can use as a useful reference to that user.

Make sense?
Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com

GS

unread,
May 19, 2009, 11:27:27 AM5/19/09
to webrat
so then, am i correct in thinking that within a cucumber scenario a
step such as,

Given I am at MY "some_nested_resource" page

can be implemented as:

Given /^I am at MY "(.+)" page$/ do |route_fragment|
full_path = "/users/" + @me.id.to_s + "/#{route_fragment}"
visit full_path
end

and thank you!

doug livesey

unread,
May 19, 2009, 11:32:42 AM5/19/09
to web...@googlegroups.com
> Make sense?

Yes, and that's the way I've ended up going, too.
However, due to some session sharing, not all my apps have logins, so this didn't work for them.
When I couldn't get stubbing the authorise method in my application controller to work, I have ended up extracting login functionality into a plugin to include in those apps so that I can use something similar to the method you propose.
& it works, so that's fine.
Would be nice to just stub the authorise method, though.
   Doug.
Reply all
Reply to author
Forward
0 new messages