""" Tests for the configuration modal TUI component. This module contains unit tests for the ConfigModal class, validating modal behavior and configuration interaction. """ import pytest from unittest.mock import Mock, patch from textual.widgets import Checkbox, Button from hosts.core.config import Config from hosts.tui.config_modal import ConfigModal class TestConfigModal: """Test cases for the ConfigModal class.""" def test_modal_initialization(self): """Test modal initialization with config.""" mock_config = Mock(spec=Config) mock_config.should_show_default_entries.return_value = False modal = ConfigModal(mock_config) assert modal.config == mock_config def test_modal_compose_method_exists(self): """Test that modal has compose method.""" mock_config = Mock(spec=Config) mock_config.should_show_default_entries.return_value = True modal = ConfigModal(mock_config) # Test that compose method exists and is callable assert hasattr(modal, 'compose') assert callable(modal.compose) def test_action_save_updates_config(self): """Test that save action updates configuration.""" mock_config = Mock(spec=Config) mock_config.should_show_default_entries.return_value = False modal = ConfigModal(mock_config) modal.dismiss = Mock() # Mock the checkbox query mock_checkbox = Mock() mock_checkbox.value = True modal.query_one = Mock(return_value=mock_checkbox) # Trigger save action modal.action_save() # Verify config was updated mock_config.set.assert_called_once_with("show_default_entries", True) mock_config.save.assert_called_once() modal.dismiss.assert_called_once_with(True) def test_action_save_preserves_false_state(self): """Test that save action preserves False checkbox state.""" mock_config = Mock(spec=Config) mock_config.should_show_default_entries.return_value = True modal = ConfigModal(mock_config) modal.dismiss = Mock() # Mock the checkbox query with False value mock_checkbox = Mock() mock_checkbox.value = False modal.query_one = Mock(return_value=mock_checkbox) # Trigger save action modal.action_save() # Verify the False value was saved mock_config.set.assert_called_once_with("show_default_entries", False) mock_config.save.assert_called_once() modal.dismiss.assert_called_once_with(True) def test_action_cancel_no_config_changes(self): """Test that cancel action doesn't modify configuration.""" mock_config = Mock(spec=Config) mock_config.should_show_default_entries.return_value = False modal = ConfigModal(mock_config) modal.dismiss = Mock() # Trigger cancel action modal.action_cancel() # Verify config was NOT updated mock_config.set.assert_not_called() mock_config.save.assert_not_called() modal.dismiss.assert_called_once_with(False) def test_save_button_pressed_event(self): """Test save button pressed event handling.""" mock_config = Mock(spec=Config) mock_config.should_show_default_entries.return_value = False modal = ConfigModal(mock_config) modal.action_save = Mock() # Create mock save button save_button = Mock() save_button.id = "save-button" event = Button.Pressed(save_button) modal.on_button_pressed(event) modal.action_save.assert_called_once() def test_cancel_button_pressed_event(self): """Test cancel button pressed event handling.""" mock_config = Mock(spec=Config) mock_config.should_show_default_entries.return_value = False modal = ConfigModal(mock_config) modal.action_cancel = Mock() # Create mock cancel button cancel_button = Mock() cancel_button.id = "cancel-button" event = Button.Pressed(cancel_button) modal.on_button_pressed(event) modal.action_cancel.assert_called_once() def test_unknown_button_pressed_ignored(self): """Test that unknown button presses are ignored.""" mock_config = Mock(spec=Config) mock_config.should_show_default_entries.return_value = False modal = ConfigModal(mock_config) modal.action_save = Mock() modal.action_cancel = Mock() # Create a mock button with unknown ID unknown_button = Mock() unknown_button.id = "unknown-button" event = Button.Pressed(unknown_button) # Should not raise exception modal.on_button_pressed(event) # Should not trigger any actions modal.action_save.assert_not_called() modal.action_cancel.assert_not_called() def test_modal_bindings_defined(self): """Test that modal has expected key bindings.""" mock_config = Mock(spec=Config) modal = ConfigModal(mock_config) # Check that bindings are defined assert len(modal.BINDINGS) == 2 # Check specific bindings binding_keys = [binding.key for binding in modal.BINDINGS] assert "escape" in binding_keys assert "enter" in binding_keys binding_actions = [binding.action for binding in modal.BINDINGS] assert "cancel" in binding_actions assert "save" in binding_actions def test_modal_css_defined(self): """Test that modal has CSS styling defined.""" mock_config = Mock(spec=Config) modal = ConfigModal(mock_config) # Check that CSS is defined assert hasattr(modal, 'CSS') assert isinstance(modal.CSS, str) assert len(modal.CSS) > 0 # Check for key CSS classes assert "config-container" in modal.CSS assert "config-title" in modal.CSS assert "button-row" in modal.CSS def test_config_method_called_during_initialization(self): """Test that config method is called during modal setup.""" mock_config = Mock(spec=Config) # Test with True mock_config.should_show_default_entries.return_value = True modal = ConfigModal(mock_config) # Verify the config object is stored assert modal.config == mock_config # Test with False mock_config.should_show_default_entries.return_value = False modal = ConfigModal(mock_config) # Verify the config object is stored assert modal.config == mock_config def test_compose_method_signature(self): """Test that compose method has the expected signature.""" mock_config = Mock(spec=Config) mock_config.should_show_default_entries.return_value = False modal = ConfigModal(mock_config) # Test that compose method exists and has correct signature import inspect sig = inspect.signature(modal.compose) assert len(sig.parameters) == 0 # No parameters except self # Test return type annotation if present if sig.return_annotation != inspect.Signature.empty: from textual.app import ComposeResult assert sig.return_annotation == ComposeResult def test_modal_inheritance(self): """Test that ConfigModal properly inherits from ModalScreen.""" mock_config = Mock(spec=Config) modal = ConfigModal(mock_config) from textual.screen import ModalScreen assert isinstance(modal, ModalScreen) # Should have the config attribute assert hasattr(modal, 'config') assert modal.config == mock_config