1

I set up Pundit to guard a bunch of request paths, and it's working fine. In particular, if I hit /api/users/:id with a PATCH request, passing the relevant parameters, I get a 403 if I'm not authenticated. Then I wrote this spec

context 'When logged out' do
  describe 'user update' do
    before(:each) do
      @new_user = FactoryBot.create(:user, password: 'testpassword')
    end

    it 'fails with PATCH' do
      patch "/api/users/#{@new_user.id}", params: { given_name: 'Testing Alice' }
      expect(response).to have_http_status(:forbidden)
    end
  end
end

but when I run rspec, I get the following failure:

  1) When logged out user update fails with PATCH
     Failure/Error: authorize @user

     Pundit::NotAuthorizedError:
       not allowed to update? this #<User id: 24, email: "nolanschinner@schuster.net", given_name: "Deja", family_name: "Schmeler", role: "USER", password_digest: "$2a$04$3lhKjBj2DfLymYnTfhDZV.IrlhPPxsPHIe.hI0lHdb1...", created_at: "2018-12-07 15:08:00", updated_at: "2018-12-07 15:08:00", verification_token: nil, email_verified: false, gender: nil>
     # /Users/morpheu5/.rvm/gems/ruby-2.5.1/gems/pundit-2.0.0/lib/pundit.rb:209:in `authorize'
     # ./app/controllers/api/v1/users_controller.rb:55:in `update'
     # ...

The method being tested is right here.

As far as I can tell, Pundit raises the exception and this throws rspec into despair. How do I write this test so that it actually works?

Morpheu5
  • 2,610
  • 6
  • 39
  • 72
  • It looks like the code above is conflating authentication (whether or not someone is logged in) with authorization (whether or not someone has permission to perform an action). Could you show us the bit of the controller that is calling Pundit? – aridlehoover Dec 12 '18 at 00:46
  • Hi, the method is right here: https://github.com/Morpheu5/UniJobs-api/blob/9ccb3b2c42b2e8386566c38636aa3192a4c2fdd3/app/controllers/api/v1/users_controller.rb#L112 – Morpheu5 Dec 14 '18 at 11:14

1 Answers1

1

The subject is a bit old but, for those still searching for the answer, you should write something like:

context 'When logged out' do
  describe 'user update' do
    before(:each) do
      @new_user = FactoryBot.create(:user, password: 'testpassword')
    end

    it 'fails with PATCH' do
      expect{patch "/api/users/#{@new_user.id}", params: { given_name: 'Testing Alice' }}.to raise_error(Pundit::NotAuthorizedError)
    end
  end
end
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Alexis Lenoir
  • 26
  • 1
  • 2