class ActionPolicy::RSpec::HaveAuthorizedScope
Implements `have_authorized_scope` matcher.
Verifies that a block of code applies authorization scoping using specific policy.
Example:
# in controller/request specs subject { get :index } it "has authorized scope" do expect { subject } .to have_authorized_scope(:active_record_relation) .with(ProductPolicy) end
Attributes
actual_scopes[R]
name[R]
policy[R]
scope_options[R]
target_expectations[R]
type[R]
Public Class Methods
new(type)
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 26 def initialize(type) @type = type @name = :default @scope_options = nil end
Public Instance Methods
actual_scopes_message()
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 100 def actual_scopes_message if actual_scopes.empty? "no scopings have been made" else "the following scopings were encountered:\n" \ "#{formatted_scopings}" end end
as(name)
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 37 def as(name) @name = name self end
does_not_match?(*)
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 74 def does_not_match?(*) raise "This matcher doesn't support negation" end
failure_message()
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 80 def failure_message "expected a scoping named :#{name} for type :#{type} " \ "#{scope_options_message} " \ "from #{policy} to have been applied, " \ "but #{actual_scopes_message}" end
formatted_scopings()
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 109 def formatted_scopings actual_scopes.map do " - #{_1.inspect}" end.join("\n") end
match(_expected, actual)
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 52 def match(_expected, actual) raise "This matcher only supports block expectations" unless actual.is_a?(Proc) ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call } @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options) } return false if matching_scopes.empty? return true unless target_expectations if matching_scopes.size > 1 raise "Too many matching scopings (#{matching_scopes.size}), " \ "you can run `.with_target` only when there is the only one match" end target_expectations.call(matching_scopes.first.target) true end
scope_options_message()
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 87 def scope_options_message if scope_options if defined?(::RSpec::Matchers::Composable) && scope_options.is_a?(::RSpec::Matchers::Composable) "with scope options #{scope_options.description}" else "with scope options #{scope_options}" end else "without scope options" end end
supports_block_expectations?()
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 78 def supports_block_expectations?() = true def failure_message "expected a scoping named :#{name} for type :#{type} " \ "#{scope_options_message} " \ "from #{policy} to have been applied, " \ "but #{actual_scopes_message}" end def scope_options_message if scope_options if defined?(::RSpec::Matchers::Composable) && scope_options.is_a?(::RSpec::Matchers::Composable) "with scope options #{scope_options.description}" else "with scope options #{scope_options}" end else "without scope options" end end def actual_scopes_message if actual_scopes.empty? "no scopings have been made" else "the following scopings were encountered:\n" \ "#{formatted_scopings}" end end def formatted_scopings actual_scopes.map do " - #{_1.inspect}" end.join("\n") end end
with(policy)
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 32 def with(policy) @policy = policy self end
with_scope_options(scope_options)
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 42 def with_scope_options(scope_options) @scope_options = scope_options self end
with_target(&block)
click to toggle source
# File lib/action_policy/rspec/have_authorized_scope.rb, line 47 def with_target(&block) @target_expectations = block self end