class ActionPolicy::RSpec::BeAuthorizedTo

Authorization matcher `be_authorized_to`.

Verifies that a block of code has been authorized using specific policy.

Example:

# in controller/request specs
subject { patch :update, id: product.id }

it "is authorized" do
  expect { subject }
    .to be_authorized_to(:manage?, product)
    .with(ProductPolicy)
end

Attributes

actual_calls[R]
policy[R]
rule[R]
target[R]

Public Class Methods

new(rule, target) click to toggle source
# File lib/action_policy/rspec/be_authorized_to.rb, line 25
def initialize(rule, target)
  @rule = rule
  @target = target
end

Public Instance Methods

actual_calls_message() click to toggle source
# File lib/action_policy/rspec/be_authorized_to.rb, line 63
def actual_calls_message
  if actual_calls.empty?
    "no authorization calls have been made"
  else
    "the following calls were encountered:\n" \
    "#{formatted_calls}"
  end
end
does_not_match?(*) click to toggle source
# File lib/action_policy/rspec/be_authorized_to.rb, line 51
def does_not_match?(*)
  raise "This matcher doesn't support negation"
end
failure_message() click to toggle source
# File lib/action_policy/rspec/be_authorized_to.rb, line 57
def failure_message
  "expected #{formatted_record} " \
  "to be authorized with #{policy}##{rule}, " \
  "but #{actual_calls_message}"
end
formatted_calls() click to toggle source
# File lib/action_policy/rspec/be_authorized_to.rb, line 72
def formatted_calls
  actual_calls.map do
    " - #{_1.inspect}"
  end.join("\n")
end
formatted_record(record = target) click to toggle source
# File lib/action_policy/rspec/be_authorized_to.rb, line 78
  def formatted_record(record = target) = ::RSpec::Support::ObjectFormatter.format(record)
end
match(_expected, actual) click to toggle source
# File lib/action_policy/rspec/be_authorized_to.rb, line 35
def match(_expected, actual)
  raise "This matcher only supports block expectations" unless actual.is_a?(Proc)

  @policy ||= ::ActionPolicy.lookup(target)

  begin
    ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
  rescue ActionPolicy::Unauthorized
    # we don't want to care about authorization result
  end

  @actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls

  actual_calls.any? { _1.matches?(policy, rule, target) }
end
supports_block_expectations?() click to toggle source
# File lib/action_policy/rspec/be_authorized_to.rb, line 55
    def supports_block_expectations?() = true

    def failure_message
      "expected #{formatted_record} " \
      "to be authorized with #{policy}##{rule}, " \
      "but #{actual_calls_message}"
    end

    def actual_calls_message
      if actual_calls.empty?
        "no authorization calls have been made"
      else
        "the following calls were encountered:\n" \
        "#{formatted_calls}"
      end
    end

    def formatted_calls
      actual_calls.map do
        " - #{_1.inspect}"
      end.join("\n")
    end

    def formatted_record(record = target) = ::RSpec::Support::ObjectFormatter.format(record)
  end
end
with(policy) click to toggle source
# File lib/action_policy/rspec/be_authorized_to.rb, line 30
def with(policy)
  @policy = policy
  self
end