From 9adaad87280432d91f4bd1f97796808f5d8bc80d Mon Sep 17 00:00:00 2001 From: DualFroz Date: Fri, 28 Aug 2026 14:20:00 +0200 Subject: [PATCH] test: add middleware and static file tests --- test/test_middleware_params.rb | 43 ++++++++++++++++++++ test/test_middleware_static.rb | 71 ++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 test/test_middleware_params.rb create mode 100644 test/test_middleware_static.rb diff --git a/test/test_middleware_params.rb b/test/test_middleware_params.rb new file mode 100644 index 0000000..d3eada3 --- /dev/null +++ b/test/test_middleware_params.rb @@ -0,0 +1,43 @@ +require 'minitest/autorun' +require 'prism' +require 'support' + +class MiddlewareParamsTest < Minitest::Test + include TestSupport + + def setup + @seen_env = nil + downstream = lambda do |env| + @seen_env = env + [200, {}, ['ok']] + end + @app = Prism::Middleware::ParamsParser.new(downstream) + end + + def test_valid_json_body_passes_through + env = env_for('POST', '/echo', headers: { 'Content-Type' => 'application/json' }, body: '{"a":1}') + status, = @app.call(env) + assert_equal 200, status + end + + def test_malformed_json_body_returns_400_before_reaching_app + env = env_for('POST', '/echo', headers: { 'Content-Type' => 'application/json' }, body: '{not-json') + status, headers, body = @app.call(env) + assert_equal 400, status + assert_equal 'application/json', headers['Content-Type'] + assert_includes JSON.parse(body.join)['error'], 'invalid JSON' + assert_nil @seen_env, 'downstream app must not run on malformed body' + end + + def test_downstream_can_still_read_the_body_after_validation + env = env_for('POST', '/echo', headers: { 'Content-Type' => 'application/json' }, body: '{"a":1}') + @app.call(env) + assert_equal({ 'a' => 1 }, JSON.parse(@seen_env['rack.input'].read)) + end + + def test_non_json_body_is_left_alone + env = env_for('POST', '/echo', headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }, body: 'a=1') + status, = @app.call(env) + assert_equal 200, status + end +end diff --git a/test/test_middleware_static.rb b/test/test_middleware_static.rb new file mode 100644 index 0000000..f236894 --- /dev/null +++ b/test/test_middleware_static.rb @@ -0,0 +1,71 @@ +require 'minitest/autorun' +require 'prism' +require 'tmpdir' +require 'fileutils' + +class MiddlewareStaticTest < Minitest::Test + def setup + @root = Dir.mktmpdir('prism-static-root') + File.write(File.join(@root, 'index.html'), '

static

') + FileUtils.mkdir_p(File.join(@root, 'css')) + File.write(File.join(@root, 'css', 'app.css'), 'body { color: red; }') + @downstream = ->(env) { [404, {}, ["app: #{env['PATH_INFO']}"]] } + @app = Prism::Middleware::Static.new(@downstream, root: @root) + end + + def teardown + FileUtils.remove_entry(@root) + end + + def env_for(path, method: 'GET') + { 'REQUEST_METHOD' => method, 'PATH_INFO' => path } + end + + def test_serves_existing_file + status, headers, body = @app.call(env_for('/index.html')) + assert_equal 200, status + assert_equal 'text/html;charset=utf-8', headers['Content-Type'] + assert_equal '

static

', body.join + end + + def test_serves_nested_file_with_correct_content_type + status, headers, body = @app.call(env_for('/css/app.css')) + assert_equal 200, status + assert_equal 'text/css', headers['Content-Type'] + assert_equal 'body { color: red; }', body.join + end + + def test_falls_through_to_app_when_file_missing + status, _, body = @app.call(env_for('/nope.html')) + assert_equal 404, status + assert_equal 'app: /nope.html', body.join + end + + def test_blocks_path_traversal_outside_root + status, _, body = @app.call(env_for('/../../../../etc/passwd')) + assert_equal 404, status + assert_equal 'app: /../../../../etc/passwd', body.join + end + + def test_serves_directory_index_when_requesting_a_folder + FileUtils.mkdir_p(File.join(@root, 'docs')) + File.write(File.join(@root, 'docs', 'index.html'), '

docs home

') + status, headers, body = @app.call(env_for('/docs')) + assert_equal 200, status + assert_equal 'text/html;charset=utf-8', headers['Content-Type'] + assert_equal '

docs home

', body.join + end + + def test_falls_through_when_directory_has_no_index_file + FileUtils.mkdir_p(File.join(@root, 'empty-dir')) + status, _, body = @app.call(env_for('/empty-dir')) + assert_equal 404, status + assert_equal 'app: /empty-dir', body.join + end + + def test_ignores_non_get_head_requests + status, _, body = @app.call(env_for('/index.html', method: 'POST')) + assert_equal 404, status + assert_equal 'app: /index.html', body.join + end +end