Bypassing CanCan :: AccessDenied when running RSpec tests
I am trying to run strong parameter tests for my model Restaurant
and I am facing an error that does not evolve during development. In my controller, I have a CanCan method load_and_authorize_resource
that only allows admins to create, update and destroy these model instances:
class RestaurantsController < ApplicationController
load_and_authorize_resource param_method: :restaurant_params, find_by: :slug
...
end
When it comes to running tests, I get the error:
1) RestaurantsController should permit POST #create to receive parameters :name
Failure/Error: should permit(:name).
CanCan::AccessDenied:
You are not authorized to access this page.
Is there an easy way to get around this permission? I've looked at all of this and there doesn't seem to be a clear answer.
Test
describe RestaurantsController do
let(:user) { FactoryGirl.create(:user, admin: true) }
it { should permit(:name).for(:create) }
end
NOTE. I reviewed the docs on CanCan and they say to instantiate a user with its admin attribute set to true. Even with that, I am still a little confused about how to insert this user into my test.
source to share
After some research, I've come to the conclusion that the best way to get around this has more to do with logging my User
factory through Devise more than the CanCanCan gem itself.
Depending on your setup, this might change, but for my user factory, I have an attribute admin
set to true
.
user.rb
FactoryGirl.define do
factory :user do
first_name "John"
last_name "Doe"
email "john@example.com"
password "password"
admin true
end
end
Then I created a subdirectory in my spec
named folder support
and followed the example in the Devise link provided to create the appropriate module method for the user to login:
specs / support / controller_macros.rb
module ControllerMacros
def login_admin
before(:each) do
@request.env["devise.mapping"] = Devise.mappings[:admin]
sign_in FactoryGirl.create(:user)
end
end
end
Then in my rails_helper
file, I just extended this module to use the method login_admin
. The DID NOT example mentioned that you need a require
file controller_macros
in this helper. This may be misunderstood by some, but could potentially be overlooked if not careful:
specs / rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'support/controller_macros'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
....
config.include Devise::TestHelpers, type: :controller
config.extend ControllerMacros, type: :controller
end
Finally, in your controller tests, just apply the method login_admin
where needed:
Restaurant Controller Testers
describe RestaurantsController do
login_admin
it { should permit(:name).for(:create) }
end
source to share