Back to Repositories

Testing Enum Field Type Configuration in rails_admin

This test suite validates the RailsAdmin::Config::Fields::Types::Enum functionality, focusing on enumeration field behavior in Rails Admin. It covers various enum configuration scenarios and serialization support across different ORMs.

Test Coverage Overview

The test suite provides comprehensive coverage of enum field type functionality in Rails Admin.

Key areas tested include:
  • Auto-detection of enumerations through instance and class methods
  • Custom enum method configuration
  • Enum value overriding capabilities
  • Serialization support for ActiveRecord and Mongoid models

Implementation Analysis

The testing approach employs RSpec’s shared examples and context-specific testing patterns. The suite systematically verifies enum behavior through mock objects and actual model implementations, utilizing RSpec’s expectation syntax for assertions.

Framework-specific features tested include:
  • Rails Admin field configuration DSL
  • ORM-specific serialization handling
  • Dynamic enum value resolution

Technical Details

Testing tools and configuration:
  • RSpec as the testing framework
  • Shared example patterns for generic field type testing
  • Mock objects using RSpec’s allow/receive syntax
  • Dynamic class evaluation for testing different scenarios
  • Conditional testing based on ORM type (ActiveRecord/Mongoid)

Best Practices Demonstrated

The test suite exemplifies several testing best practices in Ruby and Rails.

Notable practices include:
  • Proper test isolation using before/after hooks
  • Comprehensive edge case coverage
  • Clean test organization using RSpec contexts
  • Effective use of subject blocks
  • Proper cleanup of modified classes

railsadminteam/rails_admin

spec/rails_admin/config/fields/types/enum_spec.rb

            
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe RailsAdmin::Config::Fields::Types::Enum do
  it_behaves_like 'a generic field type', :string_field, :enum

  subject { RailsAdmin.config(Team).field(:color) }

  describe "when object responds to '\#{method}_enum'" do
    before do
      allow_any_instance_of(Team).to receive(:color_enum).and_return(%w[blue green red])
      RailsAdmin.config Team do
        edit do
          field :color
        end
      end
    end

    it 'auto-detects enumeration' do
      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)
      is_expected.not_to be_multiple
      expect(subject.with(object: Team.new).enum).to eq %w[blue green red]
    end
  end

  describe "when class responds to '\#{method}_enum'" do
    before do
      allow(Team).to receive(:color_enum).and_return(%w[blue green red])
      Team.instance_eval do
        def color_enum
          %w[blue green red]
        end
      end
      RailsAdmin.config Team do
        edit do
          field :color
        end
      end
    end

    it 'auto-detects enumeration' do
      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)
      expect(subject.with(object: Team.new).enum).to eq %w[blue green red]
    end
  end

  describe 'the enum instance method' do
    before do
      Team.class_eval do
        def color_list
          %w[blue green red]
        end
      end
      RailsAdmin.config Team do
        field :color, :enum do
          enum_method :color_list
        end
      end
    end

    after do
      Team.send(:remove_method, :color_list)
    end

    it 'allows configuration' do
      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)
      expect(subject.with(object: Team.new).enum).to eq %w[blue green red]
    end
  end

  describe 'the enum class method' do
    before do
      Team.instance_eval do
        def color_list
          %w[blue green red]
        end
      end
      RailsAdmin.config Team do
        field :color, :enum do
          enum_method :color_list
        end
      end
    end

    after do
      Team.instance_eval { undef :color_list }
    end

    it 'allows configuration' do
      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)
      expect(subject.with(object: Team.new).enum).to eq %w[blue green red]
    end
  end

  describe 'when overriding enum configuration' do
    before do
      Team.class_eval do
        def color_list
          %w[blue green red]
        end
      end
      RailsAdmin.config Team do
        field :color, :enum do
          enum_method :color_list
          enum do
            %w[yellow black]
          end
        end
      end
    end

    after do
      Team.send(:remove_method, :color_list)
    end

    it 'allows direct listing of enumeration options and override enum method' do
      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)
      expect(subject.with(object: Team.new).enum).to eq %w[yellow black]
    end
  end

  describe 'when serialize is enabled in ActiveRecord model', active_record: true do
    subject { RailsAdmin.config(TeamWithSerializedEnum).field(:color) }

    before do
      class TeamWithSerializedEnum < Team
        self.table_name = 'teams'
        if ActiveRecord.gem_version < Gem::Version.new('7.1')
          serialize :color
        else
          serialize :color, coder: JSON
        end
        def color_enum
          %w[blue green red]
        end
      end
      RailsAdmin.config do |c|
        c.included_models = [TeamWithSerializedEnum]
      end
    end

    it 'makes enumeration multi-selectable' do
      is_expected.to be_multiple
    end
  end

  describe 'when serialize is enabled in Mongoid model', mongoid: true do
    before do
      allow(Team).to receive(:color_enum).and_return(%w[blue green red])
      Team.instance_eval do
        field :color, type: Array
      end
    end

    after do
      Team.instance_eval do
        field :color, type: String
      end
    end

    it 'makes enumeration multi-selectable' do
      is_expected.to be_multiple
    end
  end
end