Implement command pattern for undo/redo functionality in HostsManager
- Added command classes: ToggleEntryCommand, MoveEntryCommand, AddEntryCommand, DeleteEntryCommand, UpdateEntryCommand. - Integrated UndoRedoHistory to manage command execution and history. - Updated HostsManager to use command-based methods for editing entries with undo/redo support. - Enhanced HostsManagerApp to display undo/redo status and handle undo/redo actions via keyboard shortcuts. - Refactored navigation handler to utilize command-based methods for toggling and moving entries. - Created comprehensive tests for command classes and integration with HostsManager.
This commit is contained in:
parent
77d4a2e955
commit
bc0f8b99e8
8 changed files with 1461 additions and 55 deletions
584
tests/test_commands.py
Normal file
584
tests/test_commands.py
Normal file
|
@ -0,0 +1,584 @@
|
|||
"""
|
||||
Tests for the command pattern implementation in the hosts TUI application.
|
||||
|
||||
This module tests the undo/redo functionality, command pattern,
|
||||
and integration with the HostsManager.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch
|
||||
from src.hosts.core.commands import (
|
||||
Command,
|
||||
OperationResult,
|
||||
UndoRedoHistory,
|
||||
ToggleEntryCommand,
|
||||
MoveEntryCommand,
|
||||
AddEntryCommand,
|
||||
DeleteEntryCommand,
|
||||
UpdateEntryCommand,
|
||||
)
|
||||
from src.hosts.core.models import HostEntry, HostsFile
|
||||
from src.hosts.core.manager import HostsManager
|
||||
|
||||
|
||||
class TestOperationResult:
|
||||
"""Test the OperationResult class."""
|
||||
|
||||
def test_operation_result_success(self):
|
||||
"""Test successful operation result."""
|
||||
result = OperationResult(True, "Operation successful")
|
||||
assert result.success is True
|
||||
assert result.message == "Operation successful"
|
||||
|
||||
def test_operation_result_failure(self):
|
||||
"""Test failed operation result."""
|
||||
result = OperationResult(False, "Operation failed")
|
||||
assert result.success is False
|
||||
assert result.message == "Operation failed"
|
||||
|
||||
def test_operation_result_with_data(self):
|
||||
"""Test operation result with additional data."""
|
||||
result = OperationResult(True, "Operation successful", {"key": "value"})
|
||||
assert result.success is True
|
||||
assert result.message == "Operation successful"
|
||||
assert result.data == {"key": "value"}
|
||||
|
||||
|
||||
class TestUndoRedoHistory:
|
||||
"""Test the UndoRedoHistory class."""
|
||||
|
||||
def test_initial_state(self):
|
||||
"""Test initial state of undo/redo history."""
|
||||
history = UndoRedoHistory()
|
||||
assert not history.can_undo()
|
||||
assert not history.can_redo()
|
||||
assert history.get_undo_description() is None
|
||||
assert history.get_redo_description() is None
|
||||
|
||||
def test_execute_command(self):
|
||||
"""Test executing a command adds it to history."""
|
||||
history = UndoRedoHistory()
|
||||
hosts_file = HostsFile()
|
||||
command = Mock(spec=Command)
|
||||
command.execute.return_value = OperationResult(True, "Test executed")
|
||||
command.get_description.return_value = "Test command"
|
||||
|
||||
result = history.execute_command(command, hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert result.message == "Test executed"
|
||||
assert history.can_undo()
|
||||
assert not history.can_redo()
|
||||
assert history.get_undo_description() == "Test command"
|
||||
command.execute.assert_called_once_with(hosts_file)
|
||||
|
||||
def test_execute_failed_command(self):
|
||||
"""Test executing a failed command does not add it to history."""
|
||||
history = UndoRedoHistory()
|
||||
hosts_file = HostsFile()
|
||||
command = Mock(spec=Command)
|
||||
command.execute.return_value = OperationResult(False, "Test failed")
|
||||
|
||||
result = history.execute_command(command, hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert result.message == "Test failed"
|
||||
assert not history.can_undo()
|
||||
assert not history.can_redo()
|
||||
|
||||
def test_undo_operation(self):
|
||||
"""Test undoing an operation."""
|
||||
history = UndoRedoHistory()
|
||||
hosts_file = HostsFile()
|
||||
command = Mock(spec=Command)
|
||||
command.execute.return_value = OperationResult(True, "Test executed")
|
||||
command.undo.return_value = OperationResult(True, "Test undone")
|
||||
command.get_description.return_value = "Test command"
|
||||
|
||||
# Execute then undo
|
||||
history.execute_command(command, hosts_file)
|
||||
result = history.undo(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert result.message == "Test undone"
|
||||
assert not history.can_undo()
|
||||
assert history.can_redo()
|
||||
assert history.get_redo_description() == "Test command"
|
||||
command.undo.assert_called_once_with(hosts_file)
|
||||
|
||||
def test_redo_operation(self):
|
||||
"""Test redoing an operation."""
|
||||
history = UndoRedoHistory()
|
||||
hosts_file = HostsFile()
|
||||
command = Mock(spec=Command)
|
||||
command.execute.return_value = OperationResult(True, "Test executed")
|
||||
command.undo.return_value = OperationResult(True, "Test undone")
|
||||
command.get_description.return_value = "Test command"
|
||||
|
||||
# Execute, undo, then redo
|
||||
history.execute_command(command, hosts_file)
|
||||
history.undo(hosts_file)
|
||||
result = history.redo(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert result.message == "Test executed"
|
||||
assert history.can_undo()
|
||||
assert not history.can_redo()
|
||||
assert history.get_undo_description() == "Test command"
|
||||
assert command.execute.call_count == 2
|
||||
|
||||
def test_undo_with_empty_history(self):
|
||||
"""Test undo with empty history."""
|
||||
history = UndoRedoHistory()
|
||||
hosts_file = HostsFile()
|
||||
result = history.undo(hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert "No operations to undo" in result.message
|
||||
|
||||
def test_redo_with_empty_history(self):
|
||||
"""Test redo with empty history."""
|
||||
history = UndoRedoHistory()
|
||||
hosts_file = HostsFile()
|
||||
result = history.redo(hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert "No operations to redo" in result.message
|
||||
|
||||
def test_max_history_limit(self):
|
||||
"""Test that history respects the maximum limit."""
|
||||
history = UndoRedoHistory(max_history=2)
|
||||
hosts_file = HostsFile()
|
||||
|
||||
# Add 3 commands
|
||||
for i in range(3):
|
||||
command = Mock(spec=Command)
|
||||
command.execute.return_value = OperationResult(True, f"Command {i}")
|
||||
command.get_description.return_value = f"Command {i}"
|
||||
history.execute_command(command, hosts_file)
|
||||
|
||||
# Should only keep the last 2 commands
|
||||
assert len(history.undo_stack) == 2
|
||||
|
||||
def test_clear_history(self):
|
||||
"""Test clearing the history."""
|
||||
history = UndoRedoHistory()
|
||||
hosts_file = HostsFile()
|
||||
command = Mock(spec=Command)
|
||||
command.execute.return_value = OperationResult(True, "Test executed")
|
||||
command.get_description.return_value = "Test command"
|
||||
|
||||
history.execute_command(command, hosts_file)
|
||||
assert history.can_undo()
|
||||
|
||||
history.clear_history()
|
||||
assert not history.can_undo()
|
||||
assert not history.can_redo()
|
||||
|
||||
def test_new_command_clears_redo_stack(self):
|
||||
"""Test that executing a new command clears the redo stack."""
|
||||
history = UndoRedoHistory()
|
||||
hosts_file = HostsFile()
|
||||
|
||||
# Execute and undo a command
|
||||
command1 = Mock(spec=Command)
|
||||
command1.execute.return_value = OperationResult(True, "Command 1")
|
||||
command1.undo.return_value = OperationResult(True, "Undo 1")
|
||||
command1.get_description.return_value = "Command 1"
|
||||
|
||||
history.execute_command(command1, hosts_file)
|
||||
history.undo(hosts_file)
|
||||
assert history.can_redo()
|
||||
|
||||
# Execute a new command
|
||||
command2 = Mock(spec=Command)
|
||||
command2.execute.return_value = OperationResult(True, "Command 2")
|
||||
command2.get_description.return_value = "Command 2"
|
||||
|
||||
history.execute_command(command2, hosts_file)
|
||||
assert not history.can_redo() # Redo stack should be cleared
|
||||
|
||||
|
||||
class TestToggleEntryCommand:
|
||||
"""Test the ToggleEntryCommand class."""
|
||||
|
||||
def test_toggle_active_to_inactive(self):
|
||||
"""Test toggling an active entry to inactive."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"], is_active=True)
|
||||
hosts_file.entries.append(entry)
|
||||
|
||||
command = ToggleEntryCommand(0)
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert not hosts_file.entries[0].is_active
|
||||
assert "deactivated" in result.message
|
||||
|
||||
def test_toggle_inactive_to_active(self):
|
||||
"""Test toggling an inactive entry to active."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"], is_active=False)
|
||||
hosts_file.entries.append(entry)
|
||||
|
||||
command = ToggleEntryCommand(0)
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert hosts_file.entries[0].is_active
|
||||
assert "activated" in result.message
|
||||
|
||||
def test_toggle_undo(self):
|
||||
"""Test undoing a toggle operation."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"], is_active=True)
|
||||
hosts_file.entries.append(entry)
|
||||
|
||||
command = ToggleEntryCommand(0)
|
||||
command.execute(hosts_file) # Toggle to inactive
|
||||
result = command.undo(hosts_file) # Toggle back to active
|
||||
|
||||
assert result.success is True
|
||||
assert hosts_file.entries[0].is_active
|
||||
assert "Undid toggle" in result.message
|
||||
|
||||
def test_toggle_invalid_index(self):
|
||||
"""Test toggle with invalid index."""
|
||||
hosts_file = HostsFile()
|
||||
command = ToggleEntryCommand(0)
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert "Invalid entry index" in result.message
|
||||
|
||||
def test_toggle_get_description(self):
|
||||
"""Test getting command description."""
|
||||
command = ToggleEntryCommand(0)
|
||||
description = command.get_description()
|
||||
assert "Toggle entry at index 0" in description
|
||||
|
||||
|
||||
class TestMoveEntryCommand:
|
||||
"""Test the MoveEntryCommand class."""
|
||||
|
||||
def test_move_entry_up(self):
|
||||
"""Test moving an entry up."""
|
||||
hosts_file = HostsFile()
|
||||
entry1 = HostEntry(ip_address="192.168.1.1", hostnames=["test1.local"])
|
||||
entry2 = HostEntry(ip_address="192.168.1.2", hostnames=["test2.local"])
|
||||
hosts_file.entries.extend([entry1, entry2])
|
||||
|
||||
command = MoveEntryCommand(1, 0) # Move from index 1 to index 0
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert hosts_file.entries[0] == entry2
|
||||
assert hosts_file.entries[1] == entry1
|
||||
assert "up" in result.message
|
||||
|
||||
def test_move_entry_down(self):
|
||||
"""Test moving an entry down."""
|
||||
hosts_file = HostsFile()
|
||||
entry1 = HostEntry(ip_address="192.168.1.1", hostnames=["test1.local"])
|
||||
entry2 = HostEntry(ip_address="192.168.1.2", hostnames=["test2.local"])
|
||||
hosts_file.entries.extend([entry1, entry2])
|
||||
|
||||
command = MoveEntryCommand(0, 1) # Move from index 0 to index 1
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert hosts_file.entries[0] == entry2
|
||||
assert hosts_file.entries[1] == entry1
|
||||
assert "down" in result.message
|
||||
|
||||
def test_move_undo(self):
|
||||
"""Test undoing a move operation."""
|
||||
hosts_file = HostsFile()
|
||||
entry1 = HostEntry(ip_address="192.168.1.1", hostnames=["test1.local"])
|
||||
entry2 = HostEntry(ip_address="192.168.1.2", hostnames=["test2.local"])
|
||||
hosts_file.entries.extend([entry1, entry2])
|
||||
|
||||
command = MoveEntryCommand(1, 0) # Move entry2 up
|
||||
command.execute(hosts_file)
|
||||
result = command.undo(hosts_file) # Move back down
|
||||
|
||||
assert result.success is True
|
||||
assert hosts_file.entries[0] == entry1
|
||||
assert hosts_file.entries[1] == entry2
|
||||
assert "Undid move" in result.message
|
||||
|
||||
def test_move_invalid_indices(self):
|
||||
"""Test move with invalid indices."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"])
|
||||
hosts_file.entries.append(entry)
|
||||
|
||||
command = MoveEntryCommand(0, 5) # Invalid target index
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert "Invalid move" in result.message
|
||||
|
||||
def test_move_same_position(self):
|
||||
"""Test moving entry to same position."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"])
|
||||
hosts_file.entries.append(entry)
|
||||
|
||||
command = MoveEntryCommand(0, 0) # Same position
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert "No movement needed" in result.message
|
||||
|
||||
def test_move_get_description(self):
|
||||
"""Test getting command description."""
|
||||
command = MoveEntryCommand(1, 0)
|
||||
description = command.get_description()
|
||||
assert "Move entry up" in description
|
||||
|
||||
|
||||
class TestAddEntryCommand:
|
||||
"""Test the AddEntryCommand class."""
|
||||
|
||||
def test_add_entry(self):
|
||||
"""Test adding an entry."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"])
|
||||
|
||||
command = AddEntryCommand(entry)
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert len(hosts_file.entries) == 1
|
||||
assert hosts_file.entries[0] == entry
|
||||
assert "Added entry" in result.message
|
||||
|
||||
def test_add_entry_at_specific_index(self):
|
||||
"""Test adding an entry at a specific index."""
|
||||
hosts_file = HostsFile()
|
||||
entry1 = HostEntry(ip_address="192.168.1.1", hostnames=["test1.local"])
|
||||
entry2 = HostEntry(ip_address="192.168.1.2", hostnames=["test2.local"])
|
||||
hosts_file.entries.append(entry1)
|
||||
|
||||
command = AddEntryCommand(entry2, index=0) # Insert at beginning
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert len(hosts_file.entries) == 2
|
||||
assert hosts_file.entries[0] == entry2
|
||||
assert hosts_file.entries[1] == entry1
|
||||
|
||||
def test_add_entry_undo(self):
|
||||
"""Test undoing an add operation."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"])
|
||||
|
||||
command = AddEntryCommand(entry)
|
||||
command.execute(hosts_file)
|
||||
result = command.undo(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert len(hosts_file.entries) == 0
|
||||
assert "Undid add" in result.message
|
||||
|
||||
def test_add_entry_invalid_index(self):
|
||||
"""Test adding entry with invalid index."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"])
|
||||
|
||||
command = AddEntryCommand(entry, index=5) # Invalid index
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert "Invalid insertion index" in result.message
|
||||
|
||||
def test_add_get_description(self):
|
||||
"""Test getting command description."""
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"])
|
||||
command = AddEntryCommand(entry)
|
||||
description = command.get_description()
|
||||
assert "Add entry: 192.168.1.1 test.local" in description
|
||||
|
||||
|
||||
class TestDeleteEntryCommand:
|
||||
"""Test the DeleteEntryCommand class."""
|
||||
|
||||
def test_delete_entry(self):
|
||||
"""Test deleting an entry."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"])
|
||||
hosts_file.entries.append(entry)
|
||||
|
||||
command = DeleteEntryCommand(0)
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert len(hosts_file.entries) == 0
|
||||
assert "Deleted entry" in result.message
|
||||
|
||||
def test_delete_entry_undo(self):
|
||||
"""Test undoing a delete operation."""
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"])
|
||||
hosts_file.entries.append(entry)
|
||||
|
||||
command = DeleteEntryCommand(0)
|
||||
command.execute(hosts_file)
|
||||
result = command.undo(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert len(hosts_file.entries) == 1
|
||||
assert hosts_file.entries[0].ip_address == "192.168.1.1"
|
||||
assert "Undid delete" in result.message
|
||||
|
||||
def test_delete_invalid_index(self):
|
||||
"""Test delete with invalid index."""
|
||||
hosts_file = HostsFile()
|
||||
command = DeleteEntryCommand(0)
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert "Invalid entry index" in result.message
|
||||
|
||||
def test_delete_get_description(self):
|
||||
"""Test getting command description."""
|
||||
command = DeleteEntryCommand(0)
|
||||
description = command.get_description()
|
||||
assert "Delete entry at index 0" in description
|
||||
|
||||
|
||||
class TestUpdateEntryCommand:
|
||||
"""Test the UpdateEntryCommand class."""
|
||||
|
||||
def test_update_entry(self):
|
||||
"""Test updating an entry."""
|
||||
hosts_file = HostsFile()
|
||||
old_entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"], comment="old comment", is_active=True)
|
||||
hosts_file.entries.append(old_entry)
|
||||
|
||||
command = UpdateEntryCommand(0, "192.168.1.2", ["updated.local"], "new comment", False)
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert hosts_file.entries[0].ip_address == "192.168.1.2"
|
||||
assert hosts_file.entries[0].hostnames == ["updated.local"]
|
||||
assert hosts_file.entries[0].comment == "new comment"
|
||||
assert hosts_file.entries[0].is_active is False
|
||||
assert "Updated entry" in result.message
|
||||
|
||||
def test_update_entry_undo(self):
|
||||
"""Test undoing an update operation."""
|
||||
hosts_file = HostsFile()
|
||||
old_entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"], comment="old comment", is_active=True)
|
||||
hosts_file.entries.append(old_entry)
|
||||
|
||||
command = UpdateEntryCommand(0, "192.168.1.2", ["updated.local"], "new comment", False)
|
||||
command.execute(hosts_file)
|
||||
result = command.undo(hosts_file)
|
||||
|
||||
assert result.success is True
|
||||
assert hosts_file.entries[0].ip_address == "192.168.1.1"
|
||||
assert hosts_file.entries[0].hostnames == ["test.local"]
|
||||
assert hosts_file.entries[0].comment == "old comment"
|
||||
assert hosts_file.entries[0].is_active is True
|
||||
assert "Undid update" in result.message
|
||||
|
||||
def test_update_invalid_index(self):
|
||||
"""Test update with invalid index."""
|
||||
hosts_file = HostsFile()
|
||||
|
||||
command = UpdateEntryCommand(0, "192.168.1.2", ["updated.local"], None, True)
|
||||
result = command.execute(hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert "Invalid entry index" in result.message
|
||||
|
||||
def test_update_get_description(self):
|
||||
"""Test getting command description."""
|
||||
command = UpdateEntryCommand(0, "192.168.1.2", ["updated.local"], None, True)
|
||||
description = command.get_description()
|
||||
assert "Update entry at index 0" in description
|
||||
|
||||
|
||||
class TestHostsManagerIntegration:
|
||||
"""Test integration of commands with HostsManager."""
|
||||
|
||||
def test_manager_undo_redo_properties(self):
|
||||
"""Test undo/redo availability properties."""
|
||||
manager = HostsManager()
|
||||
|
||||
# Initially no undo/redo available
|
||||
assert not manager.can_undo()
|
||||
assert not manager.can_redo()
|
||||
assert manager.get_undo_description() is None
|
||||
assert manager.get_redo_description() is None
|
||||
|
||||
def test_manager_undo_without_edit_mode(self):
|
||||
"""Test undo when not in edit mode."""
|
||||
manager = HostsManager()
|
||||
hosts_file = HostsFile()
|
||||
result = manager.undo_last_operation(hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert "Not in edit mode" in result.message
|
||||
|
||||
def test_manager_redo_without_edit_mode(self):
|
||||
"""Test redo when not in edit mode."""
|
||||
manager = HostsManager()
|
||||
hosts_file = HostsFile()
|
||||
result = manager.redo_last_operation(hosts_file)
|
||||
|
||||
assert result.success is False
|
||||
assert "Not in edit mode" in result.message
|
||||
|
||||
@patch('src.hosts.core.manager.HostsManager.enter_edit_mode')
|
||||
def test_manager_execute_toggle_command(self, mock_enter_edit):
|
||||
"""Test executing a toggle command through the manager."""
|
||||
mock_enter_edit.return_value = (True, "Edit mode enabled")
|
||||
|
||||
manager = HostsManager()
|
||||
manager.edit_mode = True # Simulate edit mode
|
||||
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"], is_active=True)
|
||||
hosts_file.entries.append(entry)
|
||||
|
||||
result = manager.execute_toggle_command(hosts_file, 0)
|
||||
|
||||
assert result.success is True
|
||||
assert not hosts_file.entries[0].is_active
|
||||
|
||||
@patch('src.hosts.core.manager.HostsManager.enter_edit_mode')
|
||||
def test_manager_execute_move_command(self, mock_enter_edit):
|
||||
"""Test executing a move command through the manager."""
|
||||
mock_enter_edit.return_value = (True, "Edit mode enabled")
|
||||
|
||||
manager = HostsManager()
|
||||
manager.edit_mode = True # Simulate edit mode
|
||||
|
||||
hosts_file = HostsFile()
|
||||
entry1 = HostEntry(ip_address="192.168.1.1", hostnames=["test1.local"])
|
||||
entry2 = HostEntry(ip_address="192.168.1.2", hostnames=["test2.local"])
|
||||
hosts_file.entries.extend([entry1, entry2])
|
||||
|
||||
result = manager.execute_move_command(hosts_file, 1, "up")
|
||||
|
||||
assert result.success is True
|
||||
assert hosts_file.entries[0] == entry2
|
||||
|
||||
@patch('src.hosts.core.manager.HostsManager.enter_edit_mode')
|
||||
def test_manager_command_not_in_edit_mode(self, mock_enter_edit):
|
||||
"""Test executing commands when not in edit mode."""
|
||||
manager = HostsManager()
|
||||
hosts_file = HostsFile()
|
||||
entry = HostEntry(ip_address="192.168.1.1", hostnames=["test.local"])
|
||||
|
||||
result = manager.execute_add_command(hosts_file, entry)
|
||||
|
||||
assert result.success is False
|
||||
assert "Not in edit mode" in result.message
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__])
|
Loading…
Add table
Add a link
Reference in a new issue