Back to Repositories

Testing Dynamic Version Comment Detection in WPScan

This test suite validates the dynamic version finder functionality in WPScan, specifically focusing on comment-based version detection implementation. The tests ensure proper configuration and constant handling for version detection patterns in HTML comments.

Test Coverage Overview

The test suite provides comprehensive coverage of the DynamicFinder::Version::Comment class functionality.

Key areas tested include:
  • Dynamic class creation with various configuration options
  • Default value handling for XPATH and CONFIDENCE constants
  • Pattern matching configuration for version detection
  • Path and XPath parameter validation

Implementation Analysis

The testing approach uses RSpec’s describe/context pattern to validate different configuration scenarios for the Comment finder class. The implementation leverages module manipulation to create and remove test classes dynamically, allowing isolated testing of constant configurations.

Technical patterns include:
  • Dynamic constant verification
  • Module-level class creation
  • Configuration merging validation

Technical Details

Testing infrastructure includes:
  • RSpec as the testing framework
  • Module-level constant manipulation
  • Before/After hooks for test isolation
  • Let blocks for dynamic test data
  • Nested context blocks for different scenarios

Best Practices Demonstrated

The test suite demonstrates several testing best practices for Ruby and RSpec testing.

Notable practices include:
  • Proper test isolation using hooks
  • Dynamic test data generation
  • Comprehensive edge case coverage
  • Clear context separation
  • Consistent expectation patterns

wpscanteam/wpscan

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

            
# frozen_string_literal: true

describe WPScan::Finders::DynamicFinder::Version::Comment 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::Comment }
  let(:finder_config) { { 'pattern' => /some version: (?<v>[\d.]+)/i } }
  let(:default)       { { 'xpath' => '//comment()', 'confidence' => 60 } }

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

  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(:Comment)).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::XPATH).to eql default['xpath']
        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' => 30) }

      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::XPATH).to eql default['xpath']
        expect(finder_class::PATH).to eql nil
      end
    end

    context 'when PATH' do
      let(:finder_config) { super().merge('path' => 'file.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']
        expect(finder_class::XPATH).to eql default['xpath']
      end
    end

    context 'when XPATH' do
      let(:finder_config) { super().merge('xpath' => '//comment()[contains(. "aa")]') }

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

        expect(finder_class::PATH).to eql nil
        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