Back to Repositories

Testing AccessDenied Exception Handling in CanCan

This test suite focuses on validating the AccessDenied exception handling in the CanCan authorization library. It ensures proper error message handling, internationalization support, and access control functionality for Ruby applications.

Test Coverage Overview

The test suite comprehensively covers the CanCan::AccessDenied exception class functionality.

Key areas tested include:
  • Action and subject accessor validation
  • Custom message handling
  • Default message management
  • I18n integration for error messages

Implementation Analysis

The testing approach uses RSpec’s behavior-driven development patterns with nested describe blocks for organizing test scenarios.

Technical implementation includes:
  • Before hooks for test setup
  • Explicit message verification
  • I18n backend manipulation
  • Isolation of translation testing

Technical Details

Testing infrastructure includes:
  • RSpec as the testing framework
  • I18n for internationalization testing
  • Custom exception class implementation
  • Spec helper integration

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Isolated test scenarios
  • Proper test cleanup after I18n modifications
  • Clear test case organization
  • Comprehensive edge case coverage
  • Explicit expectation setting

ryanb/cancan

spec/cancan/exceptions_spec.rb

            
require "spec_helper"

describe CanCan::AccessDenied do
  describe "with action and subject" do
    before(:each) do
      @exception = CanCan::AccessDenied.new(nil, :some_action, :some_subject)
    end

    it "should have action and subject accessors" do
      @exception.action.should == :some_action
      @exception.subject.should == :some_subject
    end

    it "should have a changable default message" do
      @exception.message.should == "You are not authorized to access this page."
      @exception.default_message = "Unauthorized!"
      @exception.message.should == "Unauthorized!"
    end
  end

  describe "with only a message" do
    before(:each) do
      @exception = CanCan::AccessDenied.new("Access denied!")
    end

    it "should have nil action and subject" do
      @exception.action.should be_nil
      @exception.subject.should be_nil
    end

    it "should have passed message" do
      @exception.message.should == "Access denied!"
    end
  end

  describe "i18n in the default message" do
    after(:each) do
      I18n.backend = nil
    end

    it "uses i18n for the default message" do
      I18n.backend.store_translations :en, :unauthorized => {:default => "This is a different message"}
      @exception = CanCan::AccessDenied.new
      @exception.message.should == "This is a different message"
    end

    it "defaults to a nice message" do
      @exception = CanCan::AccessDenied.new
      @exception.message.should == "You are not authorized to access this page."
    end

    it "does not use translation if a message is given" do
      @exception = CanCan::AccessDenied.new("Hey! You're not welcome here")
      @exception.message.should == "Hey! You're not welcome here"
      @exception.message.should_not == "You are not authorized to access this page."
    end
  end
end