There is a subtle difference in your question. Authorization usually refers to the permissions that users have in the application. Authentication referrers for users registering and registering users.
As for Authentication , I usually prefer to use integration/requests or acceptance/feature specs . Recently, feature specifications have been particularly preferred, since Capybara DSL ( page and visit ) are only available in feature specifications. Previously, they were allowed in query specifications prior to update 2.x.
I will test things like registration, login and shutdown. For instance,
# signing_up_spec.rb feature 'Signing up' do scenario 'Successful sign up' do visit '/' within 'nav' do click_link 'Sign up' end fill_in "Email", :with => " user@ticketee.com " fill_in "Password", :with => "password" fill_in "Password confirmation", :with => "password" click_button "Sign up" page.should have_content("Please open the link to activate your account.") end end
This allows you to test a higher level aspect and allows you to see the various components (controllers, views, etc.) in your application, working together. This is by definition an integration test / acceptance test. I would do the same as above for signing_in_spec.rb and signing_out_spec.rb
Now for Authorization I would choose to use controller specifications. This allows you to check the individual actions that the user has for access. These controller specifications are more granular in nature and, by definition, are unit / function tests. For example, let's say you have a resource for a ticket, and you want to verify that only certain users can access a specific function.
# tickets_controller_spec.rb describe TicketsController do let(:user) { FactoryGirl.create(:confirmed_user) } let(:project) { FactoryGirl.create(:project) } let(:ticket) { FactoryGirl.create(:ticket, :project => project, :user => user) } context "standard users" do it "cannot access a ticket for a project" do sign_in(:user, user) get :show, :id => ticket.id, :project_id => project.id response.should redirect_to(root_path) flash[:alert].should eql("The project you were looking for could not be found.") end context "with permission to view the project" do before do sign_in(:user, user) define_permission!(user, "view", project) end def cannot_create_tickets! response.should redirect_to(project) flash[:alert].should eql("You cannot create tickets on this project.") end def cannot_update_tickets! response.should redirect_to(project) flash[:alert].should eql("You cannot edit tickets on this project.") end it "cannot begin to create a ticket" do get :new, :project_id => project.id cannot_create_tickets! end it "cannot create a ticket without permission" do post :create, :project_id => project.id cannot_create_tickets! end it "cannot edit a ticket without permission" do get :edit, { :project_id => project.id, :id => ticket.id } cannot_update_tickets! end it "cannot update a ticket without permission" do put :update, { :project_id => project.id, :id => ticket.id, :ticket => {} } cannot_update_tickets! end it "cannot delete a ticket without permission" do delete :destroy, { :project_id => project.id, :id => ticket.id } response.should redirect_to(project) flash[:alert].should eql("You cannot delete tickets from this project.") end it "can create tickets, but not tag them" do Permission.create(:user => user, :thing => project, :action => "create tickets") post :create, :ticket => { :title => "New ticket!", :description => "Brand spankin' new", :tag_names => "these are tags" }, :project_id => project.id Ticket.last.tags.should be_empty end end end end
I found that the combination of rspec-rails , capybara and factory_girl_rails worked well in both types of testing in rails applications.
The above examples were taken from the Rails3Book repository on github . Take a look at the repo for more examples. This is a great way to see the features that you have when testing a rails application.