refactor: comprehensive code quality, security, and release readiness improvements
Some checks failed
Lint & Test / test (push) Failing after 48s
Some checks failed
Lint & Test / test (push) Failing after 48s
Security: tighten CORS defaults, add webhook rate limiting, fix XSS in automations, guard WebSocket JSON.parse, validate ADB address input, seal debug exception leak, URL-encode WS tokens, CSS.escape in selectors. Code quality: add Pydantic models for brightness/power endpoints, fix thread safety and name uniqueness in DeviceStore, immutable update pattern, split 6 oversized files into 16 focused modules, enable TypeScript strictNullChecks (741→102 errors), type state variables, add dom-utils helper, migrate 3 modules from inline onclick to event delegation, ProcessorDependencies dataclass. Performance: async store saves, health endpoint log level, command palette debounce, optimized entity-events comparison, fix service worker precache list. Testing: expand from 45 to 293 passing tests — add store tests (141), route tests (25), core logic tests (42), E2E flow tests (33), organize into tests/api/, tests/storage/, tests/core/, tests/e2e/. DevOps: CI test pipeline, pre-commit config, Dockerfile multi-stage build with non-root user and health check, docker-compose improvements, version bump to 0.2.0. Docs: rewrite CLAUDE.md (202→56 lines), server/CLAUDE.md (212→76), create contexts/server-operations.md, fix .js→.ts references, fix env var prefix in README, rewrite INSTALLATION.md, add CONTRIBUTING.md and .env.example.
This commit is contained in:
74
server/tests/api/routes/test_system_routes.py
Normal file
74
server/tests/api/routes/test_system_routes.py
Normal file
@@ -0,0 +1,74 @@
|
||||
"""Tests for system routes — health, version.
|
||||
|
||||
These tests use the FastAPI TestClient against the real app. The health
|
||||
and version endpoints do NOT require authentication, so we can test them
|
||||
without setting up the full dependency injection.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from wled_controller import __version__
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def client():
|
||||
"""Provide a test client for the main app.
|
||||
|
||||
The app module initializes stores from the default config on import,
|
||||
which is acceptable for read-only endpoints tested here.
|
||||
"""
|
||||
from wled_controller.main import app
|
||||
|
||||
return TestClient(app, raise_server_exceptions=False)
|
||||
|
||||
|
||||
class TestHealthEndpoint:
|
||||
def test_health_returns_200(self, client):
|
||||
resp = client.get("/health")
|
||||
assert resp.status_code == 200
|
||||
|
||||
def test_health_response_structure(self, client):
|
||||
data = client.get("/health").json()
|
||||
assert data["status"] == "healthy"
|
||||
assert data["version"] == __version__
|
||||
assert "timestamp" in data
|
||||
|
||||
def test_health_no_auth_required(self, client):
|
||||
"""Health endpoint should work without Authorization header."""
|
||||
resp = client.get("/health")
|
||||
assert resp.status_code == 200
|
||||
|
||||
|
||||
class TestVersionEndpoint:
|
||||
def test_version_returns_200(self, client):
|
||||
resp = client.get("/api/v1/version")
|
||||
assert resp.status_code == 200
|
||||
|
||||
def test_version_response_fields(self, client):
|
||||
data = client.get("/api/v1/version").json()
|
||||
assert data["version"] == __version__
|
||||
assert "python_version" in data
|
||||
assert data["api_version"] == "v1"
|
||||
assert "demo_mode" in data
|
||||
|
||||
|
||||
class TestOpenAPIEndpoint:
|
||||
def test_openapi_available(self, client):
|
||||
resp = client.get("/openapi.json")
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
assert "info" in data
|
||||
assert data["info"]["version"] == __version__
|
||||
|
||||
def test_swagger_ui(self, client):
|
||||
resp = client.get("/docs")
|
||||
assert resp.status_code == 200
|
||||
assert "text/html" in resp.headers["content-type"]
|
||||
|
||||
|
||||
class TestRootEndpoint:
|
||||
def test_root_returns_html(self, client):
|
||||
resp = client.get("/")
|
||||
assert resp.status_code == 200
|
||||
assert "text/html" in resp.headers["content-type"]
|
||||
Reference in New Issue
Block a user