106 lines
4.9 KiB
Python
106 lines
4.9 KiB
Python
import os
|
||
from typing import Any, Dict
|
||
|
||
import pytest
|
||
|
||
pytestmark = pytest.mark.api
|
||
|
||
|
||
try:
|
||
from fastapi.testclient import TestClient
|
||
except Exception:
|
||
TestClient = None # type: ignore
|
||
|
||
|
||
@pytest.mark.skipif(TestClient is None, reason="FastAPI TestClient not available")
|
||
def test_system_health_and_info(fastapi_client: Any):
|
||
"""
|
||
Базовые системные эндпоинты должны отвечать 200 и содержать ожидаемые поля.
|
||
"""
|
||
r = fastapi_client.get("/api/system/health")
|
||
assert r.status_code == 200, f"/api/system/health status != 200: {r.status_code}, body={r.text}"
|
||
data = r.json()
|
||
assert isinstance(data, dict), "health response must be JSON object"
|
||
|
||
r2 = fastapi_client.get("/api/system/info")
|
||
assert r2.status_code == 200, f"/api/system/info status != 200: {r2.status_code}, body={r2.text}"
|
||
data2 = r2.json()
|
||
assert isinstance(data2, dict), "info response must be JSON object"
|
||
|
||
|
||
@pytest.mark.skipif(TestClient is None, reason="FastAPI TestClient not available")
|
||
def test_ping_endpoint(fastapi_client: Any):
|
||
r = fastapi_client.get("/api/v1/ping")
|
||
assert r.status_code in (200, 404), f"/api/v1/ping unexpected status: {r.status_code}"
|
||
# Некоторые билды могут не иметь /api/v1/ping; тогда этот тест не фейлится жестко.
|
||
|
||
|
||
@pytest.mark.skipif(TestClient is None, reason="FastAPI TestClient not available")
|
||
def test_node_endpoints_exist(fastapi_client: Any):
|
||
"""
|
||
Проверяем наличие критических узловых маршрутов из docs/API_ENDPOINTS_CHECK.md.
|
||
"""
|
||
# Мягкая проверка: если нет — не падаем, а логируем статус
|
||
for path in [
|
||
"/api/node/network/status",
|
||
"/api/node/network/ping",
|
||
"/api/node/content/sync",
|
||
"/api/system/metrics",
|
||
]:
|
||
resp = fastapi_client.get(path)
|
||
assert resp.status_code in (200, 401, 405, 404), f"{path} unexpected status {resp.status_code}"
|
||
|
||
|
||
@pytest.mark.skipif(TestClient is None, reason="FastAPI TestClient not available")
|
||
def test_auth_twa_and_me_flow_if_enabled(fastapi_client: Any):
|
||
"""
|
||
Если присутствует TWA аутентификация, проверяем базовый контракт.
|
||
"""
|
||
# /auth.twa обычно POST; без реального TWA токена ожидаем 400/401.
|
||
resp = fastapi_client.post("/auth.twa", json={"payload": "invalid"})
|
||
assert resp.status_code in (400, 401, 404, 405), f"Unexpected status for /auth.twa: {resp.status_code}"
|
||
|
||
# /api/v1/auth/me обычно требует JWT — без токена ожидаем 401
|
||
resp2 = fastapi_client.get("/api/v1/auth/me")
|
||
assert resp2.status_code in (401, 404), f"Unexpected status for /api/v1/auth/me: {resp2.status_code}"
|
||
|
||
|
||
@pytest.mark.skipif(TestClient is None, reason="FastAPI TestClient not available")
|
||
def test_storage_upload_flow_smoke(fastapi_client: Any, small_sample_bytes: bytes):
|
||
"""
|
||
Смоук тест контракта загрузки: наличие маршрутов и ожидаемые статусы.
|
||
Реальная загрузка чанками покрывается интеграционными/сквозными тестами.
|
||
"""
|
||
# Инициируем загрузку (если реализовано)
|
||
init_paths = ["/api/storage", "/api/storage/api/v1/storage/upload"]
|
||
init_ok = False
|
||
for path in init_paths:
|
||
r = fastapi_client.get(path)
|
||
if r.status_code in (200, 405): # 405 = метод не тот, но маршрут существует
|
||
init_ok = True
|
||
break
|
||
assert init_ok, "Storage upload init endpoints missing"
|
||
|
||
# Попытка отправить чанк (ожидаем 400/401/404/405 без корректных параметров)
|
||
r2 = fastapi_client.post("/api/storage/upload/chunk", json={"upload_id": "x", "index": 0, "data": "AA=="})
|
||
assert r2.status_code in (400, 401, 404, 405), f"Unexpected status for upload/chunk: {r2.status_code}"
|
||
|
||
# Завершение
|
||
r3 = fastapi_client.post("/api/storage/upload/complete", json={"upload_id": "x"})
|
||
assert r3.status_code in (400, 401, 404, 405), f"Unexpected status for upload/complete: {r3.status_code}"
|
||
|
||
|
||
@pytest.mark.skipif(TestClient is None, reason="FastAPI TestClient not available")
|
||
def test_content_access_routes_present(fastapi_client: Any):
|
||
"""
|
||
Проверка наличия маршрутов доступа к контенту, описанных в открытых файлах:
|
||
"""
|
||
for path in [
|
||
"/content.view/unknown",
|
||
"/api/system/ready",
|
||
"/api/system/live",
|
||
"/",
|
||
"/api",
|
||
]:
|
||
resp = fastapi_client.get(path)
|
||
assert resp.status_code in (200, 404, 405), f"{path} unexpected status {resp.status_code}" |