Back to Repositories

Testing Policy Generator Implementation and Permissions in Pundit

This test suite validates the generator functionality in Pundit, focusing on the installation and policy generators. It ensures proper policy file creation and default permission behaviors for a Widget policy implementation.

Test Coverage Overview

The test suite comprehensively covers generator functionality and policy behavior verification.

Key areas tested include:
  • Install generator execution and file creation
  • Policy generator for Widget model
  • Default permission settings for standard CRUD actions
  • Scope resolution behavior and error handling

Implementation Analysis

The testing approach utilizes RSpec’s temporary directory setup to isolate generator testing. It implements a structured pattern for policy permission verification using shared examples and doubles for user/widget objects.

Technical implementation details:
  • Directory manipulation for generator testing
  • Policy permission validation across multiple actions
  • Scope resolution error handling verification

Technical Details

Testing tools and configuration:
  • RSpec as the testing framework
  • Dir.mktmpdir for temporary test environment
  • Rails generators integration
  • Pundit policy generators
  • Double objects for user and widget mocking

Best Practices Demonstrated

The test suite exemplifies several testing best practices for generator and policy verification.

Notable practices include:
  • Isolated test environment setup and cleanup
  • Comprehensive permission testing across all CRUD actions
  • Proper error case handling and validation
  • Clean test organization with before/after hooks
  • Effective use of RSpec expectations and matchers

varvet/pundit

spec/generators_spec.rb

            
# frozen_string_literal: true

require "spec_helper"
require "tmpdir"

require "rails/generators"
require "generators/pundit/install/install_generator"
require "generators/pundit/policy/policy_generator"

RSpec.describe "generators" do
  before(:all) do
    @tmpdir = Dir.mktmpdir

    Dir.chdir(@tmpdir) do
      Pundit::Generators::InstallGenerator.new([], { quiet: true }).invoke_all
      Pundit::Generators::PolicyGenerator.new(%w[Widget], { quiet: true }).invoke_all

      require "./app/policies/application_policy"
      require "./app/policies/widget_policy"
    end
  end

  after(:all) do
    FileUtils.remove_entry(@tmpdir)
  end

  describe "WidgetPolicy", type: :policy do
    permissions :index?, :show?, :create?, :new?, :update?, :edit?, :destroy? do
      it "has safe defaults" do
        expect(WidgetPolicy).not_to permit(double("User"), double("Widget"))
      end
    end

    describe "WidgetPolicy::Scope" do
      describe "#resolve" do
        it "raises a descriptive error" do
          scope = WidgetPolicy::Scope.new(double("User"), double("User.all"))
          expect { scope.resolve }.to raise_error(NoMethodError, /WidgetPolicy::Scope/)
        end
      end
    end
  end
end