Implement radio set for entry type selection in edit mode: add IP and DNS options, manage field visibility, and enhance form population logic.

This commit is contained in:
Philip Henning 2025-08-18 13:43:16 +02:00
parent 489fdf4b20
commit 90935e67a6
5 changed files with 715 additions and 133 deletions

View file

@ -587,6 +587,306 @@ class TestHostsManagerApp:
assert "c" in binding_keys
assert "ctrl+c" in binding_keys
def test_radio_set_event_handling_ip_entry(self):
"""Test radio set event handling for IP entry type."""
mock_parser = Mock(spec=HostsParser)
mock_config = Mock(spec=Config)
with (
patch("hosts.tui.app.HostsParser", return_value=mock_parser),
patch("hosts.tui.app.Config", return_value=mock_config),
):
app = HostsManagerApp()
app.edit_handler.handle_entry_type_change = Mock()
# Create mock radio set event for IP entry
mock_radio_set = Mock()
mock_radio_set.id = "edit-entry-type-radio"
mock_pressed_radio = Mock()
mock_pressed_radio.id = "edit-ip-entry-radio"
event = Mock()
event.radio_set = mock_radio_set
event.pressed = mock_pressed_radio
app.on_radio_set_changed(event)
# Should handle IP entry type change
app.edit_handler.handle_entry_type_change.assert_called_once_with("ip")
def test_radio_set_event_handling_dns_entry(self):
"""Test radio set event handling for DNS entry type."""
mock_parser = Mock(spec=HostsParser)
mock_config = Mock(spec=Config)
with (
patch("hosts.tui.app.HostsParser", return_value=mock_parser),
patch("hosts.tui.app.Config", return_value=mock_config),
):
app = HostsManagerApp()
app.edit_handler.handle_entry_type_change = Mock()
# Create mock radio set event for DNS entry
mock_radio_set = Mock()
mock_radio_set.id = "edit-entry-type-radio"
mock_pressed_radio = Mock()
mock_pressed_radio.id = "edit-dns-entry-radio"
event = Mock()
event.radio_set = mock_radio_set
event.pressed = mock_pressed_radio
app.on_radio_set_changed(event)
# Should handle DNS entry type change
app.edit_handler.handle_entry_type_change.assert_called_once_with("dns")
def test_entry_type_detection_ip_entry(self):
"""Test entry type detection for IP entries."""
mock_parser = Mock(spec=HostsParser)
mock_config = Mock(spec=Config)
with (
patch("hosts.tui.app.HostsParser", return_value=mock_parser),
patch("hosts.tui.app.Config", return_value=mock_config),
):
app = HostsManagerApp()
# Add IP entry (no DNS name)
app.hosts_file = HostsFile()
ip_entry = HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
app.hosts_file.add_entry(ip_entry)
app.selected_entry_index = 0
entry_type = app.edit_handler.get_current_entry_type()
assert entry_type == "ip"
def test_entry_type_detection_dns_entry(self):
"""Test entry type detection for DNS entries."""
mock_parser = Mock(spec=HostsParser)
mock_config = Mock(spec=Config)
with (
patch("hosts.tui.app.HostsParser", return_value=mock_parser),
patch("hosts.tui.app.Config", return_value=mock_config),
):
app = HostsManagerApp()
# Add DNS entry with DNS name
app.hosts_file = HostsFile()
dns_entry = HostEntry(ip_address="0.0.0.0", hostnames=["example"])
dns_entry.dns_name = "example.com"
app.hosts_file.add_entry(dns_entry)
app.selected_entry_index = 0
entry_type = app.edit_handler.get_current_entry_type()
assert entry_type == "dns"
def test_field_visibility_ip_type(self):
"""Test field visibility logic for IP entry type."""
mock_parser = Mock(spec=HostsParser)
mock_config = Mock(spec=Config)
with (
patch("hosts.tui.app.HostsParser", return_value=mock_parser),
patch("hosts.tui.app.Config", return_value=mock_config),
):
app = HostsManagerApp()
# Mock the section elements
mock_ip_section = Mock()
mock_dns_section = Mock()
def mock_query_one(selector):
if selector == "#edit-ip-section":
return mock_ip_section
elif selector == "#edit-dns-section":
return mock_dns_section
return Mock()
app.query_one = mock_query_one
app.edit_handler.update_field_visibility(show_ip=True, show_dns=False)
# IP section should be visible, DNS section hidden
mock_ip_section.remove_class.assert_called_with("hidden")
mock_dns_section.add_class.assert_called_with("hidden")
def test_field_visibility_dns_type(self):
"""Test field visibility logic for DNS entry type."""
mock_parser = Mock(spec=HostsParser)
mock_config = Mock(spec=Config)
with (
patch("hosts.tui.app.HostsParser", return_value=mock_parser),
patch("hosts.tui.app.Config", return_value=mock_config),
):
app = HostsManagerApp()
# Mock the section elements
mock_ip_section = Mock()
mock_dns_section = Mock()
def mock_query_one(selector):
if selector == "#edit-ip-section":
return mock_ip_section
elif selector == "#edit-dns-section":
return mock_dns_section
return Mock()
app.query_one = mock_query_one
app.edit_handler.update_field_visibility(show_ip=False, show_dns=True)
# DNS section should be visible, IP section hidden
mock_ip_section.add_class.assert_called_with("hidden")
mock_dns_section.remove_class.assert_called_with("hidden")
def test_populate_edit_form_with_ip_type_detection(self):
"""Test edit form population with IP type detection."""
mock_parser = Mock(spec=HostsParser)
mock_config = Mock(spec=Config)
with (
patch("hosts.tui.app.HostsParser", return_value=mock_parser),
patch("hosts.tui.app.Config", return_value=mock_config),
):
app = HostsManagerApp()
app.entry_edit_mode = True
# Add IP entry
app.hosts_file = HostsFile()
ip_entry = HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
app.hosts_file.add_entry(ip_entry)
app.selected_entry_index = 0
# Mock radio set and buttons
mock_radio_set = Mock()
mock_ip_radio = Mock()
mock_dns_radio = Mock()
def mock_query_one(selector):
if selector == "#edit-entry-type-radio":
return mock_radio_set
elif selector == "#edit-ip-entry-radio":
return mock_ip_radio
elif selector == "#edit-dns-entry-radio":
return mock_dns_radio
return Mock()
app.query_one = mock_query_one
app.edit_handler.handle_entry_type_change = Mock()
app.edit_handler.populate_edit_form_with_type_detection()
# Should set IP radio button as pressed
assert mock_radio_set.pressed_button == mock_ip_radio
app.edit_handler.handle_entry_type_change.assert_called_with("ip")
def test_populate_edit_form_with_dns_type_detection(self):
"""Test edit form population with DNS type detection."""
mock_parser = Mock(spec=HostsParser)
mock_config = Mock(spec=Config)
with (
patch("hosts.tui.app.HostsParser", return_value=mock_parser),
patch("hosts.tui.app.Config", return_value=mock_config),
):
app = HostsManagerApp()
app.entry_edit_mode = True
# Add DNS entry
app.hosts_file = HostsFile()
dns_entry = HostEntry(ip_address="0.0.0.0", hostnames=["example"])
dns_entry.dns_name = "example.com"
app.hosts_file.add_entry(dns_entry)
app.selected_entry_index = 0
# Mock radio set, buttons, and DNS input with proper value tracking
mock_radio_set = Mock()
mock_ip_radio = Mock()
mock_dns_radio = Mock()
# Use a simple object to track value assignment
class MockDNSInput:
def __init__(self):
self.value = ""
mock_dns_input = MockDNSInput()
def mock_query_one(selector, widget_type=None):
if selector == "#edit-entry-type-radio":
return mock_radio_set
elif selector == "#edit-ip-entry-radio":
return mock_ip_radio
elif selector == "#edit-dns-entry-radio":
return mock_dns_radio
elif selector == "#dns-name-input":
return mock_dns_input
return Mock()
app.query_one = mock_query_one
app.edit_handler.handle_entry_type_change = Mock()
app.edit_handler.populate_edit_form_with_type_detection()
# Should set DNS radio button as pressed and populate DNS field
assert mock_radio_set.pressed_button == mock_dns_radio
assert mock_dns_input.value == "example.com"
app.edit_handler.handle_entry_type_change.assert_called_with("dns")
def test_edit_form_initialization_calls_type_detection(self):
"""Test that edit form initialization calls type detection."""
mock_parser = Mock(spec=HostsParser)
mock_config = Mock(spec=Config)
with (
patch("hosts.tui.app.HostsParser", return_value=mock_parser),
patch("hosts.tui.app.Config", return_value=mock_config),
):
app = HostsManagerApp()
# Mock form elements
mock_details_display = Mock()
mock_edit_form = Mock()
mock_ip_input = Mock()
mock_hostname_input = Mock()
mock_comment_input = Mock()
mock_active_checkbox = Mock()
def mock_query_one(selector, widget_type=None):
if selector == "#entry-details-display":
return mock_details_display
elif selector == "#entry-edit-form":
return mock_edit_form
elif selector == "#ip-input":
return mock_ip_input
elif selector == "#hostname-input":
return mock_hostname_input
elif selector == "#comment-input":
return mock_comment_input
elif selector == "#active-checkbox":
return mock_active_checkbox
return Mock()
app.query_one = mock_query_one
# Add test entry
app.hosts_file = HostsFile()
test_entry = HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
app.hosts_file.add_entry(test_entry)
app.selected_entry_index = 0
# Mock the type detection method
app.edit_handler.populate_edit_form_with_type_detection = Mock()
app.details_handler.update_edit_form()
# Should call type detection method
app.edit_handler.populate_edit_form_with_type_detection.assert_called_once()
def test_main_function(self):
"""Test main entry point function."""
with patch("hosts.main.HostsManagerApp") as mock_app_class: