kin: BATON-SEC-003-backend_dev
This commit is contained in:
parent
097b7af949
commit
f17ee79edb
13 changed files with 593 additions and 125 deletions
|
|
@ -6,6 +6,9 @@ Regression tests for BATON-SEC-007:
|
|||
3. POST /api/signal uses asyncio.create_task — HTTP response is not blocked
|
||||
by Telegram rate-limit pauses.
|
||||
4. GET /health returns only {"status": "ok"} — no timestamp field.
|
||||
|
||||
BATON-SEC-003: POST /api/signal now requires Authorization: Bearer <api_key>.
|
||||
Tests that send signals now register first and use the returned api_key.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -18,6 +21,7 @@ os.environ.setdefault("CHAT_ID", "-1001234567890")
|
|||
os.environ.setdefault("WEBHOOK_SECRET", "test-webhook-secret")
|
||||
os.environ.setdefault("WEBHOOK_URL", "https://example.com/api/webhook/telegram")
|
||||
os.environ.setdefault("FRONTEND_ORIGIN", "http://localhost:3000")
|
||||
os.environ.setdefault("ADMIN_TOKEN", "test-admin-token")
|
||||
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
|
|
@ -31,6 +35,10 @@ from tests.conftest import make_app_client
|
|||
|
||||
SEND_URL = f"https://api.telegram.org/bot{config.BOT_TOKEN}/sendMessage"
|
||||
|
||||
# Valid UUID v4 constants
|
||||
_UUID_CT = "d4e5f6a7-b8c9-4d0e-a1b2-c3d4e5f6a7b8"
|
||||
_UUID_SLOW = "e5f6a7b8-c9d0-4e1f-a2b3-c4d5e6f7a8b9"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Criterion 1 — retry loop is bounded to max 3 attempts
|
||||
|
|
@ -164,10 +172,13 @@ async def test_signal_uses_create_task_for_telegram_send_message():
|
|||
"""POST /api/signal must wrap telegram.send_message in asyncio.create_task."""
|
||||
with patch("backend.main.asyncio.create_task", wraps=asyncio.create_task) as mock_ct:
|
||||
async with make_app_client() as client:
|
||||
await client.post("/api/register", json={"uuid": "d4e5f6a7-b8c9-4d0e-a1b2-c3d4e5f6a7b8", "name": "CT"})
|
||||
reg = await client.post("/api/register", json={"uuid": _UUID_CT, "name": "CT"})
|
||||
assert reg.status_code == 200
|
||||
api_key = reg.json()["api_key"]
|
||||
resp = await client.post(
|
||||
"/api/signal",
|
||||
json={"user_id": "d4e5f6a7-b8c9-4d0e-a1b2-c3d4e5f6a7b8", "timestamp": 1742478000000},
|
||||
json={"user_id": _UUID_CT, "timestamp": 1742478000000},
|
||||
headers={"Authorization": f"Bearer {api_key}"},
|
||||
)
|
||||
|
||||
assert resp.status_code == 200
|
||||
|
|
@ -177,8 +188,6 @@ async def test_signal_uses_create_task_for_telegram_send_message():
|
|||
@pytest.mark.asyncio
|
||||
async def test_signal_response_returns_before_telegram_completes():
|
||||
"""POST /api/signal returns 200 even when Telegram send_message is delayed."""
|
||||
# Simulate a slow Telegram response. If send_message is awaited directly,
|
||||
# the HTTP response would be delayed until sleep completes.
|
||||
slow_sleep_called = False
|
||||
|
||||
async def slow_send_message(_text: str) -> None:
|
||||
|
|
@ -189,19 +198,21 @@ async def test_signal_response_returns_before_telegram_completes():
|
|||
with patch("backend.main.telegram.send_message", side_effect=slow_send_message):
|
||||
with patch("backend.main.asyncio.create_task", wraps=asyncio.create_task):
|
||||
async with make_app_client() as client:
|
||||
await client.post(
|
||||
reg = await client.post(
|
||||
"/api/register",
|
||||
json={"uuid": "e5f6a7b8-c9d0-4e1f-a2b3-c4d5e6f7a8b9", "name": "Slow"},
|
||||
json={"uuid": _UUID_SLOW, "name": "Slow"},
|
||||
)
|
||||
assert reg.status_code == 200
|
||||
api_key = reg.json()["api_key"]
|
||||
resp = await client.post(
|
||||
"/api/signal",
|
||||
json={
|
||||
"user_id": "e5f6a7b8-c9d0-4e1f-a2b3-c4d5e6f7a8b9",
|
||||
"user_id": _UUID_SLOW,
|
||||
"timestamp": 1742478000000,
|
||||
},
|
||||
headers={"Authorization": f"Bearer {api_key}"},
|
||||
)
|
||||
|
||||
# Response must be immediate — no blocking on the 9999-second sleep
|
||||
assert resp.status_code == 200
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue