feat(infra): auto-commit con 56 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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"
|
||||
Reference in New Issue
Block a user