Skip to content

Commit

Permalink
negated matcher for be_able_to only passes when no ability is eligible
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Gabriel and Michael Raidel authored and mraidel committed Aug 24, 2020
1 parent 300f54c commit b439cc0
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## Unreleased

* [#645](https://github.com/CanCanCommunity/cancancan/issues/645): Generate inner queries instead of join+distinct. ([@mraidel][], [@gabsi20][])

## 3.1.0

* [#605](https://github.com/CanCanCommunity/cancancan/pull/605): Generate inner queries instead of join+distinct. ([@fsateler][])
Expand Down Expand Up @@ -665,3 +669,5 @@ Please read the [guide on migrating from CanCanCan 2.x to 3.0](https://github.co
[@aleksejleonov]: https://github.com/aleksejleonov
[@albb0920]: https://github.com/albb0920
[@ayumu838]: https://github.com/ayumu838
[@mraidel]: https://github.com/mraidel
[@gabsi20]: https://github.com/gabsi20
17 changes: 10 additions & 7 deletions lib/cancan/matchers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@

Kernel.const_get(rspec_module)::Matchers.define :be_able_to do |*args|
match do |ability|
actions = args.first
if actions.is_a? Array
break false if actions.empty?
actions = Array(args.first)
break false if actions.empty?

actions.all? { |action| ability.can?(action, *args[1..-1]) }
else
ability.can?(*args)
end
actions.all? { |action| ability.can?(action, *args[1..-1]) }
end

match_when_negated do |ability|
actions = Array(args.first)
break true if actions.empty?

actions.none? { |action| ability.can?(action, *args[1..-1]) }
end

# Check that RSpec is < 2.99
Expand Down
8 changes: 5 additions & 3 deletions spec/cancan/matchers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,12 @@
is_expected.not_to be_able_to([], 123)
end

it 'delegates to can? with array of abilities with only one eligable ability' do
it 'delegates to can? with array of abilities with only one eligible ability' do
is_expected.to receive(:can?).with(:read, 123) { true }
is_expected.to receive(:can?).with(:update, 123) { false }
is_expected.not_to be_able_to(%i[read update], 123)
is_expected.not_to receive(:can?).with(:update, 123)
expect do
is_expected.not_to be_able_to(%i[read update], 123)
end.to raise_error('expected not to be able to [:read, :update] 123')
end
end
end

0 comments on commit b439cc0

Please sign in to comment.