Harden demo export cleanup safety
This commit is contained in:
@@ -22,6 +22,7 @@ class ExportRow:
|
||||
id: str
|
||||
created_at: datetime | None
|
||||
storage_path: str
|
||||
export_type: str = "project_metadata_json"
|
||||
|
||||
|
||||
def test_cleanup_candidate_selection_keeps_newest_exports() -> None:
|
||||
@@ -51,6 +52,20 @@ def test_cleanup_candidate_selection_rejects_negative_keep_latest() -> None:
|
||||
raise AssertionError("negative keep_latest should fail")
|
||||
|
||||
|
||||
def test_cleanup_can_filter_candidates_by_export_type() -> None:
|
||||
cleanup = load_cleanup_module()
|
||||
base = datetime(2026, 1, 1, 12, 0, 0)
|
||||
exports = [
|
||||
ExportRow("metadata", base + timedelta(days=2), "/tmp/metadata.json", "project_metadata_json"),
|
||||
ExportRow("report", base + timedelta(days=1), "/tmp/report.html", "project_report_html"),
|
||||
ExportRow("dataset", base, "/tmp/dataset.geojson", "dataset_geojson"),
|
||||
]
|
||||
|
||||
filtered = cleanup.filter_exports_by_type(exports, ["project_report_html"])
|
||||
|
||||
assert [export.id for export in filtered] == ["report"]
|
||||
|
||||
|
||||
def test_cleanup_path_safety_requires_storage_root_containment(tmp_path: Path) -> None:
|
||||
cleanup = load_cleanup_module()
|
||||
storage_root = tmp_path / "storage"
|
||||
@@ -72,12 +87,40 @@ def test_cleanup_script_defaults_to_explicit_demo_project() -> None:
|
||||
|
||||
assert args.project_name == cleanup.DEMO_PROJECT_NAME
|
||||
assert args.keep_latest == 3
|
||||
assert args.max_delete == 25
|
||||
assert args.export_type is None
|
||||
assert args.apply is False
|
||||
|
||||
|
||||
def test_cleanup_script_accepts_max_delete_and_repeated_export_type() -> None:
|
||||
cleanup = load_cleanup_module()
|
||||
parser = cleanup.build_parser()
|
||||
|
||||
args = parser.parse_args(
|
||||
[
|
||||
"--keep-latest",
|
||||
"10",
|
||||
"--max-delete",
|
||||
"100",
|
||||
"--export-type",
|
||||
"project_report_html",
|
||||
"--export-type",
|
||||
"project_metadata_json",
|
||||
"--apply",
|
||||
]
|
||||
)
|
||||
|
||||
assert args.keep_latest == 10
|
||||
assert args.max_delete == 100
|
||||
assert args.export_type == ["project_report_html", "project_metadata_json"]
|
||||
assert args.apply is True
|
||||
|
||||
|
||||
def test_cleanup_script_reports_dry_run_candidates_separately() -> None:
|
||||
script = Path(__file__).resolve().parents[2] / "backend" / "scripts" / "cleanup_demo_artifacts.py"
|
||||
content = script.read_text(encoding="utf-8")
|
||||
|
||||
assert '"candidate_files": []' in content
|
||||
assert 'summary["candidate_files"].append(str(path))' in content
|
||||
assert '"max_delete": max_delete' in content
|
||||
assert "blocked_reason" in content
|
||||
|
||||
Reference in New Issue
Block a user