Pundit: `permit` matcher overloaded by `shoulda-matchers`

Created on 16 Mar 2015  路  12Comments  路  Source: varvet/pundit

Having Rails 4.2.0 app with strong_parameters and shoulda-matchers 2.7.0 and this spec:

describe AlbumPolicy do
  subject { described_class }
  let(:user) { User.new }

  permissions :edit? do
    it "grants access if album belongs to a user" do
      expect(subject).to permit(user, Album.new(user: user))
    end
  end
end

The test will fail with:

  1) AlbumPolicy edit? grants access if album belongs to a user
     Failure/Error: expect(subject).to permit(user, Album.new(user: user))
     Shoulda::Matchers::ActionController::StrongParametersMatcher::ActionNotDefinedError:
       You must specify the controller action using the #for method.
     # .../shoulda-matchers-2.7.0/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb:242:in `ensure_action_and_verb_present!'
     # .../shoulda-matchers-2.7.0/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb:190:in `matches?'

Most helpful comment

Specifying type: :policy didn't help.
I removed require 'pundit/rspec' from spec_helper, and added to policy spec right after require 'spec_helper'. Now the error is gone.

All 12 comments

Hi @Holek, I was having this problem too. I resolved it specifying the type meta on my policy specs.

describe AlbumPolicy, type: :policy do
  # ...
end

With this, shoulda-matchers didn't conflict with its controller #permit matcher.

Which version of RSpec you are using?

I think Pundit behaves in the correct way and only includes the permit matcher in its own RSpec context. This is really a problem with shoulda including their matchers where they don't belong. They should limit them to only controller specs. Please file this issue with shoulda instead.

I ran into this as well. Is there are a workaround for this?

Hi @KurtRMueller, as you can see in the implementation of Pundit's custom matchers, they're going to behave normally if policies are within the /spec/policies folder and with type: :policy meta.

Shoulda-matchers permit matcher only scopes it to controller specs in its earlier versions.

Thanks for the quick response @tiagoamaro. In this case, my policy spec file is indeed in the /spec/policies folder and does have the type: policy meta added on to it.

**Edit: I fixed this by including shoulda-matchers first and then pundit/rspec.

:+1: @KurtRMueller ,
Great that you fixed it and detailed how. Hopefully, shoulda-matchers 3.0 will soon launch and stop this confusion.

Here's a question and it's up for debate:

Does any one gem have a right to claim the permit verb? Permit is ambiguous enough to where I could can see why both pundit and shoulda-matchers use the verb. In pundit's case, it's obviously policy permissions - in shoulda-matcher's case, it's for whitelisted parameters.

This could be a simple fix for both parties. Simply create an alias for the permit method: permit_parameters for shoulda-matchers and authorize or something similar for pundit.

Anyway, it's just a thought. Thanks for all your help people and I really do love Pundit :).

The difference is that Pundit is only "claiming" the permit name within the spec group that Pundit itself has created. Pundit's permit matcher is only available inside type: :policy specs. You could make a case that other gems might want to create something called a policy, but there currently isn't one, so that's a theoretical argument, and I think "dibs" applies in that case ;) shoulda however is including its matcher, which clearly only works with controller specs into _all_ specs.

Specifying type: :policy didn't help.
I removed require 'pundit/rspec' from spec_helper, and added to policy spec right after require 'spec_helper'. Now the error is gone.

+1 on @KurtRMueller's thought.

@denispeplin thanks. yours was the solution for me too

@KurtRMueller thank you, it works well now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

epinault picture epinault  路  6Comments

jkepps picture jkepps  路  4Comments

ghost picture ghost  路  5Comments

linhmtran168 picture linhmtran168  路  3Comments

lnikkila picture lnikkila  路  5Comments