Path: blob/master/spec/lib/finders/dynamic_finder/theme_version_spec.rb
1466 views
# frozen_string_literal: true12# All Theme Dynamic Finders returning a Version are tested here.3# When adding one to the spec/fixtures/db/dynamic_finder.yml, a few files have4# to be edited/created5#6# - spec/fixtures/dynamic_finder/expected.yml with the expected result/s7# - Then, depending on the finder class used: spec/fixtures/dynamic_finder/theme_version/8#9# Furthermore, the fixtures files _passive_all.html are also used by plugins/themes10# finders in spec/app/finders/plugins|themes to check the items existence from the homepage11#12# In case of a failure, it's recommended to use rspec -e "<Full Description>" while fixing.13# e.g: rspec -e "WPScan::Finders::ThemeVersion::Cardealerpress::HeaderPattern#passive"14# The -e option can also be used to test all HeaderPattern, for example: rspec -e "::HeaderPattern"1516expected_all = df_expected_all['themes']1718WPScan::DB::DynamicFinders::Theme.versions_finders_configs.each do |slug, configs|19WPScan::DB::DynamicFinders::Theme.create_versions_finders(slug)2021configs.each do |finder_class, config|22finder_super_class = config['class'] || finder_class2324# The QueryParameter specs are slow given the huge fixture file25# If someone find a fix for that, please share!26describe df_tested_class_constant('ThemeVersion', finder_class, slug), slow: true do27subject(:finder) { described_class.new(theme) }28let(:theme) { WPScan::Model::Theme.new(slug, target) }29let(:target) { WPScan::Target.new('http://wp.lab/') }30let(:fixtures) { DYNAMIC_FINDERS_FIXTURES.join('theme_version') }3132let(:expected) do33if expected_all[slug][finder_class].is_a?(Hash)34[expected_all[slug][finder_class]]35else36expected_all[slug][finder_class]37end38end3940before do41allow(target).to receive(:content_dir).and_return('wp-content')4243# When creating a theme, the style.css is checked, let's stub that44stub_request(:get, target.url("wp-content/themes/#{slug}/style.css"))45end4647describe '#passive', slow: true do48before do49if defined?(stubbed_homepage_res)50stub_request(:get, target.url).to_return(stubbed_homepage_res)51else52stub_request(:get, target.url)53end5455if defined?(stubbed_404_res)56stub_request(:get, ERROR_404_URL_PATTERN).to_return(stubbed_404_res)57else58stub_request(:get, ERROR_404_URL_PATTERN)59end60end6162if config['path']63context 'when PATH' do64it 'returns nil' do65expect(finder.passive).to eql nil66end67end68else69context 'when no PATH' do70context 'when the version is detected' do71context 'from the homepage' do72let(:ie_url) { target.url }73let(:stubbed_homepage_res) do74df_stubbed_response(75fixtures.join("#{finder_super_class.underscore}_passive_all.html"),76finder_super_class77)78end7980it 'returns the expected version/s' do81found = Array(finder.passive)8283expect(found).to_not be_empty8485found.each_with_index do |version, index|86expected_version = expected.at(index)87expected_ie = expected_version['interesting_entries'].map do |ie|88ie.gsub("#{target.url},", "#{ie_url},")89end9091expect(version).to be_a WPScan::Model::Version92expect(version.number).to eql expected_version['number'].to_s93expect(version.found_by).to eql expected_version['found_by']94expect(version.interesting_entries).to match_array expected_ie9596expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']97end98end99end100101context 'from the 404' do102let(:ie_url) { target.error_404_url }103let(:stubbed_404_res) do104df_stubbed_response(105fixtures.join("#{finder_super_class.underscore}_passive_all.html"),106finder_super_class107)108end109110it 'returns the expected version/s' do111found = Array(finder.passive)112113expect(found).to_not be_empty114115found.each_with_index do |version, index|116expected_version = expected.at(index)117expected_ie = expected_version['interesting_entries'].map do |ie|118ie.gsub("#{target.url},", "#{ie_url},")119end120121expect(version).to be_a WPScan::Model::Version122expect(version.number).to eql expected_version['number'].to_s123expect(version.found_by).to eql expected_version['found_by']124expect(version.interesting_entries).to match_array expected_ie125126expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']127end128end129end130end131132context 'when the version is not detected' do133it 'returns nil or an empty array' do134expect(finder.passive).to eql finder_super_class == 'QueryParameter' ? [] : nil135end136end137end138end139end140141describe '#aggressive' do142let(:fixtures) { super().join(slug, finder_class.underscore) }143let(:stubbed_response) { { body: 'aa' } }144145before do146stub_request(:get, theme.url(config['path'])).to_return(stubbed_response) if config['path']147end148149if config['path']150context 'when the version is detected' do151let(:stubbed_response) do152df_stubbed_response(fixtures.join(config['path']), finder_super_class)153end154155it 'returns the expected version' do156found = Array(finder.aggressive)157158expect(found).to_not be_empty159160found.each_with_index do |version, index|161expected_version = expected.at(index)162163expect(version).to be_a WPScan::Model::Version164expect(version.number).to eql expected_version['number'].to_s165expect(version.found_by).to eql expected_version['found_by']166expect(version.interesting_entries).to match_array expected_version['interesting_entries']167168expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']169end170end171end172173context 'when the version is not detected' do174it 'returns nil or an empty array' do175expect(finder.aggressive).to eql finder_super_class == 'QueryParameter' ? [] : nil176end177end178else179it 'returns nil' do180expect(finder.aggressive).to eql nil181end182end183end184end185end186end187188189