"""Tests para pass_get_secret. Deterministas: monkeypatchean subprocess.run para no ejecutar `pass` real. Verifican seleccion de linea (1-indexed), errores de pass (returncode != 0), pass no instalado (FileNotFoundError) y linea fuera de rango. """ import subprocess import sys import infra.pass_get_secret # noqa: F401 # El __init__ rebinds el nombre a la funcion; recuperamos el submodulo real. mod = sys.modules["infra.pass_get_secret"] class _FakeCompleted: def __init__(self, returncode=0, stdout="", stderr=""): self.returncode = returncode self.stdout = stdout self.stderr = stderr def test_line_1_devuelve_la_password(monkeypatch): def fake_run(args, **kwargs): assert args == ["pass", "show", "apis/lpd"] assert kwargs.get("shell") is None # nunca shell=True return _FakeCompleted(0, stdout="s3cr3t-pass\nuser: neo\nurl: https://x\n") monkeypatch.setattr(mod.subprocess, "run", fake_run) result = mod.pass_get_secret("apis/lpd") assert result == {"status": "ok", "value": "s3cr3t-pass"} def test_line_2_devuelve_metadata(monkeypatch): def fake_run(args, **kwargs): return _FakeCompleted(0, stdout="s3cr3t-pass\nuser: neo\nurl: https://x\n") monkeypatch.setattr(mod.subprocess, "run", fake_run) result = mod.pass_get_secret("apis/lpd", line=2) assert result == {"status": "ok", "value": "user: neo"} def test_returncode_distinto_de_cero_es_error(monkeypatch): def fake_run(args, **kwargs): return _FakeCompleted(1, stdout="", stderr="Error: apis/nope is not in the password store.\n") monkeypatch.setattr(mod.subprocess, "run", fake_run) result = mod.pass_get_secret("apis/nope") assert result["status"] == "error" assert result["error"] == "Error: apis/nope is not in the password store." def test_pass_no_instalado_es_error(monkeypatch): def fake_run(args, **kwargs): raise FileNotFoundError("no such file: pass") monkeypatch.setattr(mod.subprocess, "run", fake_run) result = mod.pass_get_secret("apis/lpd") assert result == {"status": "error", "error": "pass not installed"} def test_linea_fuera_de_rango_es_error(monkeypatch): def fake_run(args, **kwargs): return _FakeCompleted(0, stdout="solo-una-linea\n") monkeypatch.setattr(mod.subprocess, "run", fake_run) result = mod.pass_get_secret("apis/lpd", line=5) assert result == {"status": "error", "error": "line 5 out of range"} def test_timeout_es_error(monkeypatch): def fake_run(args, **kwargs): raise subprocess.TimeoutExpired(cmd=args, timeout=10.0) monkeypatch.setattr(mod.subprocess, "run", fake_run) result = mod.pass_get_secret("apis/lpd") assert result["status"] == "error" assert "timed out" in result["error"]