Fix #13: Expose Pre-edit Backup restoration
Preserve full diff opcodes before grouping, route modal navigation to a two-axis viewport-sized scroller, and calculate side-by-side layout using terminal cell widths so tabbed Hosts File lines keep a stable divider.
This commit is contained in:
parent
6a3e1e0d5a
commit
e268794564
13 changed files with 1103 additions and 19 deletions
|
|
@ -13,6 +13,7 @@ from unittest.mock import Mock, patch
|
|||
from src.hosts.core.manager import PermissionManager, HostsManager
|
||||
from src.hosts.core.models import HostEntry, HostsFile
|
||||
from src.hosts.core.commands import ToggleEntryCommand
|
||||
from src.hosts.core.restore_preview import fingerprint_file
|
||||
|
||||
|
||||
class TestPermissionManager:
|
||||
|
|
@ -592,15 +593,69 @@ class TestHostsManager:
|
|||
manager._backup_path = Path(backup_file.name)
|
||||
|
||||
try:
|
||||
manager.undo_redo_history.clear_history = Mock()
|
||||
success, message = manager.restore_backup()
|
||||
|
||||
assert success
|
||||
assert "restored successfully" in message
|
||||
mock_run.assert_called_once()
|
||||
assert mock_run.call_count == 2
|
||||
assert mock_run.call_args_list[0].args[0][:2] == ["sudo", "cp"]
|
||||
assert mock_run.call_args_list[0].args[0][-1] != temp_file.name
|
||||
assert mock_run.call_args_list[1].args[0][:2] == ["sudo", "mv"]
|
||||
assert mock_run.call_args_list[1].args[0][-1] == temp_file.name
|
||||
manager.undo_redo_history.clear_history.assert_called_once_with()
|
||||
finally:
|
||||
# Clean up
|
||||
manager._backup_path.unlink()
|
||||
|
||||
@patch("subprocess.run")
|
||||
def test_restore_backup_copy_failure_leaves_hosts_file_target_untouched(
|
||||
self, mock_run
|
||||
):
|
||||
"""A failed staged copy never opens the Hosts File target for writing."""
|
||||
mock_run.return_value = Mock(returncode=1, stderr="Disk full")
|
||||
|
||||
with tempfile.NamedTemporaryFile() as temp_file:
|
||||
manager = HostsManager(temp_file.name)
|
||||
manager.edit_mode = True
|
||||
with tempfile.NamedTemporaryFile(delete=False) as backup_file:
|
||||
manager._backup_path = Path(backup_file.name)
|
||||
|
||||
try:
|
||||
success, message = manager.restore_backup()
|
||||
|
||||
assert not success
|
||||
assert "Disk full" in message
|
||||
mock_run.assert_called_once()
|
||||
assert mock_run.call_args.args[0][-1] != temp_file.name
|
||||
finally:
|
||||
manager._backup_path.unlink()
|
||||
|
||||
@patch("subprocess.run")
|
||||
def test_restore_backup_refuses_files_that_changed_since_preview(self, mock_run):
|
||||
"""The privileged write uses the exact source and target the user reviewed."""
|
||||
with tempfile.NamedTemporaryFile() as temp_file:
|
||||
manager = HostsManager(temp_file.name)
|
||||
manager.edit_mode = True
|
||||
with tempfile.NamedTemporaryFile(delete=False) as backup_file:
|
||||
backup_file.write(b"127.0.0.1 restored.test\n")
|
||||
manager._backup_path = Path(backup_file.name)
|
||||
|
||||
try:
|
||||
backup_digest = fingerprint_file(
|
||||
manager._backup_path, "Pre-edit Backup"
|
||||
)
|
||||
hosts_digest = fingerprint_file(manager.parser.file_path, "Hosts File")
|
||||
Path(temp_file.name).write_text("192.0.2.2 changed.test\n")
|
||||
|
||||
success, message = manager.restore_backup(backup_digest, hosts_digest)
|
||||
|
||||
assert not success
|
||||
assert "changed since review" in message
|
||||
mock_run.assert_not_called()
|
||||
finally:
|
||||
manager._backup_path.unlink()
|
||||
|
||||
def test_restore_backup_not_in_edit_mode(self):
|
||||
"""Test restoring backup when not in edit mode."""
|
||||
with tempfile.NamedTemporaryFile() as temp_file:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue