feat(infra): auto-commit con 56 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-21 14:22:55 +02:00
parent c1071a82b3
commit 32c7336bf6
56 changed files with 5307 additions and 100 deletions
@@ -0,0 +1,117 @@
"""Tests para query_osint_db.
Mockean urllib.request.urlopen para no depender del service osint_db vivo:
se interceptan el exito (cuerpo {status:ok,...}), el error de dominio del service
({status:error,...}) y el error de red (conexion rechazada).
"""
import io
import json
import urllib.error
from query_osint_db import query_osint_db
class _FakeResponse:
"""Context manager que imita la respuesta de urllib.request.urlopen."""
def __init__(self, payload: dict):
self._raw = json.dumps(payload).encode("utf-8")
def __enter__(self):
return self
def __exit__(self, *exc):
return False
def read(self):
return self._raw
def test_query_ok_devuelve_cuerpo_del_service(monkeypatch):
payload = {
"status": "ok",
"columns": ["count_star()"],
"rows": [{"count_star()": 42}],
"row_count": 1,
"truncated": False,
}
captured = {}
def fake_urlopen(req, timeout=None):
captured["url"] = req.full_url
captured["body"] = json.loads(req.data.decode("utf-8"))
captured["method"] = req.get_method()
return _FakeResponse(payload)
monkeypatch.setattr("urllib.request.urlopen", fake_urlopen)
result = query_osint_db("SELECT COUNT(*) FROM personas")
assert result == payload
assert result["status"] == "ok"
assert result["rows"] == [{"count_star()": 42}]
assert captured["url"] == "http://127.0.0.1:8771/api/query"
assert captured["body"] == {"sql": "SELECT COUNT(*) FROM personas"}
assert captured["method"] == "POST"
def test_query_error_de_dominio_se_reenvia(monkeypatch):
payload = {"status": "error", "error": "Catalog Error: Table no existe"}
def fake_urlopen(req, timeout=None):
return _FakeResponse(payload)
monkeypatch.setattr("urllib.request.urlopen", fake_urlopen)
result = query_osint_db("SELECT * FROM tabla_inexistente")
assert result["status"] == "error"
assert "no existe" in result["error"]
def test_service_caido_devuelve_error_claro(monkeypatch):
def fake_urlopen(req, timeout=None):
raise urllib.error.URLError("Connection refused")
monkeypatch.setattr("urllib.request.urlopen", fake_urlopen)
result = query_osint_db("SELECT 1")
assert result["status"] == "error"
assert "osint_db service not reachable" in result["error"]
assert "http://127.0.0.1:8771/api/query" in result["error"]
def test_base_url_custom_se_respeta(monkeypatch):
captured = {}
def fake_urlopen(req, timeout=None):
captured["url"] = req.full_url
return _FakeResponse({"status": "ok", "rows": [], "row_count": 0})
monkeypatch.setattr("urllib.request.urlopen", fake_urlopen)
query_osint_db("SELECT 1", base_url="http://10.0.0.5:9000/")
assert captured["url"] == "http://10.0.0.5:9000/api/query"
def test_http_error_con_cuerpo_json_se_reenvia(monkeypatch):
body = json.dumps({"status": "error", "error": "boom"}).encode("utf-8")
def fake_urlopen(req, timeout=None):
raise urllib.error.HTTPError(
url=req.full_url,
code=500,
msg="Internal Server Error",
hdrs=None,
fp=io.BytesIO(body),
)
monkeypatch.setattr("urllib.request.urlopen", fake_urlopen)
result = query_osint_db("SELECT 1")
assert result["status"] == "error"
assert result["error"] == "boom"