From cd6820179f2d0a35f1da055a6d5d88ec2663339c Mon Sep 17 00:00:00 2001 From: phg Date: Thu, 31 Jul 2025 08:48:02 +0200 Subject: [PATCH] Refactor test error handling and status updates in HostsManagerApp tests --- tests/test_main.py | 56 +++++++++++++-------------- tests/test_save_confirmation_modal.py | 6 ++- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 2851847..65e431e 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -74,7 +74,7 @@ class TestHostsManagerApp: """Test handling of missing hosts file.""" mock_parser = Mock(spec=HostsParser) mock_config = Mock(spec=Config) - mock_parser.parse.side_effect = FileNotFoundError("File not found") + mock_parser.parse.side_effect = FileNotFoundError("Hosts file not found") with patch('hosts.tui.app.HostsParser', return_value=mock_parser), \ patch('hosts.tui.app.Config', return_value=mock_config): @@ -85,7 +85,7 @@ class TestHostsManagerApp: app.load_hosts_file() # Should handle error gracefully - app.update_status.assert_called_with("Error: Hosts file not found") + app.update_status.assert_called_with("❌ Error loading hosts file: Hosts file not found") def test_load_hosts_file_permission_error(self): """Test handling of permission denied error.""" @@ -102,7 +102,7 @@ class TestHostsManagerApp: app.load_hosts_file() # Should handle error gracefully - app.update_status.assert_called_with("Error: Permission denied") + app.update_status.assert_called_with("❌ Error loading hosts file: Permission denied") def test_populate_entries_table_logic(self): """Test populating DataTable logic without UI dependencies.""" @@ -207,10 +207,6 @@ class TestHostsManagerApp: app = HostsManagerApp() - # Mock the query_one method - mock_status = Mock() - app.query_one = Mock(return_value=mock_status) - # Add test entries app.hosts_file = HostsFile() app.hosts_file.add_entry(HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])) @@ -222,12 +218,10 @@ class TestHostsManagerApp: app.update_status() - # Verify status was updated - mock_status.update.assert_called_once() - call_args = mock_status.update.call_args[0][0] - assert "Read-only mode" in call_args - assert "2 entries" in call_args - assert "1 active" in call_args + # Verify sub_title was set correctly + assert "Read-only mode" in app.sub_title + assert "2 entries" in app.sub_title + assert "1 active" in app.sub_title def test_update_status_custom_message(self): """Test status bar update with custom message.""" @@ -239,15 +233,13 @@ class TestHostsManagerApp: app = HostsManagerApp() - # Mock the query_one method and set_timer to avoid event loop issues - mock_status = Mock() - app.query_one = Mock(return_value=mock_status) + # Mock set_timer to avoid event loop issues app.set_timer = Mock() # Mock the timer to avoid event loop issues app.update_status("Custom status message") - # Verify status was updated with custom message - mock_status.update.assert_called_once_with("Custom status message") + # Verify sub_title was set with custom message + assert app.sub_title == "Custom status message" # Verify timer was set for auto-clearing app.set_timer.assert_called_once() @@ -320,19 +312,21 @@ class TestHostsManagerApp: app.hosts_file.add_entry(HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])) app.hosts_file.add_entry(HostEntry(ip_address="10.0.0.1", hostnames=["test"])) - app.populate_entries_table = Mock() + # Mock the table_handler methods to avoid UI queries + app.table_handler.populate_entries_table = Mock() + app.table_handler.restore_cursor_position = Mock() app.update_status = Mock() app.action_sort_by_ip() - # Check that entries are sorted with default entries on top - assert app.hosts_file.entries[0].ip_address == "127.0.0.1" # Default entry first - assert app.hosts_file.entries[1].ip_address == "10.0.0.1" # Then sorted non-defaults + # Check that entries are sorted by IP address + assert app.hosts_file.entries[0].ip_address == "10.0.0.1" # Sorted by IP + assert app.hosts_file.entries[1].ip_address == "127.0.0.1" assert app.hosts_file.entries[2].ip_address == "192.168.1.1" assert app.sort_column == "ip" assert app.sort_ascending is True - app.populate_entries_table.assert_called_once() + app.table_handler.populate_entries_table.assert_called_once() def test_action_sort_by_hostname_ascending(self): """Test sorting by hostname in ascending order.""" @@ -350,7 +344,9 @@ class TestHostsManagerApp: app.hosts_file.add_entry(HostEntry(ip_address="192.168.1.1", hostnames=["alpha"])) app.hosts_file.add_entry(HostEntry(ip_address="10.0.0.1", hostnames=["beta"])) - app.populate_entries_table = Mock() + # Mock the table_handler methods to avoid UI queries + app.table_handler.populate_entries_table = Mock() + app.table_handler.restore_cursor_position = Mock() app.update_status = Mock() app.action_sort_by_hostname() @@ -362,7 +358,7 @@ class TestHostsManagerApp: assert app.sort_column == "hostname" assert app.sort_ascending is True - app.populate_entries_table.assert_called_once() + app.table_handler.populate_entries_table.assert_called_once() def test_data_table_row_highlighted_event(self): """Test DataTable row highlighting event handling.""" @@ -373,10 +369,10 @@ class TestHostsManagerApp: patch('hosts.tui.app.Config', return_value=mock_config): app = HostsManagerApp() - app.update_entry_details = Mock() - # Mock the display_index_to_actual_index method to return the same index - app.display_index_to_actual_index = Mock(return_value=2) + # Mock the details_handler and table_handler methods + app.details_handler.update_entry_details = Mock() + app.table_handler.display_index_to_actual_index = Mock(return_value=2) # Create mock event with required parameters mock_table = Mock() @@ -389,8 +385,8 @@ class TestHostsManagerApp: # Should update selected index and details assert app.selected_entry_index == 2 - app.update_entry_details.assert_called_once() - app.display_index_to_actual_index.assert_called_once_with(2) + app.details_handler.update_entry_details.assert_called_once() + app.table_handler.display_index_to_actual_index.assert_called_once_with(2) def test_data_table_header_selected_ip_column(self): """Test DataTable header selection for IP column.""" diff --git a/tests/test_save_confirmation_modal.py b/tests/test_save_confirmation_modal.py index 3f87b0b..705309c 100644 --- a/tests/test_save_confirmation_modal.py +++ b/tests/test_save_confirmation_modal.py @@ -279,7 +279,9 @@ class TestSaveConfirmationIntegration: """Test exit_edit_entry_mode cleans up properly.""" app.entry_edit_mode = True app.original_entry_values = {"test": "data"} - app.update_entry_details = Mock() + + # Mock the details_handler and query_one methods + app.details_handler.update_entry_details = Mock() app.query_one = Mock() app.update_status = Mock() @@ -290,6 +292,6 @@ class TestSaveConfirmationIntegration: assert not app.entry_edit_mode assert app.original_entry_values is None - app.update_entry_details.assert_called_once() + app.details_handler.update_entry_details.assert_called_once() mock_table.focus.assert_called_once() app.update_status.assert_called_once_with("Exited entry edit mode")