"""Tests unitarios para el módulo server.""" from unittest.mock import MagicMock, patch class TestRunServer: """Tests para la función run_server.""" # ======================================== # Tests para run_server - Complejidad Media # Path 1: Servidor inicia y sirve normalmente # Path 2: KeyboardInterrupt detiene el servidor # Path 3: Servidor se cierra correctamente en finally # ======================================== def test_run_server_creates_server_with_correct_address(self): """Test: run_server crea servidor en la dirección correcta.""" with patch("m3u_list_builder.server.settings") as mock_settings: mock_settings.port = 9999 mock_settings.output_file = "test.m3u" with patch( "m3u_list_builder.server.ThreadingHTTPServer" ) as mock_server_class: mock_server = MagicMock() mock_server.serve_forever.side_effect = KeyboardInterrupt() mock_server_class.return_value = mock_server from m3u_list_builder.server import run_server run_server() # Verificar que se creó con la dirección correcta mock_server_class.assert_called_once() call_args = mock_server_class.call_args[0] assert call_args[0] == ("", 9999) def test_run_server_uses_correct_port(self): """Test: run_server usa el puerto de settings.""" with patch("m3u_list_builder.server.settings") as mock_settings: mock_settings.port = 8080 mock_settings.output_file = "playlist.m3u" with patch( "m3u_list_builder.server.ThreadingHTTPServer" ) as mock_server_class: mock_server = MagicMock() mock_server.serve_forever.side_effect = KeyboardInterrupt() mock_server_class.return_value = mock_server from m3u_list_builder.server import run_server run_server() call_args = mock_server_class.call_args[0] assert call_args[0][1] == 8080 def test_run_server_calls_serve_forever(self): """Test: run_server llama a serve_forever.""" with patch("m3u_list_builder.server.settings") as mock_settings: mock_settings.port = 8080 mock_settings.output_file = "playlist.m3u" with patch( "m3u_list_builder.server.ThreadingHTTPServer" ) as mock_server_class: mock_server = MagicMock() mock_server.serve_forever.side_effect = KeyboardInterrupt() mock_server_class.return_value = mock_server from m3u_list_builder.server import run_server run_server() mock_server.serve_forever.assert_called_once() def test_run_server_handles_keyboard_interrupt(self): """Test: run_server maneja KeyboardInterrupt sin crash.""" with patch("m3u_list_builder.server.settings") as mock_settings: mock_settings.port = 8080 mock_settings.output_file = "playlist.m3u" with patch( "m3u_list_builder.server.ThreadingHTTPServer" ) as mock_server_class: mock_server = MagicMock() mock_server.serve_forever.side_effect = KeyboardInterrupt() mock_server_class.return_value = mock_server from m3u_list_builder.server import run_server # No debe lanzar excepción run_server() def test_run_server_closes_server_on_interrupt(self): """Test: run_server cierra el servidor tras KeyboardInterrupt.""" with patch("m3u_list_builder.server.settings") as mock_settings: mock_settings.port = 8080 mock_settings.output_file = "playlist.m3u" with patch( "m3u_list_builder.server.ThreadingHTTPServer" ) as mock_server_class: mock_server = MagicMock() mock_server.serve_forever.side_effect = KeyboardInterrupt() mock_server_class.return_value = mock_server from m3u_list_builder.server import run_server run_server() mock_server.server_close.assert_called_once() def test_run_server_closes_server_on_normal_exit(self): """Test: run_server cierra el servidor en salida normal.""" with patch("m3u_list_builder.server.settings") as mock_settings: mock_settings.port = 8080 mock_settings.output_file = "playlist.m3u" with patch( "m3u_list_builder.server.ThreadingHTTPServer" ) as mock_server_class: mock_server = MagicMock() # Simular que serve_forever termina normalmente mock_server.serve_forever.return_value = None mock_server_class.return_value = mock_server from m3u_list_builder.server import run_server run_server() mock_server.server_close.assert_called_once() def test_run_server_logs_startup_message(self, caplog): """Test: run_server registra mensaje de inicio.""" with patch("m3u_list_builder.server.settings") as mock_settings: mock_settings.port = 8080 mock_settings.output_file = "playlist.m3u" with patch( "m3u_list_builder.server.ThreadingHTTPServer" ) as mock_server_class: mock_server = MagicMock() mock_server.serve_forever.side_effect = KeyboardInterrupt() mock_server_class.return_value = mock_server import logging with caplog.at_level(logging.INFO): from m3u_list_builder.server import run_server run_server() # El mensaje puede estar en el log # Nota: Dependiendo del orden de imports, puede que no se capture def test_run_server_uses_simple_http_handler(self): """Test: run_server usa SimpleHTTPRequestHandler.""" with patch("m3u_list_builder.server.settings") as mock_settings: mock_settings.port = 8080 mock_settings.output_file = "playlist.m3u" with patch( "m3u_list_builder.server.ThreadingHTTPServer" ) as mock_server_class: with patch( "m3u_list_builder.server.SimpleHTTPRequestHandler" ) as mock_handler: mock_server = MagicMock() mock_server.serve_forever.side_effect = KeyboardInterrupt() mock_server_class.return_value = mock_server from m3u_list_builder.server import run_server run_server() # Verificar que se pasó el handler correcto call_args = mock_server_class.call_args[0] assert call_args[1] == mock_handler