From 58696560dda1556f1d1ae16d69c3542e7cc69898 Mon Sep 17 00:00:00 2001 From: Jake Webster Date: Fri, 23 Jan 2026 12:56:46 +1000 Subject: [PATCH] TEST: core main network specs --- spec/beef/core/main/network_stack/api_spec.rb | 10 ++ .../main/network_stack/assethandler_spec.rb | 143 ++++++++++++++++++ .../main/network_stack/handlers/raw_spec.rb | 45 ++++++ 3 files changed, 198 insertions(+) create mode 100644 spec/beef/core/main/network_stack/api_spec.rb create mode 100644 spec/beef/core/main/network_stack/assethandler_spec.rb create mode 100644 spec/beef/core/main/network_stack/handlers/raw_spec.rb diff --git a/spec/beef/core/main/network_stack/api_spec.rb b/spec/beef/core/main/network_stack/api_spec.rb new file mode 100644 index 000000000..d6705b0a3 --- /dev/null +++ b/spec/beef/core/main/network_stack/api_spec.rb @@ -0,0 +1,10 @@ +RSpec.describe BeEF::Core::NetworkStack::RegisterHttpHandler do + describe '.mount_handler' do + let(:mock_server) { double('server', mount: true) } + + it 'mounts dynamic reconstruction handler' do + expect(mock_server).to receive(:mount).with('/dh', anything) + described_class.mount_handler(mock_server) + end + end +end diff --git a/spec/beef/core/main/network_stack/assethandler_spec.rb b/spec/beef/core/main/network_stack/assethandler_spec.rb new file mode 100644 index 000000000..fa4995718 --- /dev/null +++ b/spec/beef/core/main/network_stack/assethandler_spec.rb @@ -0,0 +1,143 @@ +RSpec.describe BeEF::Core::NetworkStack::Handlers::AssetHandler do + let(:handler) { described_class.instance } + + before do + @mock_server = double('server', mount: true, unmount: true, remap: true) + allow(BeEF::Core::Server).to receive(:instance).and_return(@mock_server) + # Reset singleton state + handler.instance_variable_set(:@allocations, {}) + handler.instance_variable_set(:@sockets, {}) + handler.instance_variable_set(:@http_server, @mock_server) + end + + describe '#initialize' do + it 'initializes with empty allocations and sockets' do + expect(handler.allocations).to eq({}) + expect(handler.root_dir).to be_a(String) + end + end + + describe '#build_url' do + it 'returns path when path is provided' do + expect(handler.build_url('/test', nil)).to eq('/test') + end + + it 'appends extension when provided' do + expect(handler.build_url('/test', 'js')).to eq('/test.js') + end + + it 'generates random URL when path is nil' do + url = handler.build_url(nil, nil) + expect(url).to start_with('/') + expect(url.length).to be > 1 + end + + it 'generates random URL with extension when path is nil' do + url = handler.build_url(nil, 'js') + expect(url).to end_with('.js') + expect(url).to start_with('/') + end + end + + describe '#check' do + it 'returns false when URL is not allocated' do + expect(handler.check('/nonexistent')).to be false + end + + it 'returns true when count is -1 (unlimited)' do + handler.instance_variable_set(:@allocations, { '/test' => { 'count' => -1 } }) + expect(handler.check('/test')).to be true + end + + it 'decrements count and returns true when count > 0' do + handler.instance_variable_set(:@allocations, { '/test' => { 'count' => 2 } }) + expect(handler.check('/test')).to be true + expect(handler.allocations['/test']['count']).to eq(1) + end + + it 'unbinds when count reaches 0' do + handler.instance_variable_set(:@allocations, { '/test' => { 'count' => 1 } }) + expect(handler).to receive(:unbind).with('/test') + handler.check('/test') + end + + it 'returns false when count is 0' do + handler.instance_variable_set(:@allocations, { '/test' => { 'count' => 0 } }) + expect(handler.check('/test')).to be false + end + end + + describe '#bind_redirect' do + it 'binds redirector to URL' do + expect(@mock_server).to receive(:mount) + expect(@mock_server).to receive(:remap) + url = handler.bind_redirect('http://example.com', '/redirect') + expect(url).to eq('/redirect') + expect(handler.allocations['/redirect']).to eq({ 'target' => 'http://example.com' }) + end + + it 'generates random URL when path is nil' do + expect(@mock_server).to receive(:mount) + expect(@mock_server).to receive(:remap) + url = handler.bind_redirect('http://example.com') + expect(url).to start_with('/') + expect(handler.allocations[url]).not_to be_nil + end + end + + describe '#bind_raw' do + it 'binds raw HTTP response to URL' do + expect(@mock_server).to receive(:mount) + expect(@mock_server).to receive(:remap) + url = handler.bind_raw('200', { 'Content-Type' => 'text/html' }, '', '/raw') + expect(url).to eq('/raw') + expect(handler.allocations['/raw']).to eq({}) + end + end + + describe '#bind' do + let(:test_file) { '/spec/support/assets/test.txt' } + let(:test_file_path) { File.join(handler.root_dir, test_file) } + + before do + FileUtils.mkdir_p(File.dirname(test_file_path)) + File.write(test_file_path, 'test content') + end + + after do + FileUtils.rm_f(test_file_path) + end + + it 'binds file to URL when file exists' do + expect(@mock_server).to receive(:mount) + expect(@mock_server).to receive(:remap) + url = handler.bind(test_file, '/test') + expect(url).to eq('/test') + expect(handler.allocations['/test']['file']).to include(test_file) + end + + it 'returns nil when file does not exist' do + expect(@mock_server).not_to receive(:mount) + result = handler.bind('/nonexistent/file.txt', '/test') + expect(result).to be_nil + end + + it 'uses text/plain content type when extension is nil' do + expect(@mock_server).to receive(:mount) do |_url, handler_obj| + expect(handler_obj.instance_variable_get(:@header)['Content-Type']).to eq('text/plain') + end + expect(@mock_server).to receive(:remap) + handler.bind(test_file, '/test', nil) + end + end + + describe '#unbind' do + it 'removes allocation and unmounts URL' do + handler.instance_variable_set(:@allocations, { '/test' => {} }) + expect(@mock_server).to receive(:unmount).with('/test') + expect(@mock_server).to receive(:remap) + handler.unbind('/test') + expect(handler.allocations).not_to have_key('/test') + end + end +end diff --git a/spec/beef/core/main/network_stack/handlers/raw_spec.rb b/spec/beef/core/main/network_stack/handlers/raw_spec.rb new file mode 100644 index 000000000..1fe50b79e --- /dev/null +++ b/spec/beef/core/main/network_stack/handlers/raw_spec.rb @@ -0,0 +1,45 @@ +RSpec.describe BeEF::Core::NetworkStack::Handlers::Raw do + describe '#initialize' do + it 'initializes with status, header, and body' do + handler = described_class.new('200', { 'Content-Type' => 'text/html' }, '') + expect(handler.instance_variable_get(:@status)).to eq('200') + expect(handler.instance_variable_get(:@header)).to eq({ 'Content-Type' => 'text/html' }) + expect(handler.instance_variable_get(:@body)).to eq('') + end + + it 'initializes with default empty header and nil body' do + handler = described_class.new('404') + expect(handler.instance_variable_get(:@status)).to eq('404') + expect(handler.instance_variable_get(:@header)).to eq({}) + expect(handler.instance_variable_get(:@body)).to be_nil + end + end + + describe '#call' do + it 'returns Rack::Response with correct status, header, and body' do + handler = described_class.new('200', { 'Content-Type' => 'text/html' }, '') + response = handler.call({}) + + expect(response).to be_a(Rack::Response) + expect(response.status).to eq(200) + expect(response.headers['Content-Type']).to eq('text/html') + expect(response.body).to eq(['']) + end + + it 'handles different status codes' do + handler = described_class.new('404', {}, 'Not Found') + response = handler.call({}) + + expect(response.status).to eq(404) + expect(response.body).to eq(['Not Found']) + end + + it 'handles nil body' do + handler = described_class.new('204', {}) + response = handler.call({}) + + expect(response.status).to eq(204) + expect(response.body).to eq([]) + end + end +end