Agile Outsourcing, from Idea to tested Software

Rails 3: Functional controller testing when using devise and declarative authorization gems 28 Jun 11

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

One has to give it to the developers of devise and declarative authorization, they have really created extremely useful gems. As we are using these gems extensively in our own product and also for client products and projects, we also need to test them. Now both gems offer very helpful test helpers which need just a little bit of help to work together. The issue arises if a controller takes advantage of both gems where we found ourselves faced with disappearing session values after signing in with devise. But after digging a little bit in the declarative authorization source code, we found how to make the two gems work together for testing. The same post can also be found on Github


Below code example seems to work for Rails 3.0.6, devise 1.1.5, declarative authorization 0.5.3.


The sign_in test helper from devise adds the key/value pair “warden.user.user.key” => ["User",id] to the session and one has to explicitly add the session to the declarative_authorization get_with helper. The *_with methods call the request_with method which defaults the session argument to an empty hash unless one explicitly provides the session.


And without the above mentioned key/value pair in the session when calling get_with, one will not get past devise’s authenticate_user! before filter.


The following test in the users_controller_test.rb works when trying to access the users_controller show action which is included in the filter_resource_access and has an appropriate rule listed in the authorization rules:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#config/authorization_rules.rb
role :authenticated do
    has_permission_on :users, :to => [:show] do
      if_attribute :id => is { user.id}
    end
end

#app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_filter :authenticate_user!
  filter_resource_access

  def show    #@user is already loaded through filter_resource_access method of the declarative_authorization gem
    respond_to do |format|
      format.html  { render :action => :show}
    end
  end
end

# test/test_helper.rb
ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require 'declarative_authorization/maintenance'
require 'rails/test_help'

class ActiveSupport::TestCase
  include Authorization::TestHelper
  fixtures :all
end

# test/functional/user_controller_test.rb
require 'test_helper'

class UsersControllerTest < ActionController::TestCase
  include Devise::TestHelpers
  setup do
    @user = users(:authenticated)  #this user must obviously have symbol :authenticated as an element of the role_symbols array
   end

  test "should get to show action if current user is equal to the called resource" do
    sign_in @user
    get_with @user, :show,{:id=> @user.id}, session #this is where the session from sign_in is added to get_with
    assert_response :success
  end
end

Leave a Reply