184 lines
7.0 KiB
Ruby
184 lines
7.0 KiB
Ruby
RSpec.describe BeEF::Module do
|
|
let(:config) { BeEF::Core::Configuration.instance }
|
|
|
|
describe '.is_present' do
|
|
it 'returns true when module exists in configuration' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({ 'test_module' => {} })
|
|
expect(described_class.is_present('test_module')).to be true
|
|
end
|
|
|
|
it 'returns false when module does not exist' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({})
|
|
expect(described_class.is_present('nonexistent')).to be false
|
|
end
|
|
end
|
|
|
|
describe '.is_enabled' do
|
|
it 'returns true when module is present and enabled' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({ 'test_module' => {} })
|
|
allow(config).to receive(:get).with('beef.module.test_module.enable').and_return(true)
|
|
expect(described_class.is_enabled('test_module')).to be true
|
|
end
|
|
|
|
it 'returns false when module is not present' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({})
|
|
expect(described_class.is_enabled('nonexistent')).to be false
|
|
end
|
|
|
|
it 'returns false when module is disabled' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({ 'test_module' => {} })
|
|
allow(config).to receive(:get).with('beef.module.test_module.enable').and_return(false)
|
|
expect(described_class.is_enabled('test_module')).to be false
|
|
end
|
|
end
|
|
|
|
describe '.is_loaded' do
|
|
it 'returns true when module is enabled and loaded' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({ 'test_module' => {} })
|
|
allow(config).to receive(:get).with('beef.module.test_module.enable').and_return(true)
|
|
allow(config).to receive(:get).with('beef.module.test_module.loaded').and_return(true)
|
|
expect(described_class.is_loaded('test_module')).to be true
|
|
end
|
|
|
|
it 'returns false when module is not loaded' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({ 'test_module' => {} })
|
|
allow(config).to receive(:get).with('beef.module.test_module.enable').and_return(true)
|
|
allow(config).to receive(:get).with('beef.module.test_module.loaded').and_return(false)
|
|
expect(described_class.is_loaded('test_module')).to be false
|
|
end
|
|
end
|
|
|
|
describe '.get_key_by_database_id' do
|
|
it 'returns module key for matching database id' do
|
|
modules = {
|
|
'module1' => { 'db' => { 'id' => 1 } },
|
|
'module2' => { 'db' => { 'id' => 2 } }
|
|
}
|
|
allow(config).to receive(:get).with('beef.module').and_return(modules)
|
|
expect(described_class.get_key_by_database_id(2)).to eq('module2')
|
|
end
|
|
|
|
it 'returns nil when no module matches' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({})
|
|
expect(described_class.get_key_by_database_id(999)).to be_nil
|
|
end
|
|
end
|
|
|
|
describe '.get_key_by_class' do
|
|
it 'returns module key for matching class' do
|
|
modules = {
|
|
'module1' => { 'class' => 'TestClass1' },
|
|
'module2' => { 'class' => 'TestClass2' }
|
|
}
|
|
allow(config).to receive(:get).with('beef.module').and_return(modules)
|
|
expect(described_class.get_key_by_class('TestClass2')).to eq('module2')
|
|
end
|
|
end
|
|
|
|
describe '.exists?' do
|
|
it 'returns true when class exists' do
|
|
test_class = Class.new
|
|
BeEF::Core::Command.const_set(:Testmodule, test_class)
|
|
expect(described_class.exists?('testmodule')).to be true
|
|
BeEF::Core::Command.send(:remove_const, :Testmodule)
|
|
end
|
|
|
|
it 'returns false when class does not exist' do
|
|
expect(described_class.exists?('NonexistentClass')).to be false
|
|
end
|
|
end
|
|
|
|
describe '.match_target_browser' do
|
|
it 'returns browser constant for valid browser string' do
|
|
result = described_class.match_target_browser('FF')
|
|
expect(result).to eq(BeEF::Core::Constants::Browsers::FF)
|
|
end
|
|
|
|
it 'returns false for invalid browser string' do
|
|
expect(described_class.match_target_browser('InvalidBrowser')).to be false
|
|
end
|
|
|
|
it 'returns false for non-string input' do
|
|
expect(described_class.match_target_browser(123)).to be false
|
|
end
|
|
end
|
|
|
|
describe '.match_target_os' do
|
|
it 'returns OS constant for valid OS string' do
|
|
result = described_class.match_target_os('Linux')
|
|
expect(result).to eq(BeEF::Core::Constants::Os::OS_LINUX_UA_STR)
|
|
end
|
|
|
|
it 'returns false for invalid OS string' do
|
|
expect(described_class.match_target_os('InvalidOS')).to be false
|
|
end
|
|
|
|
it 'returns false for non-string input' do
|
|
expect(described_class.match_target_os(123)).to be false
|
|
end
|
|
end
|
|
|
|
describe '.match_target_browser_spec' do
|
|
it 'returns hash with max_ver and min_ver' do
|
|
spec = { 'max_ver' => 10, 'min_ver' => 5 }
|
|
result = described_class.match_target_browser_spec(spec)
|
|
expect(result['max_ver']).to eq(10)
|
|
expect(result['min_ver']).to eq(5)
|
|
end
|
|
|
|
it 'handles latest as max_ver' do
|
|
spec = { 'max_ver' => 'latest' }
|
|
result = described_class.match_target_browser_spec(spec)
|
|
expect(result['max_ver']).to eq('latest')
|
|
end
|
|
|
|
it 'returns empty hash for non-hash input' do
|
|
expect(described_class.match_target_browser_spec('invalid')).to eq({})
|
|
end
|
|
|
|
it 'includes OS when specified' do
|
|
spec = { 'max_ver' => 10, 'os' => 'Linux' }
|
|
result = described_class.match_target_browser_spec(spec)
|
|
expect(result['os']).to eq(BeEF::Core::Constants::Os::OS_LINUX_UA_STR)
|
|
end
|
|
end
|
|
|
|
describe '.merge_options' do
|
|
it 'returns nil when module is not present' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({})
|
|
expect(described_class.merge_options('nonexistent', [])).to be_nil
|
|
end
|
|
|
|
it 'merges default options with custom options' do
|
|
allow(config).to receive(:get).with('beef.module').and_return({ 'test_module' => {} })
|
|
allow(described_class).to receive(:is_present).and_return(true)
|
|
allow(described_class).to receive(:check_hard_load).and_return(true)
|
|
allow(described_class).to receive(:get_options).and_return(
|
|
[
|
|
{ 'name' => 'option1', 'value' => 'default1' },
|
|
{ 'name' => 'option2', 'value' => 'default2' }
|
|
]
|
|
)
|
|
custom_opts = [{ 'name' => 'option1', 'value' => 'custom1' }]
|
|
result = described_class.merge_options('test_module', custom_opts)
|
|
|
|
expect(result.length).to eq(2)
|
|
expect(result.find { |o| o['name'] == 'option1' }['value']).to eq('custom1')
|
|
expect(result.find { |o| o['name'] == 'option2' }['value']).to eq('default2')
|
|
end
|
|
end
|
|
|
|
describe '.check_hard_load' do
|
|
it 'returns true when module is already loaded' do
|
|
allow(described_class).to receive(:is_loaded).and_return(true)
|
|
expect(described_class.check_hard_load('test_module')).to be true
|
|
end
|
|
|
|
it 'calls hard_load when module is not loaded' do
|
|
allow(described_class).to receive(:is_loaded).and_return(false)
|
|
expect(described_class).to receive(:hard_load).with('test_module')
|
|
described_class.check_hard_load('test_module')
|
|
end
|
|
end
|
|
end
|