Enhance status display and entry details in HostsManagerApp
- Updated header title to "/etc/hosts Manager" and modified subtitle format. - Implemented a dedicated overlay status bar for error messages, ensuring no layout shifts. - Refactored entry details display to use DataTable with labeled rows for improved consistency. - Added CSS styles for the new status bar and DataTable. - Created tests for status bar visibility and DataTable functionality, ensuring all tests pass.
This commit is contained in:
parent
999b949f32
commit
25001042e5
11 changed files with 524 additions and 98 deletions
|
@ -22,8 +22,8 @@ class TestHostsManagerApp:
|
|||
with patch('hosts.tui.app.HostsParser'), patch('hosts.tui.app.Config'):
|
||||
app = HostsManagerApp()
|
||||
|
||||
assert app.title == "Hosts Manager"
|
||||
assert app.sub_title == "Read-only mode"
|
||||
assert app.title == "/etc/hosts Manager"
|
||||
assert app.sub_title == "" # Now set by update_status
|
||||
assert app.edit_mode is False
|
||||
assert app.selected_entry_index == 0
|
||||
assert app.sort_column == ""
|
||||
|
@ -142,15 +142,26 @@ class TestHostsManagerApp:
|
|||
"""Test updating entry details pane."""
|
||||
mock_parser = Mock(spec=HostsParser)
|
||||
mock_config = Mock(spec=Config)
|
||||
mock_config.should_show_default_entries.return_value = True
|
||||
|
||||
with patch('hosts.tui.app.HostsParser', return_value=mock_parser), \
|
||||
patch('hosts.tui.app.Config', return_value=mock_config):
|
||||
|
||||
app = HostsManagerApp()
|
||||
|
||||
# Mock the query_one method
|
||||
mock_details = Mock()
|
||||
app.query_one = Mock(return_value=mock_details)
|
||||
# Mock the query_one method to return DataTable mock
|
||||
mock_details_table = Mock()
|
||||
mock_details_table.columns = [] # Mock empty columns list
|
||||
mock_edit_form = Mock()
|
||||
|
||||
def mock_query_one(selector, widget_type=None):
|
||||
if selector == "#entry-details-table":
|
||||
return mock_details_table
|
||||
elif selector == "#entry-edit-form":
|
||||
return mock_edit_form
|
||||
return Mock()
|
||||
|
||||
app.query_one = mock_query_one
|
||||
|
||||
# Add test entry
|
||||
app.hosts_file = HostsFile()
|
||||
|
@ -164,12 +175,12 @@ class TestHostsManagerApp:
|
|||
|
||||
app.update_entry_details()
|
||||
|
||||
# Verify update was called with content containing entry details
|
||||
mock_details.update.assert_called_once()
|
||||
call_args = mock_details.update.call_args[0][0]
|
||||
assert "127.0.0.1" in call_args
|
||||
assert "localhost, local" in call_args
|
||||
assert "Test comment" in call_args
|
||||
# Verify DataTable operations were called
|
||||
mock_details_table.remove_class.assert_called_with("hidden")
|
||||
mock_edit_form.add_class.assert_called_with("hidden")
|
||||
mock_details_table.clear.assert_called_once()
|
||||
mock_details_table.add_column.assert_called()
|
||||
mock_details_table.add_row.assert_called()
|
||||
|
||||
def test_update_entry_details_no_entries(self):
|
||||
"""Test updating entry details with no entries."""
|
||||
|
@ -181,16 +192,29 @@ class TestHostsManagerApp:
|
|||
|
||||
app = HostsManagerApp()
|
||||
|
||||
# Mock the query_one method
|
||||
mock_details = Mock()
|
||||
app.query_one = Mock(return_value=mock_details)
|
||||
# Mock the query_one method to return DataTable mock
|
||||
mock_details_table = Mock()
|
||||
mock_details_table.columns = [] # Mock empty columns list
|
||||
mock_edit_form = Mock()
|
||||
|
||||
def mock_query_one(selector, widget_type=None):
|
||||
if selector == "#entry-details-table":
|
||||
return mock_details_table
|
||||
elif selector == "#entry-edit-form":
|
||||
return mock_edit_form
|
||||
return Mock()
|
||||
|
||||
app.query_one = mock_query_one
|
||||
app.hosts_file = HostsFile()
|
||||
|
||||
app.update_entry_details()
|
||||
|
||||
# Verify update was called with "No entries loaded"
|
||||
mock_details.update.assert_called_once_with("No entries loaded")
|
||||
# Verify DataTable operations were called for empty state
|
||||
mock_details_table.remove_class.assert_called_with("hidden")
|
||||
mock_edit_form.add_class.assert_called_with("hidden")
|
||||
mock_details_table.clear.assert_called_once()
|
||||
mock_details_table.add_column.assert_called_with("Field", key="field")
|
||||
mock_details_table.add_row.assert_called_with("No entries loaded")
|
||||
|
||||
def test_update_status_default(self):
|
||||
"""Test status bar update with default information."""
|
||||
|
@ -233,13 +257,24 @@ class TestHostsManagerApp:
|
|||
|
||||
app = HostsManagerApp()
|
||||
|
||||
# Mock set_timer to avoid event loop issues
|
||||
app.set_timer = Mock() # Mock the timer to avoid event loop issues
|
||||
# Mock set_timer and query_one to avoid event loop and UI issues
|
||||
app.set_timer = Mock()
|
||||
mock_status_bar = Mock()
|
||||
app.query_one = Mock(return_value=mock_status_bar)
|
||||
|
||||
# Add test hosts_file for subtitle generation
|
||||
app.hosts_file = HostsFile()
|
||||
app.hosts_file.add_entry(HostEntry(ip_address="127.0.0.1", hostnames=["localhost"]))
|
||||
app.hosts_file.add_entry(HostEntry(ip_address="192.168.1.1", hostnames=["router"], is_active=False))
|
||||
|
||||
app.update_status("Custom status message")
|
||||
|
||||
# Verify sub_title was set with custom message
|
||||
assert app.sub_title == "Custom status message"
|
||||
# Verify status bar was updated with custom message
|
||||
mock_status_bar.update.assert_called_with("Custom status message")
|
||||
mock_status_bar.remove_class.assert_called_with("hidden")
|
||||
# Verify subtitle shows current status (not the custom message)
|
||||
assert "2 entries" in app.sub_title
|
||||
assert "Read-only mode" in app.sub_title
|
||||
# Verify timer was set for auto-clearing
|
||||
app.set_timer.assert_called_once()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue