Devise sign_in helper, test unit and authenticate_user! before filters....

1,040 views
Skip to first unread message

pjammer

unread,
Dec 23, 2009, 11:23:55 AM12/23/09
to Devise
hi all.

i'm sure it's something i'm doing but here we go:

in test_helper.rb setup a login method:
def login(user = users(:one))
sign_in :user, user
# user
end

in a test of my Track controller i just simply put the
authenticate_user! in a before_filter in the Tracks_Controller.rb file
(boring scaffold stuff... nothing cool about this)

class TracksController < ApplicationController
before_filter :authenticate_user!
# GET /tracks
# GET /tracks.xml
def index
@tracks = Track.all

respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @tracks }
end
end
end

in my Track_controller_test.rb file i do something like:

class TracksControllerTest < ActionController::TestCase

test "should get index" do
login
get :index

assert_response :success
assert_not_nil assigns(:tracks)
end
end

So i keep getting redirected which means i am not being authenticated
as a logged in user.

Your doc's talk about scope or resource for the sign_in helper
method. what are they supposed to be? @user means nothing to me in
terms of the docs friends, as it's an instance variable of user i
guess... but is @user an instance of?

Anyone able to help get me passed this authenticate_user! before
filter in my tests. (needless to say the code itself works in a
browser).

Carlos A. da Silva

unread,
Dec 23, 2009, 11:44:11 AM12/23/09
to Devise
Hi,

Have you already added Devise::TestHelpers to your test case? You can
do this by putting the following code in your test_helper.rb:

class ActionController::TestCase
include Devise::TestHelpers
end

And yes, @user is the instance of some valid user you have.

pjammer

unread,
Dec 23, 2009, 11:53:45 AM12/23/09
to Devise
hi Carlos and thanks.

Yes i did put that in at the bottom of test_helper.rb.

I'm also using the devise gem 0.6.1 for reference.

here is a truncated version of my test_helper.rb file.

class ActiveSupport::TestCase


def login(user = users(:one))

sign_in user
end
end


class ActionController::TestCase
include Devise::TestHelpers
end

So i assume by passing a fixture to sign_in, and if that fixture is a
valid user, it should "pass" the authentication correct?

Here is my user.yml fixture i'm using... which i stole from my
User.first in script/console.

User.yml:
one:
email: m...@you.com
encrypted_password: be5d96b764da38099b7bdd255156e8b3c162c298
password_salt: onudpY9fYVuH6vtoSDiR
confirmation_token:
confirmed_at: <%= Time.now %>
confirmation_sent_at:
reset_password_token:
remember_token:
remember_created_at:

Am i doing something wrong code wise Carlos? Given all this info, how
would go about getting passed the before_filter?
thanks

On Dec 23, 11:44 am, "Carlos A. da Silva"

Carlos A. da Silva

unread,
Dec 23, 2009, 12:13:56 PM12/23/09
to Devise
Initially I'm not seeing anything wrong right now, and I'd ask you to
test with the last devise version, 0.7.4 and see what happen.

pjammer

unread,
Dec 23, 2009, 12:20:19 PM12/23/09
to Devise
no dice. Updated to the latest version, still the same thing.

how would i see if sign_in actually is working?

On Dec 23, 12:13 pm, "Carlos A. da Silva"

Carlos A. da Silva

unread,
Dec 23, 2009, 12:31:57 PM12/23/09
to Devise
Try creating a user by hand, something like:

@user = User.create!(
:email => 'us...@test.com',
:password => 'user123',
:password_confirmation => 'user123'
)

instead of using this fixture. I've created a fresh app here with the
following test:

class ProjectsControllerTest < ActionController::TestCase
include Devise::TestHelpers

def setup
user = User.create!(
:email => 'us...@test.com',
:password => 'user123',
:password_confirmation => 'user123'
)
sign_in user
end

test "should get index" do

get :index
assert_response :success
assert_not_nil assigns(:projects)
end
end

And everythink is working fine.

pjammer

unread,
Dec 23, 2009, 12:49:15 PM12/23/09
to Devise
So, i tried the following test and got this error:
----------- track_controller_test.rb ------------
#this works by the way.... is it because i have confirmable turned on?
test "does sign_in work" do
sign_in users(:one)
assert_response :success
assert @controller.instance_variable_set(:"@current_user", true)
end
#this gets the error still....

test "should get index" do
user = User.create!(
:email => 'ub...@test.com',

:password => 'user123',
:password_confirmation => 'user123'
)

sign_in user


get :index
assert_response :success
assert_not_nil assigns(:tracks)
end

------------------------
4) Error:
test_should_get_index(TracksControllerTest):
ActionView::TemplateError: Missing host to link to! Please
provide :host parameter or set default_url_options[:host]
On line #5 of /library/ruby/gems/1.8/gems/devise-0.7.4/app/views/
devise_mailer/confirmation_instructions.html.erb

2:
3: You can confirm your account through the link below:
4:
5: <%= link_to 'Confirm my account', confirmation_url
(@resource, :confirmation_token => @resource.confirmation_token) %>

