Search code examples
ruby-on-railsruby-on-rails-3rspeccancancancancan

RSpec and Cancancan: all negative tests failing


Can anyone help me to understand why only my negative (i.e., should_not) tests would be failing? All my should tests are passing, so it makes me think I've got some configuration thing wrong, although what I've no idea.

ability.rb

# encoding: utf-8
#
class Ability
  include CanCan::Ability

  def initialize(user)
    @user = user || User.new
    if @user.administrator?
      administrator_abilities
    elsif @user.client?
      client_abilities
    elsif @user.guest?
      guest_abilities
    end
    can :read, :share
  end

  private

  def administrator_abilities
    can :manage, :all
    can [:index, :filter, :new, :create], :administration
  end

  def client_abilities
    cannot :manage, administrator_resources
    can :manage, [:account, :provider_auth, :user_auth]
    can :read, [Component, Cover, Introduction, Template]
    can :manage, client_made_resources, user_id: @user.id
  end

  def guest_abilities
    cannot :manage, client_made_resources
    cannot :manage, administrator_resources
    can :create, Expression
  end

  def client_made_resources
    [Authorisation, Document, Component,
     CustomArticle, EditedArticle, Invoice, Order, Photo]
  end

  def administrator_resources
    [Brand, Chart, Component, Cover, Expression, Introduction, Mode,
     Preference, Price, Template, User, UserNote]
  end
end

user_spec.rb

# encoding: utf-8
#
require 'spec_helper'
require 'cancan/matchers'
def client_made_resources
  [Authorisation, Document, Component, CustomArticle, EditedArticle, Invoice,
   Order, Photo]
end

def administrator_resources
  [Brand, Chart, Component, Cover, Expression, Introduction, Mode, Preference,
   Price, Template, User, UserNote]
end

RSpec.describe Ability do
  let(:user) { create(:user, state: 'guest') }
  subject    { Ability.new(user) }

  context 'guest' do
    client_made_resources.each do |r|
      it "should not be able to manage client's #{r}" do
        expect(subject).to_not be_able_to(:manage, r.new)
      end
    end

Every negative test has this result:

rspec ./spec/models/user_spec.rb:69 # Ability guest should not be able to manage client's Document

Thanks for your help.


Solution

  • I have no idea why but I've refactored my tests and they now work as expected. Maybe this'll help someone.

    RSpec.describe User do
      describe 'Abilities' do
        context 'guest' do
          let(:user) { create(:user, state: 'guest') }
          (client_made_resources + administrator_resources).each do |r|
            it "cannot manage #{r}" do
              ability = Ability.new(user)
              assert ability.cannot?(:manage, r.new)
            end
          end
    
          it 'can read shares' do
            ability = Ability.new(user)
            assert ability.can?(:read, :share)
          end
    ...