Перенаправление Devise + CanCan AccessDenied отличается между средой разработки и тестирования - PullRequest
0 голосов
/ 12 августа 2011

У меня есть приложение Rails 3.1 (RC5) с Devise и CanCan. Оба настроены хорошо и работают как положено, за исключением того, что когда я запускаю интеграционные тесты, чтобы убедиться, что AccessDenied перенаправляется по желанию, перенаправление переходит к входу Devise вместо корня приложения. В своем тесте я могу убедиться, что пользователь все еще вошел в систему и может получить доступ к соответствующим частям приложения.

В этом коротком контроллере определено перенаправление, которое наследуют другие ограниченные контроллеры (вместо прямого наследования ApplicationController).

class AuthorizedController < ApplicationController
  before_filter :authenticate_user!

  rescue_from CanCan::AccessDenied do |exception|
    redirect_to root_url, :alert => exception.message
  end
end

Ограниченные контроллеры выглядят так:

class Admin::UsersController < AuthorizedController
  load_and_authorize_resource
  def index
    @users = User.all.order('name')
  end
  ...
end

Я использую тест интеграции по умолчанию (ActionDispatch :: IntegrationTest); Единственные дополнительные драгоценности для тестирования, которые у меня есть, это Капибара, Машинист и Фейкер (без RSpec, Cucumber и т. д.).

Мой тест выглядит так:

def test_user_permissions
  sign_in users(:user)
  get admin_users_path
  assert_response :redirect
  assert_redirected_to root_url
end

Тест не пройден с:

Expected response to be a redirect to <http://www.example.com/> but was a redirect to <http://www.example.com/users/sign_in>

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

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

Приложение и решение:

Изначально я не включал метод sign_in, который содержал ключ подсказки. Вот оно:

module ActionController
  class IntegrationTest
    include Capybara::DSL
    def sign_in (user, password = 'Passw0rd')
      sign_out
      visit root_path
      fill_in 'Email',    :with => user.email
      fill_in 'Password', :with => password
      click_button 'Sign in'
      signed_in? user
    end
    ...
  end
end

Я смешивал в тесте методы доступа Capybara (visit, click_button и т. Д.) В sign_in и методы доступа к тесту интеграции ванили (get и т. Д.). Когда я использовал Webrat (до Capybara), это микширование работало так, как я ожидал, но, очевидно, состояние сеанса Capybara обрабатывается отдельно, поэтому доступ через методы Capybara был аутентифицирован, а доступ через методы тестирования ванильной интеграции не был.

1 Ответ

1 голос
/ 22 августа 2011

Вы не опубликовали свою конфигурацию devise в ApplicationController, но похоже, что проверки устройства Identity / Sign-in загружаются перед проверками CanCan Authorization (что имеет смысл).

Похоже, что ваш тестовый вход в настройке работает неправильно, потому что '/ users / sign_in' - это перенаправление по умолчанию для устройства, когда нет действительного сеанса пользователя.

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

before_filters будет выполняться из базового ApplicationController первым по цепочке в порядке их определения, поэтому подклассы фильтруют после фильтров базового класса. Вот почему я думаю, что в вашем базовом ApplicationController есть конфигурация Devise, которая не позволяет CanCan работать.

Если вы опубликуете свой конфигурационный код / ​​код Devise, мы сможем помочь вам в дальнейшей его отладке.

РЕДАКТИРОВАТЬ / TLDR:

Вы видите перенаправление на вход в систему, поскольку Devise не считает, что существует действительный сеанс пользователя. Ваш тестовый помощник sign_in () работает не так, как вы думаете. Вот почему это работает в режиме разработки с живой сессией пользователя через ручной вход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...