Skip to content

Commit

Permalink
Merge pull request #806 from gregfletch/refactor/gregfletch/allow-cus…
Browse files Browse the repository at this point in the history
…tom-rspec-matcher-description

Add customizable permit matcher description
  • Loading branch information
Burgestrand committed May 13, 2024
2 parents 18994ac + 86c7251 commit 0ab259e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,37 @@ describe PostPolicy do
end
```

You can customize the description used for the `permit` matcher:

``` ruby
Pundit::RSpec::Matchers.description =
"permit the user"
```

given the spec

```ruby
permissions :update?, :show? do
it { expect(policy).to permit(user, record) }
end
```

will change the output from

```
update? and show?
is expected to permit #<User id: 105> and #<User id: 106>
```

to

```
update? and show?
is expected to permit the user
```

which may be desirable when distributing policy specs as documentation.

An alternative approach to Pundit policy specs is scoping them to a user context as outlined in this
[excellent post](http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/) and implemented in the third party [pundit-matchers](https://github.com/punditcommunity/pundit-matchers) gem.

Expand Down
14 changes: 14 additions & 0 deletions lib/pundit/rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ module RSpec
module Matchers
extend ::RSpec::Matchers::DSL

class << self
attr_writer :description

def description(user, record)
return @description.call(user, record) if defined?(@description) && @description.respond_to?(:call)

@description
end
end

# rubocop:disable Metrics/BlockLength
matcher :permit do |user, record|
match_proc = lambda do |policy|
Expand Down Expand Up @@ -33,6 +43,10 @@ module Matchers
"#{record} but #{@violating_permissions.to_sentence} #{was_were} granted"
end

description do
Pundit::RSpec::Matchers.description(user, record) || super()
end

if respond_to?(:match_when_negated)
match(&match_proc)
match_when_negated(&match_when_negated_proc)
Expand Down
27 changes: 27 additions & 0 deletions spec/policies/post_policy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,32 @@
should permit(user, other_post)
end.to raise_error(RSpec::Expectations::ExpectationNotMetError)
end

it "uses the default description if not overridden" do
expect(permit(user, own_post).description).to eq("permit #{user.inspect} and #{own_post.inspect}")
end

context "when the matcher description is overridden" do
after do
Pundit::RSpec::Matchers.description = nil
end

it "sets a custom matcher description with a Proc" do
allow(user).to receive(:role).and_return("default_role")
allow(own_post).to receive(:id).and_return(1)

Pundit::RSpec::Matchers.description = lambda { |user, record|
"permit user with role #{user.role} to access record with ID #{record.id}"
}

description = permit(user, own_post).description
expect(description).to eq("permit user with role default_role to access record with ID 1")
end

it "sets a custom matcher description with a string" do
Pundit::RSpec::Matchers.description = "permit user"
expect(permit(user, own_post).description).to eq("permit user")
end
end
end
end

0 comments on commit 0ab259e

Please sign in to comment.