I always seem to overlook testing. For one reason or another, it is really easy to forget about. But before getting too far into a project, it is a good idea to make sure you have some tests and that they are passing. Getting the initial tests to pass will be the focus of this post. The problem I have run into with restful_authentication is that the tests have not been updated for rails 2.0. Updating those tests to pass will be the subject of this post.
If you haven’t already, add the line ‘include AuthenticatedTestHelper’ to the bottom of the test/test_helper.rb file.
Before moving on, lets see where we stand with the current test cases. Here are my results
rake
...
...
1) Failure:
test_should_initialize_activation_code_upon_creation(UserTest) [./test/unit/user_test.rb:18]:
24 tests, 42 assertions, 1 failures, 0 errors
Not a bad start. In my first post about restful_authentication, I changed what happens when users create accounts. This tests makes sure there is an activation code after creation, but is not needed now. To solve this, I’m just going to comment out that particular test and create a test that passes when the activation code is nil after creation. The test is almost identical and looks like this
def test_should_not_initialize_activation_code_upon_creation user = create_user assert_nil user.reload.activation_code end
All tests now pass, but we are not finished. Lets add the admin_required filter to the articles controller except for the show and index actions and rerun the tests.
class ArticlesController < ApplicationController before_filter :admin_required, :except => [:index, :show]
rake
...
...
1) Failure:
test_should_create_article(ArticlesControllerTest)
<3> expected but was
<2>.
2) Failure:
test_should_destroy_article(ArticlesControllerTest)
<1> expected but was
<2>.
3) Failure:
test_should_get_edit(ArticlesControllerTest)
Expected response to be a <:success>, but was <302>
4) Failure:
test_should_get_new(ArticlesControllerTest)
Expected response to be a <:success>, but was <302>
5) Failure:
test_should_update_article(ArticlesControllerTest)
expected a redirect to <{"action"=>"index", "controller"=>"articles"}>, found one to <{"action"=>"new", "controller"=>"sessions"}>, a difference of <{"action"=>"new", "controller"=>"sessions"}>
26 tests, 43 assertions, 5 failures, 0 errors
The unit tests still pass, but the functional tests now get 5 failures
From here, the next thing to do is change the restful_authentication test code to the rails 2.0 way. Open up your users fixture and change it to this
quentin: login: quentin email: quentin@example.com salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test created_at: <%= 5.days.ago.to_s :db %> activated_at: <%= 5.days.ago.to_s :db %> state: active role: administrator aaron: login: aaron email: aaron@example.com salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test created_at: <%= 1.days.ago.to_s :db %> activated_at: <%= 1.days.ago.to_s :db %> state: active role: subscriber
All I did was delete the id and activation code. Next thing to do is modify the sessions and users controller test files. The tests themselves to not need to be changed, just the top portion. Posted below is what your edited files will look like through the first test. As you can see, all the stuff that rails now does automatically has been removed and the controller tests changed from Test::Unit::TestCase to ActionController::TestCase.
# test/functional/users_controller_test.rb
require File.dirname(__FILE__) + '/../test_helper'
class UsersControllerTest < ActionController::TestCase
def test_should_allow_signup
assert_difference 'User.count' do
create_user
assert_response :redirect
end
end
# test/functional/sessions_controller_test.rb
require File.dirname(__FILE__) + '/../test_helper'
class SessionsControllerTest < ActionController::TestCase
def test_should_login_and_redirect
post :create, :login => 'quentin', :password => 'test'
assert session[:user_id]
assert_response :redirect
end
For our articles tests, we now need to login_as :quentin for the tests that require admin privileges. Add that line to the top of the five test cases that require admin privileges and all those tests pass. The only test that fails now is the the test_should_activate_user(UsersControllerTest), but like the first test failure, is not needed anymore.
It might also be a good idea to add in the tests that make sure users can’t do things without the required privileges. Here are the five I added to make sure only authorized users can create and edit articles
def test_should_not_get_new
get :new
assert_redirected_to login_path
end
def test_should_not_create_article
assert_difference('Article.count', 0) do
post :create, :article => { :title => "title one", :body => "body one" }
end
end
def test_should_not_get_edit
get :edit, :id => articles(:one).id
assert_redirected_to login_path
end
def test_should_not_update_article
put :update, :id => articles(:one).id, :article => {:title => "this is the new title"}
assert_redirected_to login_path
end
def test_should_not_destroy_article
assert_difference('Article.count', 0) do
delete :destroy, :id => articles(:one).id
end
assert_redirected_to login_path
end
Of course, it is a good idea to make sure only admins can create and edit articles and that subscribers cannot. That will be left for you when you to complete.
Since I’ve been trying to keep this discussion to restful_authentication, I haven’t really touched on the articles model. I just want to mention though, I am making the assumption that an article model will always need a title and body. Because of this, I added the validates_presence_of :title, :body line to my model.
That should be enough to get your tests passing. Eventually, this info will be obsolete, but until then, this should help.
Tags: functional tests, restful_authentication
One Response
Jason
May 16th, 2008 at 8:29 am
1I was wondering how you are getting your test to run with “role: administrator” in your user fixture? When I try it, using restful_authentication having followed this http://www.railsforum.com/viewtopic.php?id=14216&p=1, I get an error because :role isn’t defined in my user model as its another table/model.
When I don’t use the “role: administrator” I am getting 302 errors because my test isn’t :success because I am being redirected for not logging in.
I have tried to use login_as :quinten, but that doesn’t help because some of my controller actions require you to be an admin.
I am going nuts trying to figure this out and I can’t find any documentation or info besides this post.
Thanks in advance for your help.
RSS feed for comments on this post · TrackBack URI
Leave a reply