From 99bbae80998227cd002305830f23db856c42ec8e Mon Sep 17 00:00:00 2001 From: DualFroz Date: Wed, 9 Sep 2026 15:48:30 +0200 Subject: [PATCH] test: cover test_dispatch_emits_process_action_event_with_status --- test/test_application.rb | 28 ++++++++++++ test/test_application_error_handling.rb | 57 +++++++++++++++++++++++++ test/test_application_mount.rb | 52 ++++++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 test/test_application_error_handling.rb create mode 100644 test/test_application_mount.rb diff --git a/test/test_application.rb b/test/test_application.rb index 4fcec4e..9e45b94 100644 --- a/test/test_application.rb +++ b/test/test_application.rb @@ -133,4 +133,32 @@ class ApplicationTest < Minitest::Test assert_equal 200, status assert_equal '', body.join end + + def test_dispatch_emits_process_action_event_with_status + events = [] + subscriber = Prism::Instrumentation.subscribe('process_action.prism') { |event| events << event } + begin + call('GET', '/users/9') + ensure + Prism::Instrumentation.unsubscribe(subscriber) + end + + assert_equal 1, events.size + assert_equal 'GET', events.first.payload[:method] + assert_equal '/users/9', events.first.payload[:path] + assert_equal 200, events.first.payload[:status] + end + + def test_dispatch_emits_event_for_not_found_too + events = [] + subscriber = Prism::Instrumentation.subscribe('process_action.prism') { |event| events << event } + begin + call('GET', '/missing') + ensure + Prism::Instrumentation.unsubscribe(subscriber) + end + + assert_equal 1, events.size + assert_equal 404, events.first.payload[:status] + end end diff --git a/test/test_application_error_handling.rb b/test/test_application_error_handling.rb new file mode 100644 index 0000000..3f12abe --- /dev/null +++ b/test/test_application_error_handling.rb @@ -0,0 +1,57 @@ +require 'minitest/autorun' +require 'prism' +require 'support' + +class ErrorHandlingBoomController < Prism::Controller + def index + raise 'kaboom, no rescue_from anywhere for this one' + end +end + +class ErrorHandlingFineController < Prism::Controller + def index + halt(200, 'fine') + end +end + +class ErrorHandlingApp < Prism::Application + get '/boom', to: 'error_handling_boom#index' + get '/fine', to: 'error_handling_fine#index' +end + +class ApplicationErrorHandlingTest < Minitest::Test + include TestSupport + + def call(method, path, **opts) + ErrorHandlingApp.call(env_for(method, path, **opts)) + end + + def test_unhandled_exception_becomes_a_safe_500_instead_of_crashing_the_request + status, headers, body = call('GET', '/boom') + assert_equal 500, status + assert_equal 'text/plain', headers['Content-Type'] + assert_equal 'Internal Server Error', body.join + end + + def test_the_500_body_never_leaks_the_exception_message + _, _, body = call('GET', '/boom') + refute_includes body.join, 'kaboom' + end + + def test_unrelated_requests_are_unaffected_by_the_fallback + status, _, body = call('GET', '/fine') + assert_equal 200, status + assert_equal 'fine', body.join + end + + def test_the_exception_is_still_recorded_on_the_instrumentation_payload + events = [] + subscriber = Prism::Instrumentation.subscribe('process_action.prism') { |event| events << event } + call('GET', '/boom') + klass, message = events.last.payload[:exception] + assert_equal 'RuntimeError', klass + assert_includes message, 'kaboom' + ensure + Prism::Instrumentation.unsubscribe(subscriber) + end +end diff --git a/test/test_application_mount.rb b/test/test_application_mount.rb new file mode 100644 index 0000000..a5ebeae --- /dev/null +++ b/test/test_application_mount.rb @@ -0,0 +1,52 @@ +require 'minitest/autorun' +require 'prism' +require 'support' + +class EchoMountedApp + def call(env) + [200, { 'Content-Type' => 'text/plain' }, + ["script_name=#{env['SCRIPT_NAME']} path_info=#{env['PATH_INFO']}"]] + end +end + +class MountApp < Prism::Application + mount '/admin', EchoMountedApp.new + + get '/host-route' do + 'host app route' + end +end + +class MountPrecedenceApp < Prism::Application + mount '/shared', EchoMountedApp.new + + get '/shared' do + 'host app route wins' + end +end + +class ApplicationMountTest < Minitest::Test + include TestSupport + + def test_mounted_app_receives_rewritten_script_name_and_path_info + status, _, body = MountApp.call(env_for('GET', '/admin/users/1')) + assert_equal 200, status + assert_equal 'script_name=/admin path_info=/users/1', body.join + end + + def test_mounted_app_receives_root_path_info_at_bare_prefix + _, _, body = MountApp.call(env_for('GET', '/admin')) + assert_equal 'script_name=/admin path_info=/', body.join + end + + def test_host_applications_own_routes_take_precedence_over_mounts + status, _, body = MountPrecedenceApp.call(env_for('GET', '/shared')) + assert_equal 200, status + assert_equal 'host app route wins', body.join + end + + def test_unmatched_path_outside_any_mount_still_404s + status, = MountApp.call(env_for('GET', '/nowhere')) + assert_equal 404, status + end +end