Back to Repositories

Testing Dynamic Version Pattern Detection in WPScan

This test suite validates the WPScan Dynamic Finder’s BodyPattern functionality for version detection, focusing on pattern matching configuration and constant initialization. The tests ensure proper class creation and constant handling for version detection patterns.

Test Coverage Overview

The test suite covers the creation and configuration of dynamic finder classes for version detection through body pattern matching. Key areas tested include:

  • Default configuration handling for pattern matching
  • Custom confidence level settings
  • Path configuration options
  • Constant initialization and validation

Implementation Analysis

The testing approach uses RSpec’s module manipulation capabilities to dynamically create and test finder classes. The implementation leverages RSpec’s before/after hooks for test isolation and context blocks for different configuration scenarios.

Tests verify constant assignment and configuration inheritance through class creation.

Technical Details

Testing tools and configuration:

  • RSpec testing framework
  • Dynamic class creation using create_child_class
  • Module manipulation for test isolation
  • Constant verification through RSpec expectations
  • Regular expression pattern matching validation

Best Practices Demonstrated

The test suite demonstrates several testing best practices:

  • Proper test isolation using before/after hooks
  • Contextual testing with different configuration scenarios
  • Clear separation of test cases
  • Comprehensive validation of default and custom configurations
  • Modular test organization with describe blocks

wpscanteam/wpscan

spec/lib/finders/dynamic_finder/version/body_pattern_spec.rb

            
# frozen_string_literal: true

describe WPScan::Finders::DynamicFinder::Version::BodyPattern do
  module WPScan
    module Finders
      module Version
        # Needed to be able to test the below
        module Rspec
        end
      end
    end
  end

  let(:finder_module) { WPScan::Finders::Version::Rspec }
  let(:finder_class)  { WPScan::Finders::Version::Rspec::BodyPattern }
  let(:finder_config) { { 'pattern' => /aaa/i } }
  let(:default)       { { 'confidence' => 60 } }

  before { described_class.create_child_class(finder_module, :BodyPattern, finder_config) }
  after  { finder_module.send(:remove_const, :BodyPattern) }

  describe '.create_child_class' do
    context 'when no PATH and CONFIDENCE' do
      it 'contains the expected constants to their default values' do
        # Doesn't work, dunno why
        # expect(finder_module.const_get(:BodyPattern)).to be_a described_class
        # expect(finder_class.is_a?(described_class)).to eql true
        # expect(finder_class).to be_a described_class

        expect(finder_class::PATTERN).to eql finder_config['pattern']
        expect(finder_class::CONFIDENCE).to eql default['confidence']
        expect(finder_class::PATH).to eql nil
      end
    end

    context 'when CONFIDENCE' do
      let(:finder_config) { super().merge('confidence' => 50) }

      it 'contains the expected constants' do
        expect(finder_class::PATTERN).to eql finder_config['pattern']
        expect(finder_class::CONFIDENCE).to eql finder_config['confidence']

        expect(finder_class::PATH).to eql nil
      end
    end

    context 'when PATH' do
      let(:finder_config) { super().merge('path' => 'changelog.txt') }

      it 'contains the expected constants' do
        expect(finder_class::PATTERN).to eql finder_config['pattern']
        expect(finder_class::PATH).to eql finder_config['path']

        expect(finder_class::CONFIDENCE).to eql default['confidence']
      end
    end
  end

  describe '#passive, #aggressive' do
    # Handled in spec/lib/finders/dynamic_finder/plugin_version_spec
  end
end