TEST: main autorun specs

This commit is contained in:
Jake Webster
2026-01-30 16:38:40 +10:00
parent fc10884d50
commit a69423fb94
2 changed files with 202 additions and 0 deletions
@@ -0,0 +1,119 @@
#
# Copyright (c) 2006-2026 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - https://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
require 'spec_helper'
RSpec.describe BeEF::Core::AutorunEngine::Parser do
let(:parser) { described_class.instance }
def valid_minimal_args
{
name: 'Test Rule',
author: 'Test Author',
browser: 'ALL',
browser_version: 'ALL',
os: 'Windows',
os_version: 'ALL',
modules: [],
execution_order: [],
execution_delay: [],
chain_mode: 'sequential'
}
end
describe '#parse' do
it 'returns true for valid minimal args (empty modules)' do
result = parser.parse(
valid_minimal_args[:name],
valid_minimal_args[:author],
valid_minimal_args[:browser],
valid_minimal_args[:browser_version],
valid_minimal_args[:os],
valid_minimal_args[:os_version],
valid_minimal_args[:modules],
valid_minimal_args[:execution_order],
valid_minimal_args[:execution_delay],
valid_minimal_args[:chain_mode]
)
expect(result).to be true
end
it 'raises ArgumentError for empty name' do
expect do
parser.parse('', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'sequential')
end.to raise_error(ArgumentError, /Invalid rule name/)
end
it 'raises ArgumentError for nil name' do
expect do
parser.parse(nil, 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'sequential')
end.to raise_error(ArgumentError, /Invalid rule name/)
end
it 'raises ArgumentError for empty author' do
expect do
parser.parse('Name', '', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'sequential')
end.to raise_error(ArgumentError, /Invalid author name/)
end
it 'raises ArgumentError for invalid chain_mode' do
expect do
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'invalid')
end.to raise_error(ArgumentError, /Invalid chain_mode definition/)
end
it 'raises ArgumentError for invalid os' do
expect do
parser.parse('Name', 'Author', 'ALL', 'ALL', 'InvalidOS', 'ALL', [], [], [], 'sequential')
end.to raise_error(ArgumentError, /Invalid os definition/)
end
it 'raises ArgumentError when execution_delay size does not match modules size' do
expect do
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [{ 'name' => 'a' }], [1], [], 'sequential')
end.to raise_error(ArgumentError, /execution_delay.*consistent with number of modules/)
end
it 'raises ArgumentError when execution_order size does not match modules size' do
expect do
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [{ 'name' => 'a' }], [], [0], 'sequential')
end.to raise_error(ArgumentError, /execution_order.*consistent with number of modules/)
end
it 'raises TypeError when execution_delay contains non-Integer' do
# Use one module so sizes match; then type check runs on execution_delay
expect do
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [{}], [1], ['not_an_int'], 'sequential')
end.to raise_error(TypeError, /execution_delay.*Integers/)
end
it 'raises TypeError when execution_order contains non-Integer' do
# Use one module so sizes match; then type check runs on execution_order
expect do
parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [{}], ['x'], [0], 'sequential')
end.to raise_error(TypeError, /execution_order.*Integers/)
end
it 'raises ArgumentError for invalid browser' do
expect do
parser.parse('Name', 'Author', 'XX', 'ALL', 'Windows', 'ALL', [], [], [], 'sequential')
end.to raise_error(ArgumentError, /Invalid browser definition/)
end
it 'accepts nested-forward as chain_mode' do
result = parser.parse('Name', 'Author', 'ALL', 'ALL', 'Windows', 'ALL', [], [], [], 'nested-forward')
expect(result).to be true
end
it 'accepts valid os values' do
%w[Linux Windows OSX Android iOS BlackBerry ALL].each do |os|
result = parser.parse('Name', 'Author', 'ALL', 'ALL', os, 'ALL', [], [], [], 'sequential')
expect(result).to be true
end
end
end
end
@@ -0,0 +1,83 @@
#
# Copyright (c) 2006-2026 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - https://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
require 'spec_helper'
RSpec.describe BeEF::Core::AutorunEngine::RuleLoader do
let(:loader) { described_class.instance }
def valid_rule_data
{
'name' => 'Test Rule',
'author' => 'Test Author',
'browser' => 'ALL',
'browser_version' => 'ALL',
'os' => 'Windows',
'os_version' => 'ALL',
'modules' => [],
'execution_order' => [],
'execution_delay' => [],
'chain_mode' => 'sequential'
}
end
before do
allow(loader).to receive(:print_error)
allow(loader).to receive(:print_info)
allow(loader).to receive(:print_more)
end
describe '#load_rule_json' do
it 'returns success and rule_id when parse succeeds and rule is new' do
# Parser will succeed with valid minimal data; no existing rule
result = loader.load_rule_json(valid_rule_data)
expect(result['success']).to be true
expect(result).to have_key('rule_id')
expect(result['rule_id']).to be_a(Integer)
end
it 'returns success false and error when parse raises' do
allow(BeEF::Core::AutorunEngine::Parser.instance).to receive(:parse).and_raise(ArgumentError.new('Invalid rule name'))
result = loader.load_rule_json(valid_rule_data.merge('name' => 'x'))
expect(result['success']).to be false
expect(result['error']).to include('Invalid rule name')
end
it 'returns success false and error when rule already exists' do
# Create the rule first so it already exists
BeEF::Core::Models::Rule.create!(
name: 'Duplicate Rule',
author: 'Test Author',
browser: 'ALL',
browser_version: 'ALL',
os: 'Windows',
os_version: 'ALL',
modules: [].to_json,
execution_order: [].to_s,
execution_delay: [].to_s,
chain_mode: 'sequential'
)
result = loader.load_rule_json(
valid_rule_data.merge('name' => 'Duplicate Rule')
)
expect(result['success']).to be false
expect(result['error']).to include('Duplicate rule already exists')
end
it 'uses default chain_mode sequential when missing' do
data = valid_rule_data.except('chain_mode')
result = loader.load_rule_json(data)
expect(result['success']).to be true
expect(result).to have_key('rule_id')
end
end
end