baton/tests/test_arch_013.py
2026-03-20 21:09:33 +02:00

84 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Tests for BATON-ARCH-013: Keep-alive mechanism / health endpoint.
Acceptance criteria:
1. GET /health returns HTTP 200 OK.
2. Response body contains JSON with {"status": "ok"}.
3. Endpoint does not require authorization (no token, no secret header needed).
4. Keep-alive loop is started when APP_URL is set, and NOT started when APP_URL is unset.
"""
from __future__ import annotations
import os
os.environ.setdefault("BOT_TOKEN", "test-bot-token")
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")
from unittest.mock import AsyncMock, patch
import pytest
from tests.conftest import make_app_client, temp_db
# ---------------------------------------------------------------------------
# Criterion 1 & 2 & 3 — GET /health → 200 OK, {"status": "ok"}, no auth
# ---------------------------------------------------------------------------
@pytest.mark.asyncio
async def test_health_returns_200_ok():
"""GET /health должен вернуть HTTP 200 без какого-либо заголовка авторизации."""
async with make_app_client() as client:
response = await client.get("/health")
assert response.status_code == 200
@pytest.mark.asyncio
async def test_health_returns_status_ok():
"""GET /health должен вернуть JSON содержащий {"status": "ok"}."""
async with make_app_client() as client:
response = await client.get("/health")
data = response.json()
assert data.get("status") == "ok"
# ---------------------------------------------------------------------------
# Criterion 4 — keep-alive task lifecycle
# ---------------------------------------------------------------------------
@pytest.mark.asyncio
async def test_keepalive_started_when_app_url_set():
"""Keep-alive задача должна стартовать при наличии APP_URL."""
from backend.main import app
with temp_db():
with patch("backend.telegram.set_webhook", new_callable=AsyncMock):
with patch("backend.config.APP_URL", "https://example.com"):
with patch("backend.main._keep_alive_loop", new_callable=AsyncMock) as mock_loop:
async with app.router.lifespan_context(app):
pass
# asyncio.create_task вызывается с корутиной _keep_alive_loop — проверяем что она была вызвана
assert mock_loop.called
@pytest.mark.asyncio
async def test_keepalive_not_started_when_app_url_unset():
"""Keep-alive задача НЕ должна стартовать при отсутствии APP_URL."""
from backend.main import app
with temp_db():
with patch("backend.telegram.set_webhook", new_callable=AsyncMock):
with patch("backend.config.APP_URL", None):
with patch("backend.main._keep_alive_loop", new_callable=AsyncMock) as mock_loop:
async with app.router.lifespan_context(app):
pass
assert not mock_loop.called