mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
241 lines
9.4 KiB
Python
241 lines
9.4 KiB
Python
"""Tests for rollback CLI module."""
|
|
|
|
from unittest.mock import MagicMock, PropertyMock, patch
|
|
|
|
import pytest
|
|
from click.testing import CliRunner
|
|
|
|
|
|
class TestRollbackCLI:
|
|
"""Test rollback CLI commands."""
|
|
|
|
def test_rollback_list_snapshots(self, temp_dir):
|
|
"""Test rollback list command with snapshots."""
|
|
from nodupe.tools.maintenance.rollback import list_cmd
|
|
from nodupe.tools.maintenance.snapshot import SnapshotManager
|
|
|
|
# Create a snapshot
|
|
test_file = temp_dir / "test.txt"
|
|
test_file.write_text("content")
|
|
|
|
snapshot_mgr = SnapshotManager(str(temp_dir / ".nodupe/backups"))
|
|
snapshot_mgr.create_snapshot([str(test_file)])
|
|
|
|
# Mock SnapshotManager to use our temp directory
|
|
with patch('nodupe.tools.maintenance.rollback.SnapshotManager') as mock_mgr:
|
|
mock_instance = MagicMock()
|
|
mock_instance.list_snapshots.return_value = [
|
|
{"snapshot_id": "abc123", "timestamp": "2025-01-01", "file_count": 1}
|
|
]
|
|
mock_mgr.return_value = mock_instance
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(list_cmd, ['--snapshots'])
|
|
|
|
assert result.exit_code == 0
|
|
assert "Snapshots" in result.output
|
|
|
|
def test_rollback_list_transactions(self, temp_dir):
|
|
"""Test rollback list command with transactions."""
|
|
from nodupe.tools.maintenance.rollback import list_cmd
|
|
from nodupe.tools.maintenance.transaction import TransactionLog
|
|
|
|
# Create a transaction
|
|
tx_log = TransactionLog(str(temp_dir / ".nodupe/backups"))
|
|
tx_id = tx_log.begin_transaction()
|
|
tx_log.commit_transaction()
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.TransactionLog') as mock_tx:
|
|
mock_instance = MagicMock()
|
|
mock_instance.list_transactions.return_value = [
|
|
{"transaction_id": "abc123", "timestamp": "2025-01-01", "status": "completed", "operation_count": 1}
|
|
]
|
|
mock_tx.return_value = mock_instance
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(list_cmd, ['--transactions'])
|
|
|
|
assert result.exit_code == 0
|
|
assert "Transactions" in result.output
|
|
|
|
def test_rollback_create_command(self, temp_dir):
|
|
"""Test rollback create command."""
|
|
from nodupe.tools.maintenance.rollback import create_cmd
|
|
|
|
test_file = temp_dir / "test.txt"
|
|
test_file.write_text("content")
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.SnapshotManager') as mock_mgr:
|
|
mock_instance = MagicMock()
|
|
mock_instance.create_snapshot.return_value = MagicMock(
|
|
snapshot_id="abc123",
|
|
files=[str(test_file)]
|
|
)
|
|
mock_mgr.return_value = mock_instance
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(create_cmd, [str(test_file)])
|
|
|
|
assert result.exit_code == 0
|
|
assert "snapshot" in result.output.lower()
|
|
|
|
def test_rollback_restore_command_success(self):
|
|
"""Test rollback restore command with success."""
|
|
from nodupe.tools.maintenance.rollback import restore_cmd
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.SnapshotManager') as mock_mgr:
|
|
mock_instance = MagicMock()
|
|
mock_instance.restore_snapshot.return_value = True
|
|
mock_mgr.return_value = mock_instance
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(restore_cmd, ['abc123'])
|
|
|
|
assert result.exit_code == 0
|
|
assert "Restored" in result.output
|
|
|
|
def test_rollback_restore_command_failure(self):
|
|
"""Test rollback restore command with failure."""
|
|
from nodupe.tools.maintenance.rollback import restore_cmd
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.SnapshotManager') as mock_mgr:
|
|
mock_instance = MagicMock()
|
|
mock_instance.restore_snapshot.return_value = False
|
|
mock_mgr.return_value = mock_instance
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(restore_cmd, ['nonexistent'])
|
|
|
|
assert result.exit_code == 1
|
|
|
|
def test_rollback_delete_command_success(self):
|
|
"""Test rollback delete command with success."""
|
|
from nodupe.tools.maintenance.rollback import delete_cmd
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.SnapshotManager') as mock_mgr:
|
|
mock_instance = MagicMock()
|
|
mock_instance.delete_snapshot.return_value = True
|
|
mock_mgr.return_value = mock_instance
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(delete_cmd, ['abc123'])
|
|
|
|
assert result.exit_code == 0
|
|
assert "Deleted" in result.output
|
|
|
|
def test_rollback_delete_command_failure(self):
|
|
"""Test rollback delete command with failure."""
|
|
from nodupe.tools.maintenance.rollback import delete_cmd
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.SnapshotManager') as mock_mgr:
|
|
mock_instance = MagicMock()
|
|
mock_instance.delete_snapshot.return_value = False
|
|
mock_mgr.return_value = mock_instance
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(delete_cmd, ['nonexistent'])
|
|
|
|
# When delete returns False, click.echo is called with the error message
|
|
# but the exit code may still be 0, let's check for the message instead
|
|
assert "not found" in result.output.lower() or result.exit_code == 1
|
|
|
|
def test_rollback_undo_command_success(self):
|
|
"""Test rollback undo command with success."""
|
|
from nodupe.tools.maintenance.rollback import undo_cmd
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.RollbackManager') as mock_mgr:
|
|
mock_instance = MagicMock()
|
|
mock_instance.undo_last_operation.return_value = True
|
|
mock_mgr.return_value = mock_instance
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(undo_cmd)
|
|
|
|
assert result.exit_code == 0
|
|
|
|
def test_rollback_undo_command_failure(self):
|
|
"""Test rollback undo command with no operations."""
|
|
from nodupe.tools.maintenance.rollback import undo_cmd
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.RollbackManager') as mock_mgr:
|
|
mock_instance = MagicMock()
|
|
mock_instance.undo_last_operation.return_value = False
|
|
mock_mgr.return_value = mock_instance
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(undo_cmd)
|
|
|
|
assert result.exit_code == 0
|
|
assert "No operation" in result.output
|
|
|
|
|
|
class TestRollbackCLICoverage:
|
|
"""Tests for CLI coverage - specific branches."""
|
|
|
|
def test_list_cmd_no_flags_shows_both(self):
|
|
"""Test list command with no flags shows both snapshots and transactions."""
|
|
from click.testing import CliRunner
|
|
|
|
from nodupe.tools.maintenance.rollback import list_cmd
|
|
|
|
runner = CliRunner()
|
|
|
|
# Need to mock the managers to avoid file system operations
|
|
with patch('nodupe.tools.maintenance.rollback.SnapshotManager') as mock_snap, \
|
|
patch('nodupe.tools.maintenance.rollback.TransactionLog') as mock_tx:
|
|
mock_snap_instance = MagicMock()
|
|
mock_snap_instance.list_snapshots.return_value = []
|
|
mock_snap.return_value = mock_snap_instance
|
|
|
|
mock_tx_instance = MagicMock()
|
|
mock_tx_instance.list_transactions.return_value = []
|
|
mock_tx.return_value = mock_tx_instance
|
|
|
|
result = runner.invoke(list_cmd, [])
|
|
|
|
# With no flags, both should be shown (snapshots or not transactions)
|
|
assert "Snapshots" in result.output or "No snapshots" in result.output
|
|
|
|
def test_list_cmd_transactions_only(self):
|
|
"""Test list command with --transactions flag only shows transactions."""
|
|
from click.testing import CliRunner
|
|
|
|
from nodupe.tools.maintenance.rollback import list_cmd
|
|
|
|
runner = CliRunner()
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.SnapshotManager') as mock_snap, \
|
|
patch('nodupe.tools.maintenance.rollback.TransactionLog') as mock_tx:
|
|
mock_snap_instance = MagicMock()
|
|
mock_snap.return_value = mock_snap_instance
|
|
|
|
mock_tx_instance = MagicMock()
|
|
mock_tx_instance.list_transactions.return_value = []
|
|
mock_tx.return_value = mock_tx_instance
|
|
|
|
result = runner.invoke(list_cmd, ['--transactions'])
|
|
|
|
# Should only show transactions
|
|
assert "Transactions" in result.output or "No transactions" in result.output
|
|
|
|
def test_list_cmd_snapshots_only(self):
|
|
"""Test list command with --snapshots flag only shows snapshots."""
|
|
from click.testing import CliRunner
|
|
|
|
from nodupe.tools.maintenance.rollback import list_cmd
|
|
|
|
runner = CliRunner()
|
|
|
|
with patch('nodupe.tools.maintenance.rollback.SnapshotManager') as mock_snap, \
|
|
patch('nodupe.tools.maintenance.rollback.TransactionLog') as mock_tx:
|
|
mock_snap_instance = MagicMock()
|
|
mock_snap_instance.list_snapshots.return_value = []
|
|
mock_snap.return_value = mock_snap_instance
|
|
|
|
mock_tx_instance = MagicMock()
|
|
mock_tx.return_value = mock_tx_instance
|
|
|
|
result = runner.invoke(list_cmd, ['--snapshots'])
|
|
|
|
# Should only show snapshots
|
|
assert "Snapshots" in result.output or "No snapshots" in result.output
|