"""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