992495e2e4
Tests that imported wled_controller.main at module level caused the real production database (data/ledgrab.db) to be opened before test fixtures could patch the config. This led to silent data loss. Patch the global config singleton at conftest module level (before any test imports main.py) to redirect all DB access to a temp directory.
93 lines
2.8 KiB
Python
93 lines
2.8 KiB
Python
"""Tests for API endpoints (public + authenticated)."""
|
|
|
|
import os
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
from wled_controller import __version__
|
|
from wled_controller.config import get_config
|
|
|
|
_has_display = bool(
|
|
os.environ.get("DISPLAY") or sys.platform == "win32" or sys.platform == "darwin"
|
|
)
|
|
requires_display = pytest.mark.skipif(not _has_display, reason="No display available (headless CI)")
|
|
|
|
# Build auth header from the first configured API key
|
|
_config = get_config()
|
|
_api_key = next(iter(_config.auth.api_keys.values()), "")
|
|
AUTH_HEADERS = {"Authorization": f"Bearer {_api_key}"} if _api_key else {}
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def client():
|
|
"""Provide a TestClient backed by the isolated test database."""
|
|
from fastapi.testclient import TestClient
|
|
from wled_controller.main import app
|
|
|
|
with TestClient(app, raise_server_exceptions=False) as c:
|
|
yield c
|
|
|
|
|
|
def test_root_endpoint(client):
|
|
"""Test root endpoint returns the HTML dashboard."""
|
|
response = client.get("/")
|
|
assert response.status_code == 200
|
|
assert "text/html" in response.headers["content-type"]
|
|
|
|
|
|
def test_health_check(client):
|
|
"""Test health check endpoint."""
|
|
response = client.get("/health")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["status"] == "healthy"
|
|
assert data["version"] == __version__
|
|
assert "timestamp" in data
|
|
|
|
|
|
def test_version_endpoint(client):
|
|
"""Test version endpoint."""
|
|
response = client.get("/api/v1/version")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["version"] == __version__
|
|
assert "python_version" in data
|
|
assert data["api_version"] == "v1"
|
|
|
|
|
|
@requires_display
|
|
def test_get_displays(client):
|
|
"""Test get displays endpoint (requires auth and a real display)."""
|
|
response = client.get("/api/v1/config/displays", headers=AUTH_HEADERS)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "displays" in data
|
|
assert "count" in data
|
|
assert isinstance(data["displays"], list)
|
|
assert data["count"] >= 0
|
|
|
|
# If displays are found, validate structure
|
|
if data["count"] > 0:
|
|
display = data["displays"][0]
|
|
assert "index" in display
|
|
assert "name" in display
|
|
assert "width" in display
|
|
assert "height" in display
|
|
assert "is_primary" in display
|
|
|
|
|
|
def test_openapi_docs(client):
|
|
"""Test OpenAPI documentation is available."""
|
|
response = client.get("/openapi.json")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["info"]["version"] == __version__
|
|
|
|
|
|
def test_swagger_ui(client):
|
|
"""Test Swagger UI is available."""
|
|
response = client.get("/docs")
|
|
assert response.status_code == 200
|
|
assert "text/html" in response.headers["content-type"]
|