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.

+3


source to share


2 answers


I have bypassed the cancan load_and_authorize_resource

call with the following as I intend to test the abilities separately.



before { allow_any_instance_of(CanCan::ControllerResource).to receive(:load_and_authorize_resource){ nil } }

      

+2


source


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

      

+1


source







All Articles