Public Access
91 lines
2.6 KiB
Python
91 lines
2.6 KiB
Python
"""Direct CLI coverage for the bundled starter recipe loader."""
|
|
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.services.starter_recipe_catalog import StarterRecipeCatalogError
|
|
|
|
|
|
SCRIPT_PATH = Path(__file__).resolve().parent.parent / "scripts" / "load_starter_recipes.py"
|
|
|
|
|
|
class FakeSession:
|
|
def __init__(self):
|
|
self.rollback_count = 0
|
|
self.close_count = 0
|
|
|
|
def rollback(self):
|
|
self.rollback_count += 1
|
|
|
|
def close(self):
|
|
self.close_count += 1
|
|
|
|
|
|
@pytest.fixture()
|
|
def loader_cli():
|
|
spec = importlib.util.spec_from_file_location("load_starter_recipes", SCRIPT_PATH)
|
|
assert spec and spec.loader
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
def test_cli_forwards_update_existing_and_writes_json(loader_cli, monkeypatch, capsys):
|
|
db = FakeSession()
|
|
calls = []
|
|
summary = {"catalog_version": 2, "updated_recipes": 50}
|
|
monkeypatch.setattr(loader_cli, "SessionLocal", lambda: db)
|
|
monkeypatch.setattr(
|
|
loader_cli,
|
|
"load_bundled_starter_catalog",
|
|
lambda session, **kwargs: calls.append((session, kwargs)) or summary,
|
|
)
|
|
|
|
assert loader_cli.main(["--update-existing"]) == 0
|
|
|
|
assert calls == [(db, {"dry_run": False, "update_existing": True})]
|
|
assert json.loads(capsys.readouterr().out) == summary
|
|
assert db.rollback_count == 0
|
|
assert db.close_count == 1
|
|
|
|
|
|
def test_cli_reports_catalog_errors_as_json_and_closes_rolled_back_session(
|
|
loader_cli, monkeypatch, capsys
|
|
):
|
|
db = FakeSession()
|
|
monkeypatch.setattr(loader_cli, "SessionLocal", lambda: db)
|
|
|
|
def fail_catalog_load(session, **kwargs):
|
|
raise StarterRecipeCatalogError("catalog validation failed")
|
|
|
|
monkeypatch.setattr(loader_cli, "load_bundled_starter_catalog", fail_catalog_load)
|
|
|
|
assert loader_cli.main(["--dry-run"]) == 1
|
|
|
|
assert json.loads(capsys.readouterr().out) == {
|
|
"dry_run": True,
|
|
"error": "catalog validation failed",
|
|
}
|
|
assert db.rollback_count == 1
|
|
assert db.close_count == 1
|
|
|
|
|
|
def test_cli_rolls_back_and_closes_session_for_database_failures(loader_cli, monkeypatch):
|
|
db = FakeSession()
|
|
monkeypatch.setattr(loader_cli, "SessionLocal", lambda: db)
|
|
|
|
def fail_catalog_load(session, **kwargs):
|
|
raise RuntimeError("database write failed")
|
|
|
|
monkeypatch.setattr(loader_cli, "load_bundled_starter_catalog", fail_catalog_load)
|
|
|
|
with pytest.raises(RuntimeError, match="database write failed"):
|
|
loader_cli.main([])
|
|
|
|
assert db.rollback_count == 1
|
|
assert db.close_count == 1
|