feat(infra): auto-commit con 88 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
"""Tests para hoppscotch_run_request.
|
||||
|
||||
Deterministas: monkeypatchean requests.request (ejecucion HTTP) y requests.post
|
||||
(mutation createUserHistory). Verifican la resolucion de placedores `<<>>`/`{{}}`
|
||||
para EJECUTAR, que el History recibe la request SIN resolver, y los caminos de
|
||||
record_history=False y de error de transporte.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from datetime import timedelta
|
||||
|
||||
import infra.hoppscotch_run_request # noqa: F401
|
||||
|
||||
# El __init__ rebinds el nombre a la funcion; recuperamos el submodulo real.
|
||||
mod = sys.modules["infra.hoppscotch_run_request"]
|
||||
|
||||
|
||||
class _FakeResponse:
|
||||
"""Respuesta minima para requests.request (ejecucion)."""
|
||||
|
||||
def __init__(self, status_code=200, text="OK", headers=None, elapsed_ms=12):
|
||||
self.status_code = status_code
|
||||
self.text = text
|
||||
self.headers = headers or {"Content-Type": "text/plain"}
|
||||
self.elapsed = timedelta(milliseconds=elapsed_ms)
|
||||
|
||||
|
||||
class _FakeGraphQLResponse:
|
||||
"""Respuesta minima para requests.post (createUserHistory)."""
|
||||
|
||||
def __init__(self, status_code=200, json_data=None):
|
||||
self.status_code = status_code
|
||||
self._json = json_data
|
||||
|
||||
def json(self):
|
||||
if self._json is None:
|
||||
raise ValueError("no json")
|
||||
return self._json
|
||||
|
||||
|
||||
def _patch_history_ok(monkeypatch, captured):
|
||||
def fake_post(url, **kwargs):
|
||||
captured["history_url"] = url
|
||||
captured["history_kwargs"] = kwargs
|
||||
return _FakeGraphQLResponse(
|
||||
200, {"data": {"createUserHistory": {"id": "hist-42"}}}
|
||||
)
|
||||
|
||||
monkeypatch.setattr(mod.requests, "post", fake_post)
|
||||
|
||||
|
||||
def test_ejecuta_resolviendo_variables_angle(monkeypatch):
|
||||
captured = {}
|
||||
|
||||
def fake_request(method, url, **kwargs):
|
||||
captured["method"] = method
|
||||
captured["url"] = url
|
||||
captured["kwargs"] = kwargs
|
||||
return _FakeResponse(200, text="pong")
|
||||
|
||||
monkeypatch.setattr(mod.requests, "request", fake_request)
|
||||
_patch_history_ok(monkeypatch, captured)
|
||||
|
||||
result = mod.hoppscotch_run_request(
|
||||
"GET",
|
||||
"<<baseURL>>/x",
|
||||
variables={"baseURL": "https://h"},
|
||||
access_token="A",
|
||||
)
|
||||
|
||||
# La request ejecutada lleva la url resuelta.
|
||||
assert captured["url"] == "https://h/x"
|
||||
assert result["status"] == "ok"
|
||||
assert result["status_code"] == 200
|
||||
assert result["response_body"] == "pong"
|
||||
assert result["duration_ms"] == 12
|
||||
|
||||
|
||||
def test_ejecuta_resolviendo_variables_brace(monkeypatch):
|
||||
captured = {}
|
||||
|
||||
def fake_request(method, url, **kwargs):
|
||||
captured["url"] = url
|
||||
return _FakeResponse(200)
|
||||
|
||||
monkeypatch.setattr(mod.requests, "request", fake_request)
|
||||
_patch_history_ok(monkeypatch, captured)
|
||||
|
||||
mod.hoppscotch_run_request(
|
||||
"GET",
|
||||
"{{baseURL}}/x",
|
||||
variables={"baseURL": "https://h"},
|
||||
access_token="A",
|
||||
)
|
||||
|
||||
# {{var}} resuelve igual que <<var>>.
|
||||
assert captured["url"] == "https://h/x"
|
||||
|
||||
|
||||
def test_record_history_registra_request_sin_resolver(monkeypatch):
|
||||
captured = {}
|
||||
|
||||
def fake_request(method, url, **kwargs):
|
||||
return _FakeResponse(200, text="body", headers={"X-Test": "1"})
|
||||
|
||||
monkeypatch.setattr(mod.requests, "request", fake_request)
|
||||
_patch_history_ok(monkeypatch, captured)
|
||||
|
||||
result = mod.hoppscotch_run_request(
|
||||
"GET",
|
||||
"<<baseURL>>/api/status",
|
||||
title="Status",
|
||||
variables={"baseURL": "https://h"},
|
||||
access_token="ACCESS-JWT",
|
||||
record_history=True,
|
||||
)
|
||||
|
||||
assert result["recorded"] is True
|
||||
assert result["history_id"] == "hist-42"
|
||||
|
||||
# El POST de History fue al endpoint GraphQL con la cookie access_token.
|
||||
assert captured["history_url"].endswith("/graphql")
|
||||
assert captured["history_kwargs"]["cookies"] == {"access_token": "ACCESS-JWT"}
|
||||
|
||||
payload = captured["history_kwargs"]["json"]
|
||||
assert "createUserHistory" in payload["query"]
|
||||
variables = payload["variables"]
|
||||
assert variables["t"] == "REST"
|
||||
|
||||
# reqData es el json string de un HoppRESTRequest v:"2" con la url SIN resolver.
|
||||
req = json.loads(variables["d"])
|
||||
assert req["v"] == "2"
|
||||
assert req["method"] == "GET"
|
||||
assert req["endpoint"] == "<<baseURL>>/api/status"
|
||||
assert req["name"] == "Status"
|
||||
|
||||
# resMetadata minimo: statusCode + duration.
|
||||
res_meta = json.loads(variables["m"])
|
||||
assert res_meta == {"statusCode": 200, "duration": 12}
|
||||
|
||||
|
||||
def test_record_history_false_no_llama_create_user_history(monkeypatch):
|
||||
calls = {"post": 0}
|
||||
|
||||
def fake_request(method, url, **kwargs):
|
||||
return _FakeResponse(200)
|
||||
|
||||
def fake_post(url, **kwargs):
|
||||
calls["post"] += 1
|
||||
return _FakeGraphQLResponse(200, {"data": {"createUserHistory": {"id": "x"}}})
|
||||
|
||||
monkeypatch.setattr(mod.requests, "request", fake_request)
|
||||
monkeypatch.setattr(mod.requests, "post", fake_post)
|
||||
|
||||
result = mod.hoppscotch_run_request(
|
||||
"GET",
|
||||
"https://h/x",
|
||||
access_token="A",
|
||||
record_history=False,
|
||||
)
|
||||
|
||||
assert result["recorded"] is False
|
||||
assert result["history_id"] is None
|
||||
assert calls["post"] == 0
|
||||
|
||||
|
||||
def test_request_exception_status_error(monkeypatch):
|
||||
def fake_request(method, url, **kwargs):
|
||||
raise mod.requests.RequestException("boom")
|
||||
|
||||
# Si llegara a postear seria un fallo del test: no debe.
|
||||
def fake_post(url, **kwargs):
|
||||
raise AssertionError("no debe registrar history si la ejecucion fallo")
|
||||
|
||||
monkeypatch.setattr(mod.requests, "request", fake_request)
|
||||
monkeypatch.setattr(mod.requests, "post", fake_post)
|
||||
|
||||
result = mod.hoppscotch_run_request(
|
||||
"GET", "https://h/x", access_token="A"
|
||||
)
|
||||
|
||||
assert result["status"] == "error"
|
||||
assert result["recorded"] is False
|
||||
assert "boom" in result["error"]
|
||||
|
||||
|
||||
def test_variable_faltante_conserva_literal(monkeypatch):
|
||||
captured = {}
|
||||
|
||||
def fake_request(method, url, **kwargs):
|
||||
captured["url"] = url
|
||||
return _FakeResponse(200)
|
||||
|
||||
monkeypatch.setattr(mod.requests, "request", fake_request)
|
||||
_patch_history_ok(monkeypatch, captured)
|
||||
|
||||
mod.hoppscotch_run_request(
|
||||
"GET",
|
||||
"<<baseURL>>/x",
|
||||
variables={"otra": "y"},
|
||||
access_token="A",
|
||||
)
|
||||
|
||||
# baseURL no esta en variables -> el literal se conserva.
|
||||
assert captured["url"] == "<<baseURL>>/x"
|
||||
Reference in New Issue
Block a user