first commit

This commit is contained in:
rayd1o
2026-03-05 11:46:58 +08:00
commit e7033775d8
20657 changed files with 1988940 additions and 0 deletions

108
backend/tests/test_api.py Normal file
View File

@@ -0,0 +1,108 @@
"""API endpoint tests"""
import pytest
from datetime import datetime
from unittest.mock import patch, AsyncMock
from httpx import AsyncClient, ASGITransport
from app.main import app
from app.core.config import settings
from app.core.security import create_access_token
@pytest.fixture
def auth_headers():
"""Create authentication headers"""
token = create_access_token({"sub": "1", "username": "testuser"})
return {"Authorization": f"Bearer {token}"}
@pytest.mark.asyncio
async def test_health_check():
"""Test health check endpoint"""
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get("/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "healthy"
assert "version" in data
@pytest.mark.asyncio
async def test_root_endpoint():
"""Test root endpoint"""
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get("/")
assert response.status_code == 200
data = response.json()
assert data["name"] == settings.PROJECT_NAME
assert data["version"] == settings.VERSION
@pytest.mark.asyncio
async def test_dashboard_stats_without_auth():
"""Test dashboard stats requires authentication"""
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get("/api/v1/dashboard/stats")
assert response.status_code == 401
@pytest.mark.asyncio
async def test_dashboard_stats_with_auth(auth_headers):
"""Test dashboard stats with authentication"""
with patch("app.api.v1.dashboard.cache.get", return_value=None):
with patch("app.api.v1.dashboard.cache.set", return_value=True):
with patch("app.db.session.get_db") as mock_get_db:
mock_session = AsyncMock()
mock_result = AsyncMock()
mock_result.scalar.return_value = 0
mock_result.fetchall.return_value = []
mock_session.execute.return_value = mock_result
async def mock_db_context():
yield mock_session
mock_get_db.return_value = mock_db_context()
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get(
"/api/v1/dashboard/stats",
headers=auth_headers,
)
assert response.status_code == 200
data = response.json()
assert "total_datasources" in data
@pytest.mark.asyncio
async def test_alerts_without_auth():
"""Test alerts endpoint requires authentication"""
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get("/api/v1/alerts")
assert response.status_code == 401
@pytest.mark.asyncio
async def test_alerts_endpoint_with_auth(auth_headers):
"""Test alerts endpoint with authentication"""
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get("/api/v1/alerts", headers=auth_headers)
assert response.status_code == 200
@pytest.mark.asyncio
async def test_invalid_token():
"""Test that invalid token is rejected"""
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get(
"/api/v1/dashboard/stats",
headers={"Authorization": "Bearer invalid_token"},
)
assert response.status_code == 401