Оставаться высохнуть при тестировании контроллера, уполномоченного через Cancan

StackOverflow https://stackoverflow.com/questions/4047085

  •  27-09-2019
  •  | 
  •  

Вопрос

Я ретроактивно пишу некоторые тесты, используя RSPEC, для проекта Rails.

Я использую GEM CANCAN, чтобы обеспечить авторизацию. Я решил написать спецификацию, который проверит ability.rb модель. Затем я продолжал проверить мои оставшиеся модели.

Я переехал на контроллеры, и я столкнулся с огромным загрязнением: я постоянно проверяю свои способности!

В принципе, я должен заглушить серию моделей, а выкупить их ассоциации; В противном случае ответ просто возвращает 403 Forbidden.
Причина этого, состоит в том, что контроллер в основном отвечает на беспокойство о разрешении.

Я не совсем уверен, отсюда отсюда. Я окунул до 6 моделей, просто чтобы написать один тест. я знать способности работают, вот что ability_spec.rb это для.

Так что этот вопрос действительно в 2 раза:

  1. Должен ли я проверять модель способностей отдельно?
  2. Если тесты контроллера будут обеспокоены правильными разрешениями?

РедактироватьТребовать «SPEC_HELPER» включает в себя разработку :: TestheelPers #, чтобы дать вашему спектру доступа к помощникам

describe TokensController do
  before(:each) do
    @mock_user = User.new(:username => "bob", :email => "user@user.com", :password => "longpassword")
    @mock_user.role = "admin"
    sign_in @mock_user
    #Ability.stub!('can').and_return(true)
  end
  it "should let me see grids/:g_id/tokens index" do
    test_grid = mock_model(Grid)
    test_token = mock_model(Token)
    Grid.stub!(:find).and_return(test_grid)
    Token.stub!(:find).and_return(test_token)
    get 'index'

    a1 = Ability.new(@mock_user)
    a1.can?(:index, Token).should be_true # This line works fine; as it should
    puts response.status #This returns 403, which means CanCan::AccessDenied was raised
  end
end

Спасибо,
Робби

Это было полезно?

Решение

Я проверяю модель Канкина отдельно, но тестирование того, что она позволит в каких условиях.

Я думаю, что если вы делаете такие вещи, как

authorize! :take_over, @the_world

Тогда я думаю, что вы должны тестировать, что в контроллере. Я не уверен, что вам нужно проверить все 6 версий ваших моделей, хотя.

Вы можете опубликовать возможности. Класс и имейте это отвечать TRUE / FALSE и проверить, как ваш контроллер обрабатывает, когда он может (и более важно), когда он не может продолжаться.

Другие советы

Не уверен, что это слишком поздно для вас, но я просто бежал в ту же проблему, и решил его, используя следующий образец кода -

before do
  @user = Factory.create(:user)
    sign_in @user

    @abilities = Ability.new(@user)
    Ability.stub(:new).and_return(@abilities)
  end
end

Я уконул способность # Новое, давая мне ссылку на экземпляр способности, которые контролирует текущий пользователь. Затем я могу заглушить конкретные способности, такие как это:

@abilities.stub!(:can?).with(:destroy, regatta).and_return(true)

или дать админские привилегии:

@abilities.stub!(:can?).and_return(false)

Подобно ответу Сэма, но с страницы Cancan Wiki по тестированию:

Тестирование контроллера

Если вы хотите протестировать функциональность авторизации на уровне контроллера, один вариант должен войти в систему пользователя, у которого есть соответствующие разрешения.

user = User.create!(:admin => true) # I recommend a factory for this
# log in user however you like, alternatively stub `current_user` method
session[:user_id] = user.id 
get :index
assert_template :index # render the template since he should have access

В качестве альтернативы, если вы хотите проверить поведение контроллера независимо от того, что находится внутри класса способностей, легко заглушить способность с любым поведением.

def setup
  @ability = Object.new
  @ability.extend(CanCan::Ability)
  @controller.stubs(:current_ability).returns(@ability)
end

test "render index if have read ability on project" do
  @ability.can :read, Project
  get :index
  assert_template :index
end

Если у вас есть очень сложные разрешения, это может привести к многим возможностям разветвлений. Если все это тестируются в слое контроллера, то он может привести к медленному и раздутому тестам. Вместо этого я рекомендую поддерживать контроллер авторизации тестов и тестировать функциональность авторизации более тщательно в модели возможностей через модульные тесты, как показано на вершине.

Я думаю, что разрешение должно быть сделано в основном для контроллеры Чтобы убедиться, что ваша авторизация работает правильно с вашими контроллерами. Так что сделать это СУХОЙ Вы можете реализовать свой собственный matcher использоваться как это

let!(:user) {create :user}
before { login_user_request user}

it "grants admin access to show action" do
  expect{ get :show, {id: user.id} }.to be_authorized
end
it "denies user access to edit action" do
  expect{ get :edit, {id: user.id} }.to be_un_authorized
end

а затем реализовать эти почтовые письма по своему собственному тестированию, как запрос будет авторизован или нет

RSpec::Matchers.define :be_authorized do
  match do |block|
    block.call
    expect(response).to be_success
  end

  def supports_block_expectations?
    true
  end
end

RSpec::Matchers.define :be_un_authorized do
  match do |block|
    expect{
      block.call
    }.to raise_error(Pundit::NotAuthorizedError)
  end

  def supports_block_expectations?
    true
  end
end

Почему бы вам не включить

can :manage, :all do
  user.is_ultrasuper == 1
end

В ваших возможностях, а затем есть PARAM IS_ULTRASUPER в одном из ваших пользователей крепежа:

one: 
  id: 1 
  username: my_username 
  is_ultrasuper: 1

Затем войдите в систему этого пользователя при настройке ваших тестов. Это в тестах вы сможете вообще ничего делать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top