在Rails中测试授权的问题

时间:2013-10-25 16:17:57

标签: ruby-on-rails ruby rspec authorization

我正在尝试在我自己的应用程序中从头开始实现Railscasts授权,但是我遇到了自定义匹配器和测试的简单问题。我得到错误的参数错误,我似乎无法弄清楚原因。

我创建了一个单独的Permission模型来保存所有逻辑,在这个模型中有一个allow?方法。这就是所有逻辑的所在。我通过浏览器手动测试了它,但是由于参数数量错误,我的单元测试失败了

wrong number of arguments (2 for 1)

这是权限模型

class Permission < Struct.new(:user)
  def allow?(controller, action)
    return true if controller == 'sessions'
    return true if controller == 'users' && action.in?(%w[new create])
    if user && user.teams.nil?
      return true if controller == 'users' && action.in?(%w[new index show edit update])
      return true if controller == 'teams' && action.in?(%w[new create index])
      return true if controller == 'user_teams' && action.in?(%w[index])
    elsif user && !user.teams.nil?
      return true if controller == 'users' && action.in?(%w[index show edit update])
      return true if controller == 'teams' && action.in?(%w[new create index show])
      return true if controller == 'user_teams' && action.in?(%w[index])
      return true if controller == 'texts' && action.in?(%w[new create index show])
      return true if controller == 'translations' && action.in?(%w[show])

    end
  end
end

这是位于spec/support/matchers/allow.rb

中的自定义匹配器的代码
RSpec::Matchers.define :allow do |*args|
  match do |permission|
    permission.allow?(*args).should be_true
  end

  failure_message_for_should do |permission|
    "expected to have permission for these actions"
  end

  failure_message_for_should_not do |permission|
    "expected to not have permission for these actions"
  end

  description do 
    "allow access to the %{*args} actions"
  end
end

这是我的应用程序控制器

class ApplicationController < ActionController::Base
  before_filter :authorize
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  include SessionsHelper
  include UserTeamsHelper

  add_flash_types :success, :danger 

  private

  def current_permission
    @current_permission ||= Permission.new(current_user)
  end

  def authorize
    if !current_permission.allow?(params[:controller], params[:action])
      redirect_to root_url, danger: 'Önce Giriş Yapmalısınız'
    end
  end

end

这是Permission模型的测试

require "spec_helper"

describe Permission do 
  describe 'as a non user' do 
    subject { Permission.new(nil) } 
    it { should allow("sessions", "new") } 
  end
end

但它不起作用,因为我得到错误数量的参数错误。有人能指出我正确的测试方法吗?

这是我得到的测试失败

Failures:

  1) Permission as a non user
     Failure/Error: it { should allow("sessions", "new") }
     ArgumentError:
       wrong number of arguments (2 for 1)
     # ./spec/models/permission_spec.rb:6:in `block (3 levels) in <top (required)>'

Finished in 0.07471 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/models/permission_spec.rb:6 # Permission as a non user

1 个答案:

答案 0 :(得分:1)

allowhttps://github.com/rspec/rspec-mocks/blob/fd78578d0d65a7917701c4410a0eb9089ee6636f/lib/rspec/mocks/syntax.rb中定义的RSpec方法,它接受一个参数。这就是你收到这个错误的原因。

您可以通过执行以下示例来验证这一点:

describe "RSpec allow method" do
  it "should exist" do
    puts method(:allow)
    puts method(:allow).source_location
  end
end

应生成如下内容:

#<Method: RSpec::Core::ExampleGroup::Nested_1(RSpec::Mocks::ExampleMethods)#allow>
/Users/palfvin/.rvm/gems/ruby-2.0.0-p247@botmetrics/gems/rspec-mocks-2.14.3/lib/rspec/mocks/syntax.rb 117

如果您使用不同的匹配器名称,我认为您没问题。