Spaces:
Sleeping
Sleeping
| """Pruebas de la API de laboratorio: auth de dispositivo, ingesta, y consulta por sesión.""" | |
| from __future__ import annotations | |
| import pytest | |
| from fastapi.testclient import TestClient | |
| from app.config import obtener_config | |
| from app.main import app | |
| PAYLOAD = { | |
| "muestra_id": "ABC-123", | |
| "instrumento_id": "vetscan-1", | |
| "fabricante": "Abaxis", | |
| "observaciones": [ | |
| {"codigo_prueba": "GLU", "valor": "5.0", "unidad": "mmol/L"}, | |
| {"codigo_prueba": "CREA", "valor": "1.2", "unidad": "mg/dL"}, | |
| ], | |
| "momento": "2026-07-25T10:00:00Z", | |
| } | |
| def cliente(): | |
| with TestClient(app) as c: | |
| yield c | |
| def _con_sesion(cliente, email="lab@example.com"): | |
| reg = cliente.post( | |
| "/api/auth/registro", | |
| json={"nombre": "Lab", "apellido": "Vet", "email": email, "password": "clave-segura-1"}, | |
| ) | |
| assert reg.status_code == 200, reg.text | |
| return reg.json()["csrf"] | |
| def test_ingesta_sin_keys_configuradas_es_503(cliente, monkeypatch): | |
| monkeypatch.setattr(obtener_config(), "lab_api_keys", []) | |
| r = cliente.post("/api/lab/ingesta", json=PAYLOAD, headers={"Authorization": "Bearer x"}) | |
| assert r.status_code == 503 | |
| def test_ingesta_sin_bearer_es_401(cliente, monkeypatch): | |
| monkeypatch.setattr(obtener_config(), "lab_api_keys", ["k-secreta"]) | |
| r = cliente.post("/api/lab/ingesta", json=PAYLOAD) | |
| assert r.status_code == 401 | |
| def test_ingesta_bearer_erroneo_es_401(cliente, monkeypatch): | |
| monkeypatch.setattr(obtener_config(), "lab_api_keys", ["k-secreta"]) | |
| r = cliente.post("/api/lab/ingesta", json=PAYLOAD, headers={"Authorization": "Bearer mala"}) | |
| assert r.status_code == 401 | |
| def test_ingesta_y_consulta_completa(cliente, monkeypatch, alta_abierta): | |
| monkeypatch.setattr(obtener_config(), "lab_api_keys", ["k-secreta"]) | |
| # Ingesta con key válida. | |
| r = cliente.post("/api/lab/ingesta", json=PAYLOAD, headers={"Authorization": "Bearer k-secreta"}) | |
| assert r.status_code == 200, r.text | |
| cuerpo = r.json() | |
| assert cuerpo["muestra_id"] == "ABC-123" | |
| assert cuerpo["analitos_mapeados"] == 2 | |
| assert cuerpo["no_mapeados"] == [] | |
| # Consulta sin sesión → 401. | |
| sin_sesion = cliente.get("/api/lab/resultados", params={"muestra": "ABC-123"}) | |
| assert sin_sesion.status_code == 401 | |
| # Con sesión → 200 y analitos mapeados (match case-insensitive del ID). | |
| _con_sesion(cliente) | |
| q = cliente.get("/api/lab/resultados", params={"muestra": "abc-123"}) | |
| assert q.status_code == 200, q.text | |
| analitos = q.json()["analitos"] | |
| assert "gluc" in analitos and "creat" in analitos | |
| assert analitos["gluc"]["valor"] == round(5.0 * 18.016, 4) | |
| # Muestra desconocida → 404. | |
| nope = cliente.get("/api/lab/resultados", params={"muestra": "NO-EXISTE"}) | |
| assert nope.status_code == 404 | |
| def test_ingesta_rechaza_observaciones_vacias(cliente, monkeypatch): | |
| monkeypatch.setattr(obtener_config(), "lab_api_keys", ["k-secreta"]) | |
| payload = {**PAYLOAD, "observaciones": []} | |
| r = cliente.post("/api/lab/ingesta", json=payload, headers={"Authorization": "Bearer k-secreta"}) | |
| assert r.status_code == 422 | |
| def test_pendientes_requiere_sesion(cliente): | |
| """401 antes que 404: la dependencia de sesión corre antes del cuerpo del endpoint, así que | |
| la cola apagada no convierte esto en un endpoint anónimo.""" | |
| assert cliente.get("/api/lab/pendientes").status_code == 401 | |
| def test_pendientes_desactivada_por_defecto_es_404(cliente, alta_abierta): | |
| """Con sesión válida y la cola apagada (el defecto), 404: indistinguible de no existir.""" | |
| _con_sesion(cliente, email="pend-off@example.com") | |
| assert cliente.get("/api/lab/pendientes").status_code == 404 | |
| def test_pendientes_lista_mas_reciente_primero(cliente, monkeypatch, alta_abierta): | |
| monkeypatch.setattr(obtener_config(), "lab_pendientes_habilitado", True) | |
| monkeypatch.setattr(obtener_config(), "lab_api_keys", ["k-secreta"]) | |
| for muestra in ("PEND-1", "PEND-2"): | |
| cliente.post( | |
| "/api/lab/ingesta", | |
| json={**PAYLOAD, "muestra_id": muestra}, | |
| headers={"Authorization": "Bearer k-secreta"}, | |
| ) | |
| _con_sesion(cliente, email="pend@example.com") | |
| r = cliente.get("/api/lab/pendientes") | |
| assert r.status_code == 200 | |
| ids = [x["muestra_id"] for x in r.json()] | |
| assert "PEND-1" in ids and "PEND-2" in ids | |
| assert ids.index("PEND-2") < ids.index("PEND-1") # el último ingerido, primero | |
| def test_persistencia_escribe_en_db(cliente, monkeypatch): | |
| from app import db | |
| monkeypatch.setattr(obtener_config(), "lab_api_keys", ["k-secreta"]) | |
| monkeypatch.setattr(obtener_config(), "lab_persistir", True) | |
| r = cliente.post( | |
| "/api/lab/ingesta", | |
| json={**PAYLOAD, "muestra_id": "PERSIST-1"}, | |
| headers={"Authorization": "Bearer k-secreta"}, | |
| ) | |
| assert r.status_code == 200 | |
| assert any("PERSIST-1" in p for p in db.cargar_resultados_lab()) | |