yqbk
yqbk

Reputation: 726

Pundit::NotDefinedError: unable to find policy when moving from Pundit 0.3 to 1.0

When I am running rspec wit pundit version 1.0 on one of my project spec classes I get multiple errors which I haven't seen before. However, when I'm switching to the previous version of pundit (0.3) everything works correctly.

Up to now what I have noticed is that with newer version of pundit @error in create function is not correctly assigned (instead of error class, I get an error message string from the error class).

class ErrorsController < ApplicationController
  before_action :set_execution_environment

  def authorize!
    authorize(@error || @errors)
  end
  private :authorize!

  def create
    @error = Error.new(error_params)
    authorize!
  end

  def error_params
    params[:error].permit(:message, :submission_id).merge(execution_environment_id: @execution_environment.id)
  end
  private :error_params

in spec/factories:

FactoryGirl.define do
  factory :error, class: Error do
    association :execution_environment, factory: :ruby
    message "exercise.rb:4:in `<main>': undefined local variable or method `foo' for main:Object (NameError)"
  end
end

in spec/controllers/error_controller.rb:

 describe 'POST #create' do
    context 'with a valid error' do
      let(:request) { proc { post :create, execution_environment_id: FactoryGirl.build(:error).execution_environment.id, error: FactoryGirl.attributes_for(:error), format: :json } }

      context 'when a hint can be matched' do
        let(:hint) { FactoryGirl.build(:ruby_syntax_error).message }

        before(:each) do
          expect_any_instance_of(Whistleblower).to receive(:generate_hint).and_return(hint)
          request.call
        end

        expect_assigns(execution_environment: :execution_environment)

        it 'does not create the error' do
          allow_any_instance_of(Whistleblower).to receive(:generate_hint).and_return(hint)
          expect { request.call }.not_to change(Error, :count)
        end

        it 'returns the hint' do
          expect(response.body).to eq({hint: hint}.to_json)
        end

        expect_json
        expect_status(200)
      end

      context 'when no hint can be matched' do
        before(:each) do
          expect_any_instance_of(Whistleblower).to receive(:generate_hint).and_return(nil)
          request.call
        end

        expect_assigns(execution_environment: :execution_environment)

        it 'creates the error' do
          allow_any_instance_of(Whistleblower).to receive(:generate_hint)
          expect { request.call }.to change(Error, :count).by(1)
        end

        expect_json
        expect_status(201)
      end
    end

I get the error message

Pundit::NotDefinedError: unable to find policy Pundit::ErrorPolicy for #<Pundit::Error: {"message"=>"exercise.rb:4:in': undefined local variable or method foo' for main:Object (NameError)", "execution_environment_id"=>1}>

since error class is not correctly created. After that every test in error class fail.

My policies:

class AdminOrAuthorPolicy < ApplicationPolicy
  [:create?, :index?, :new?].each do |action|
    define_method(action) { @user.internal_user? }
  end

  [:destroy?, :edit?, :show?, :update?].each do |action|
    define_method(action) { admin? || author? }
  end
end


class ErrorPolicy < AdminOrAuthorPolicy
  def author?
    @user == @record.execution_environment.author
  end
end

I have no such an problem with any other class.

Upvotes: 1

Views: 838

Answers (1)

stephenmurdoch
stephenmurdoch

Reputation: 34613

I've been dealing with the same problem for the last half hour, albeit using minitest, and the solution was to run spring stop and then rerun my tests. Hope this helps.

Upvotes: 1

Related Questions