Skip to content

Commit

Permalink
Add tests, documentation & changelog entry
Browse files Browse the repository at this point in the history
  • Loading branch information
inkstak committed Dec 11, 2024
1 parent da245aa commit 9aa3c43
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## master

- Allow to match failure reasons with RSpec DSL. ([@inkstak])

## 0.7.2 (2024-11-21)

- Fix missing details in deny! message interpolation. ([@palkan][])
Expand Down
6 changes: 6 additions & 0 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ describe PostPolicy do
before { user.role = "manager" }
end
end

# `failed` allowed to validates feailures reasons when they are provided
# (see Failure Reasons)
failed "when post is archived", reason: {post: [{archived?: {since: "2 days"}}]} do
before { post.archived_at = 2.days.ago }
end
end
end
```
Expand Down
14 changes: 9 additions & 5 deletions lib/action_policy/rspec/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,21 @@ def formatted_policy(policy)
end

case reason
when nil then next
when Hash then next if subject.reasons.details == reason
when Symbol then next if subject.reasons.details.values.flatten.include?(reason)
when String then next if subject.reasons.full_messages.flatten.include?(reason)
when nil
next
when Hash
next if subject.reasons.details == reason
when Symbol
next if subject.reasons.details.values.flatten.any? { |h| h.include?(reason) }
when String
next if subject.reasons.respond_to?(:full_messages) && subject.reasons.full_messages.flatten.include?(reason)
else
raise TypeError, "unexpected reason: #{reason.inspect}"
end

raise(
RSpec::Expectations::ExpectationNotMetError,
"Expected to fail with #{reason.inspect} but but actually failed for another reason:\n#{subject.inspect}",
"Expected to fail with #{reason.inspect} but but actually failed for another reason:\n#{formatted_policy(policy)}}",
the_caller
)
end
Expand Down
61 changes: 61 additions & 0 deletions spec/action_policy/dsl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ def show?
def manage?
user.admin? && !record.admin?
end

def delete?
user.admin? && check?(:not_admin?)
end

def not_admin?
details[:username] = record.name
!record.admin?
end
end

describe UserPolicy, type: :policy do
Expand Down Expand Up @@ -74,4 +83,56 @@ def manage?
end
end
end

describe_rule :delete? do
let(:user) { admin }
let(:record) { User.new("admin") }

around do |ex|
I18n.backend.store_translations(
:en,
action_policy: {
policy: {
user: {
not_admin?: "Only admins are authorized to perform this action"
}
}
}
)

ex.run
I18n.backend.reload!
end

failed "and matches reasons", reason: {user: [{not_admin?: {username: "admin"}}]}

failed "and partially matches reasons", reason: :not_admin?

failed "and match i18n reasons", reason: "Only admins are authorized to perform this action"

context "test errors with reasons" do
after do |ex|
msg = ex.exception.message
# mark as not failed
ex.remove_instance_variable(:@exception)

expect(msg).to include(<<~MESSAGE.strip)
Expected to fail with :unexpected but but actually failed for another reason:
<UserPolicy#delete?: false (reasons: {:user=>[{:not_admin?=>{:username=>"admin"}}]})
MESSAGE

if ActionPolicy::PrettyPrint.available?
expect(msg).to include(<<~MESSAGE.strip)
↳ user.admin? #=> #{ActionPolicy::PrettyPrint.colorize(true)}
AND
check?(:not_admin?) #=> #{ActionPolicy::PrettyPrint.colorize(false)}
MESSAGE
end
end

failed reason: :unexpected do
let(:record) { User.new("admin") }
end
end
end
end
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
])
end

require "i18n"

$LOAD_PATH.unshift File.expand_path("../lib", __dir__)

ENV["RUBY_NEXT_TRANSPILE_MODE"] = "rewrite"
Expand Down

0 comments on commit 9aa3c43

Please sign in to comment.