"""Tests para resolve_pg_dsn. No tocan pass ni el disco salvo via monkeypatch sobre os.environ y un .env temporal. El fallback a pass se valida indirectamente (proyecto desconocido, prioridad del env var) sin invocar el subproceso real. """ import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..")) sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "functions")) from infra.resolve_pg_dsn import resolve_pg_dsn def test_env_var_seteada_gana_y_source_es_env(monkeypatch): """La env var del proyecto gana sobre .env y pass; source == 'env'.""" expected = "postgresql://captacion:secret@localhost:5433/trends" monkeypatch.setenv("CAPTACION_DSN", expected) res = resolve_pg_dsn("captacion") assert res["status"] == "ok" assert res["dsn"] == expected assert res["source"] == "env" assert res["project"] == "captacion" def test_proyecto_desconocido_devuelve_error_sin_lanzar(): """Un proyecto no registrado devuelve {status:'error'} sin excepcion.""" res = resolve_pg_dsn("no_existe_este_proyecto") assert res["status"] == "error" assert "unknown project" in res["error"] def test_alias_largo_resuelve_a_la_clave_canonica(monkeypatch): """El alias largo 'seo_analytics' resuelve a la clave canonica 'seo'.""" monkeypatch.setenv("SEO_DSN", "postgresql://captacion:x@localhost:5433/seo") res = resolve_pg_dsn("seo_analytics") assert res["status"] == "ok" assert res["project"] == "seo" assert res["source"] == "env" def test_fallback_a_dotenv_cuando_no_hay_env_var(monkeypatch, tmp_path): """Sin env var, lee la linea = del .env del proyecto; source == 'dotenv'.""" monkeypatch.delenv("CAPTACION_DSN", raising=False) # Monta una raiz falsa con el .env del proyecto en la ruta esperada. proj_dir = tmp_path / "projects" / "captacion_clientes" proj_dir.mkdir(parents=True) dsn = "postgresql://captacion:fromdotenv@localhost:5433/trends" (proj_dir / ".env").write_text(f'CAPTACION_DSN="{dsn}"\n', encoding="utf-8") monkeypatch.setenv("FN_REGISTRY_ROOT", str(tmp_path)) res = resolve_pg_dsn("captacion_clientes") assert res["status"] == "ok" assert res["dsn"] == dsn # comillas envolventes quitadas assert res["source"] == "dotenv"