【问题标题】:Testing Admin Authorization测试管理员授权
【发布时间】:2015-06-13 21:10:57
【问题描述】:

身份验证完全是从头开始,目标是在我使用它的同时测试所有内容。我创建了一个只有管理员才能访问的管理仪表板,但我的测试给了我以下错误:

  1) Admin::DashboardController GET index with correct credentials returns http success
     Failure/Error: get :index
     NoMethodError:
       undefined method `admin?' for nil:NilClass

通过阅读源于相同错误的问题。看起来它可能是 current_user 实际上返回 nil,但是当我尝试将 current_user 的会话设置为 user 变量时,我仍然遇到同样的错误。我也尝试过对current_user 存根,但仍然遇到相同的错误。

这是规格:

dashboard_controller_spec.rb

describe "GET index" do
    before(:each) do
        allow(controller).to receive(:require_auth)
        allow(controller).to receive(:current_user)
end

context "with correct credentials" do
    it "returns http success" do
      user = create(:admin)
      session[user_id: user]
      get :index 
      expect(response).to have_http_status(:success)
    end
end

dashboard_controller.rb

class Admin::DashboardController < ApplicationController
    before_action :require_admin
    before_action :require_auth

  def index
  end
end

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  add_flash_types :success, :error

  private
  helper_method :current_user
  helper_method :logged_in?

  def logged_in?
    current_user
  end

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
    rescue ActiveRecord::RecordNotFound
  end

  def require_auth
    unless current_user
      session[:target] = request.fullpath
      redirect_to new_user_session_path, 
        notice: "You must be logged in to access that page."
    end
  end

  def require_admin
    unless current_user.admin?
      redirect_to :back, 
        notice: "Access denied."
    end
  end
end

【问题讨论】:

  • 如果您使用的是 Devise,它会为您提供可用于在控制器中登录和注销的助手。 test helpers
  • 我正在从头开始构建我的身份验证,作为身份验证/授权如何工作以及 TDD/BDD 的学习经验。

标签: ruby-on-rails authentication rspec admin factory-bot


【解决方案1】:

也许您应该在会话中存储 user.id 而不是 user:

context "with correct credentials" do
it "returns http success" do
  user = create(:admin)
  get :index, nil, {user_id: user.id}
  expect(response).to have_http_status(:success)
end
end

另外,作为旁注,redirect_to :back 仅在浏览器发送有关推荐人的信息时有效,但并非总是如此。 IE。隐私模式下的 Firefox 没有。

【讨论】:

  • 感谢您的回复以及redirect_to :back 上的旁注。不幸的是,我仍然收到同样的错误..
  • @Shroy,在这种情况下,我建议尝试不同的方法来设置会话。在此处查看选择的答案:stackoverflow.com/questions/22451969/rspec-set-session-object
  • 尝试了许多这些组合,但仍然出现错误。有趣的是我在设置session[user_id: user.id 后添加了expect(session[:user_id]).to eq(user.id) 以查看它输出的内容并收到此错误:expected: 2 got: nil (compared using ==)
  • @Shroy,好吧,至少我们知道为什么 current_user 返回 nil。那是因为 session 由于某种原因也为零。可能是before 块中的存根导致了这种情况吗?您是否尝试删除它们?
  • 据我所知,存根控制器方法的正确语法是allow(controller).to receive(:method).and_return(something)。所以我想省略and_return 部分可能很像current_user 返回nil 的原因。此外,这是 rails 3 语法。在 rails 4 中,您应该改用 stub。另一个注意事项:find_by_id 在没有找到任何东西时不会生成异常,因此您不必拯救它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 2015-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多