From c9542d36a97da6af27e33dba83042cc9325ed8f0 Mon Sep 17 00:00:00 2001 From: tech Date: Wed, 22 Apr 2026 12:26:38 +0800 Subject: [PATCH] test: add CLI tests for delete command Co-Authored-By: Claude Sonnet 4.6 --- tests/test_delete.py | 80 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/tests/test_delete.py b/tests/test_delete.py index f5098ba..c0455b2 100644 --- a/tests/test_delete.py +++ b/tests/test_delete.py @@ -1,6 +1,10 @@ from datetime import datetime, timezone -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch +import pytest +from click.testing import CliRunner + +from order_bak.cli import main from order_bak.csv_utils import write_csv from order_bak.delete import delete_orders @@ -23,6 +27,8 @@ def _make_entity(pk, rk): } +# --- delete_orders unit tests --- + def test_delete_groups_by_partition_and_batches(tmp_path): entities = [] for i in range(3): @@ -65,3 +71,75 @@ def test_delete_respects_batch_size(tmp_path): assert deleted_count == 5 assert mock_table.submit_transaction.call_count == 3 # 2+2+1 + + +# --- delete CLI command tests --- + +@pytest.fixture +def runner(): + return CliRunner() + + +@pytest.fixture +def config_file(tmp_path): + cfg = tmp_path / "config.toml" + cfg.write_text('[azure]\nconnection_string = "UseDevelopmentStorage=true"\n') + return cfg + + +def test_delete_command_no_backups(runner, config_file, tmp_path, monkeypatch): + monkeypatch.chdir(tmp_path) + (tmp_path / "backups").mkdir() + + result = runner.invoke(main, ["--config", str(config_file), "delete"]) + + assert result.exit_code == 1 + assert "No backup files found" in result.output + + +def test_delete_command_aborts(runner, config_file, tmp_path, monkeypatch): + monkeypatch.chdir(tmp_path) + backup_dir = tmp_path / "backups" + backup_dir.mkdir() + write_csv(backup_dir / "2025-01-01.csv", [_make_entity("u1", "o1")]) + + mock_table = MagicMock() + with patch("azure.data.tables.TableClient.from_connection_string", return_value=mock_table): + result = runner.invoke(main, ["--config", str(config_file), "delete"], input="n\n") + + assert "Aborted" in result.output + mock_table.submit_transaction.assert_not_called() + + +def test_delete_command_single_file(runner, config_file, tmp_path, monkeypatch): + monkeypatch.chdir(tmp_path) + backup_dir = tmp_path / "backups" + backup_dir.mkdir() + write_csv(backup_dir / "2025-01-01.csv", [_make_entity("u1", f"o{i}") for i in range(3)]) + + mock_table = MagicMock() + with patch("azure.data.tables.TableClient.from_connection_string", return_value=mock_table): + result = runner.invoke(main, ["--config", str(config_file), "delete"], input="y\n") + + assert result.exit_code == 0 + assert "3 orders" in result.output + assert "1 file" in result.output + assert mock_table.submit_transaction.called + + +def test_delete_command_multiple_files(runner, config_file, tmp_path, monkeypatch): + monkeypatch.chdir(tmp_path) + backup_dir = tmp_path / "backups" + backup_dir.mkdir() + write_csv(backup_dir / "2025-01-01.csv", [_make_entity("u1", f"o{i}") for i in range(2)]) + write_csv(backup_dir / "2025-01-02.csv", [_make_entity("u2", f"o{i}") for i in range(3)]) + + mock_table = MagicMock() + with patch("azure.data.tables.TableClient.from_connection_string", return_value=mock_table): + result = runner.invoke(main, ["--config", str(config_file), "delete"], input="y\n") + + assert result.exit_code == 0 + assert "5 orders" in result.output + assert "2 file" in result.output + # u1 (2 entities, batch 100) → 1 call; u2 (3 entities, batch 100) → 1 call + assert mock_table.submit_transaction.call_count == 2