(eval):20:in `user_confirmation_url'
(eval):11:in `send'
(eval):11:in `confirmation_url'
devise (0.7.4) app/views/devise_mailer/
confirmation_instructions.html.erb:5
devise (0.7.4) app/models/devise_mailer.rb:48:in
`render_with_scope'
devise (0.7.4) app/models/devise_mailer.rb:37:in `setup_mail'
devise (0.7.4) app/models/devise_mailer.rb:17:in
`confirmation_instructions'
devise (0.7.4) lib/devise/models/confirmable.rb:60:in
`send_confirmation_instructions'
/test/functional/tracks_controller_test.rb:12:in
`test_should_get_index'
...
rake (0.8.7) lib/rake/rake_test_loader.rb:5

So i added a test to see if i can see the current_user which would
mean it should pass, right? and it does.

Not sure where to go from here. without a before_filter passing it's
going to be hard to test.

On Dec 23, 12:31 pm, "Carlos A. da Silva"


<carlosantoniodasi...@gmail.com> wrote:
> Try creating a user by hand, something like:
>
>     @user = User.create!(

>       :email => 'u...@test.com',


>       :password => 'user123',
>       :password_confirmation => 'user123'
>     )
>
> instead of using this fixture. I've created a fresh app here with the
> following test:
>
> class ProjectsControllerTest < ActionController::TestCase
>   include Devise::TestHelpers
>
>   def setup
>     user = User.create!(

>       :email => 'u...@test.com',

Carlos A. da Silva

unread,
Dec 23, 2009, 12:58:05 PM12/23/09
to Devise
Your error:

ActionView::TemplateError: Missing host to link to! Please
provide :host parameter or set default_url_options[:host]

says you have to configure :host to ActionMailer, as you're using
Confirmable Devise will send an email after creating the user. Setup
in your test env:

config.action_mailer.default_url_options = { :host => 'localhost:
3000' }

It should be done for each environment.
Please make sure you run script/generate devise_install before
starting testing devise also.

pjammer

unread,
Dec 23, 2009, 1:34:28 PM12/23/09
to Devise
I've ran script/generate devise_install after i upgraded, reran the
test with the default url options as you have above, and i adopted it
for my passenger, but i got the same redirect error:

3) Failure:
test_should_get_edit(TracksControllerTest) [/test/functional/
tracks_controller_test.rb:44]:
Expected response to be a <:success>, but was <302>

I think it's creating the session fine and all that but there is
something in authenticate_user! that may not be passing it.

In your tests did you use the before_filter :authenticate_user! in
your projects controller?

On Dec 23, 12:58 pm, "Carlos A. da Silva"

Carlos A. da Silva

unread,
Dec 23, 2009, 1:44:13 PM12/23/09
to Devise
Yes, you can download the test app I've created here:

http://dl.dropbox.com/u/1540806/devisetest.tar.gz

please take a look at the code. Try commenting the sign_in in tests,
etc to see the errors.

José Valim

unread,
Dec 23, 2009, 2:33:28 PM12/23/09
to plataforma...@googlegroups.com
You are probably using confirmation and are not confirming your users before signing them in.

Please do:

user = User.create(valid_attributes)
user.confirm!
user

Notice that in such redirect cases, always check the flash message, they might tell you what is really happening.

Regards!
--
José Valim

Director of Engineering - Plataforma Tecnologia
http://blog.plataformatec.com.br/

pjammer

unread,
Dec 23, 2009, 4:18:41 PM12/23/09
to Devise
ok.

Loading a fixture didn't work for some reason, even a valid one, but
this ended up working instead:

def login


user = User.create!(
:email => 'ub...@test.com',
:password => 'user123',
:password_confirmation => 'user123'
)

sign_in user
user.confirm!
user
end

i use setup :login in my controller and it passes.

I also switched out the attributes above for a fixture, the same one i
posted up there, and the f@#cking thing works with user.confirm!

Very important step it appears.

HOWEVER, in your gunzip file you sent me devisetest... you didn't use
it and it worked. ODD.

while i care, i don't care too bad, since it works.
thanks all.

I'll blog about this more to get more of the word out there.

> ...
>
> read more »

pjammer

unread,
Dec 23, 2009, 5:34:33 PM12/23/09
to Devise
i just remember the devise :all... never mind, i know where we have
differences now.

thanks carlos and Jose.

> ...
>
> read more »

higuch...@gmail.com

unread,
Feb 4, 2010, 9:20:11 PM2/4/10
to Devise
Hi,
I am using 'confirmable', and I didn't find how to signed_in in rspec
controller.
Thanks for this thread, I found confirm! method and got success to
signed_in, after all.

So I'm happy if you add description about 'confirm!' around Test
Helper section in Devise's Readme.rdoc.

thanks.
naoto

> > > > > >ConfirmableDevise will send an email after creating the user. Setup

> ...
>
> read more »

José Valim

unread,
Feb 5, 2010, 10:14:42 AM2/5/10
to plataforma...@googlegroups.com
Could you please fork the project and update the README?

Ping me when you are done and I will gladly pull in your changes! :)
--
José Valim

Director of Engineering - Plataforma Tecnologia
Know more about us: http://plataformatec.com.br/en/
Reply all
Reply to author
Forward
0 new messages