"""Tests para browser_profile_show. Se mockea el helper `query` (ligado en el modulo por el `from browser._osint_db_client import query`) para validar las dos queries (perfil + cuentas), el caso perfil-no-existe y la propagacion de error. NO toca el service real. """ import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) import browser.browser_profile_show as bps from browser.browser_profile_show import browser_profile_show class _QueryRouter: """Devuelve una respuesta distinta segun si el SQL es de perfil o de cuentas.""" def __init__(self, profile_ret, accounts_ret): self.calls = [] # lista de (sql, params) self.profile_ret = profile_ret self.accounts_ret = accounts_ret def __call__(self, base_url, sql, params=None, max_rows=None): self.calls.append((sql, params)) if "browser_profile_accounts" in sql: return self.accounts_ret return self.profile_ret def test_golden_muestra_perfil_y_cuentas(monkeypatch): profile_ret = { "status": "ok", "columns": ["profile_dir", "user_data_dir", "label", "persona", "purpose", "status", "note_path", "tags", "notes", "created_at", "updated_at"], "rows": [["Profile 1", "", "Maria", "maria_fake", "rastreo", "active", "notes/p1.md", '["osint"]', "n", "t0", "t1"]], "row_count": 1, } accounts_ret = { "status": "ok", "columns": ["id", "profile_dir", "service", "identity", "secret_ref", "role", "status", "notes", "created_at", "updated_at"], "rows": [ ["Profile 1:gmail:maria@example.com", "Profile 1", "gmail", "maria@example.com", "pass show osint/p1/gmail", "primary", "active", "", "t0", "t1"], ], "row_count": 1, } router = _QueryRouter(profile_ret, accounts_ret) monkeypatch.setattr(bps, "query", router) res = browser_profile_show("Profile 1") assert res["status"] == "ok" assert res["profile"]["profile_dir"] == "Profile 1" assert res["profile"]["persona"] == "maria_fake" assert len(res["accounts"]) == 1 assert res["accounts"][0]["service"] == "gmail" assert res["accounts"][0]["secret_ref"] == "pass show osint/p1/gmail" # Se hicieron dos queries, ambas con el profile_dir como param. assert len(router.calls) == 2 assert router.calls[0][1] == ["Profile 1"] assert router.calls[1][1] == ["Profile 1"] def test_edge_perfil_no_existe_devuelve_error(monkeypatch): # El perfil no aparece (0 filas); no se debe llegar a consultar cuentas. router = _QueryRouter( profile_ret={"status": "ok", "columns": ["profile_dir"], "rows": [], "row_count": 0}, accounts_ret={"status": "ok", "columns": [], "rows": [], "row_count": 0}, ) monkeypatch.setattr(bps, "query", router) res = browser_profile_show("inexistente") assert res["status"] == "error" assert "no encontrado" in res["error"] # Solo se ejecuto la query del perfil (1 llamada), no la de cuentas. assert len(router.calls) == 1 def test_error_query_falla_devuelve_status_error(monkeypatch): router = _QueryRouter( profile_ret={"status": "error", "error": "service osint_db inaccesible en ..."}, accounts_ret={"status": "ok", "columns": [], "rows": []}, ) monkeypatch.setattr(bps, "query", router) res = browser_profile_show("Profile 1") assert res["status"] == "error" assert "inaccesible" in res["error"]