02cd9d519c
Lint & Test / test (push) Successful in 1m56s
- Rename Python package: wled_controller -> ledgrab - Rename env var prefix: WLED_ -> LEDGRAB_ (with auto-migration for old vars) - Rename localStorage key: wled_api_key -> ledgrab_api_key (with migration) - Rename HA integration domain: wled_screen_controller -> ledgrab - Update all imports, build scripts, Docker, installer, config, docs - Remove HA integration (moved to ledgrab-haos-integration repo) - Remove hacs.json (belongs in HA repo now) - Add startup warning for users with old WLED_ env vars - All tests pass (715/715), ruff clean, tsc clean, frontend builds
151 lines
5.0 KiB
Python
151 lines
5.0 KiB
Python
"""API tests for audio processing template endpoints."""
|
|
|
|
import pytest
|
|
|
|
from ledgrab.config import get_config
|
|
|
|
# Ensure audio filters registered
|
|
import ledgrab.core.audio.filters # noqa: F401
|
|
|
|
_config = get_config()
|
|
_api_key = next(iter(_config.auth.api_keys.values()), "")
|
|
AUTH = {"Authorization": f"Bearer {_api_key}"} if _api_key else {}
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def client():
|
|
"""Provide a TestClient with lifespan (startup/shutdown) properly triggered."""
|
|
from fastapi.testclient import TestClient
|
|
from ledgrab.main import app
|
|
|
|
with TestClient(app) as c:
|
|
yield c
|
|
|
|
|
|
# Track created template IDs for cleanup
|
|
_created_ids: list[str] = []
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def cleanup_after_test(client):
|
|
"""Clean up created templates after each test."""
|
|
yield
|
|
for tid in list(_created_ids):
|
|
client.delete(f"/api/v1/audio-processing-templates/{tid}", headers=AUTH)
|
|
_created_ids.clear()
|
|
|
|
|
|
def _create(client, name: str, filters: list | None = None, **kwargs) -> dict:
|
|
"""Helper: create a template and track for cleanup."""
|
|
body = {"name": name, "filters": filters or [], **kwargs}
|
|
resp = client.post("/api/v1/audio-processing-templates", json=body, headers=AUTH)
|
|
if resp.status_code == 201:
|
|
_created_ids.append(resp.json()["id"])
|
|
return resp
|
|
|
|
|
|
class TestAudioProcessingTemplateAPI:
|
|
"""Test /api/v1/audio-processing-templates endpoints."""
|
|
|
|
def test_list(self, client):
|
|
resp = client.get("/api/v1/audio-processing-templates", headers=AUTH)
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert "templates" in data
|
|
assert "count" in data
|
|
|
|
def test_create(self, client):
|
|
resp = _create(
|
|
client,
|
|
"API Test Template",
|
|
filters=[{"filter_id": "gain", "options": {"factor": 2.0}}],
|
|
description="A test template",
|
|
tags=["test"],
|
|
)
|
|
assert resp.status_code == 201
|
|
data = resp.json()
|
|
assert data["name"] == "API Test Template"
|
|
assert data["id"].startswith("apt_")
|
|
assert len(data["filters"]) == 1
|
|
assert data["filters"][0]["filter_id"] == "gain"
|
|
assert data["description"] == "A test template"
|
|
assert data["tags"] == ["test"]
|
|
|
|
def test_create_invalid_filter_returns_400(self, client):
|
|
resp = client.post(
|
|
"/api/v1/audio-processing-templates",
|
|
json={
|
|
"name": "Bad Template",
|
|
"filters": [{"filter_id": "nonexistent", "options": {}}],
|
|
},
|
|
headers=AUTH,
|
|
)
|
|
assert resp.status_code == 400
|
|
|
|
def test_get_by_id(self, client):
|
|
create_resp = _create(client, "Fetchable Template")
|
|
tid = create_resp.json()["id"]
|
|
|
|
resp = client.get(f"/api/v1/audio-processing-templates/{tid}", headers=AUTH)
|
|
assert resp.status_code == 200
|
|
assert resp.json()["name"] == "Fetchable Template"
|
|
|
|
def test_get_nonexistent_returns_404(self, client):
|
|
resp = client.get("/api/v1/audio-processing-templates/apt_nonexistent", headers=AUTH)
|
|
assert resp.status_code == 404
|
|
|
|
def test_update(self, client):
|
|
create_resp = _create(client, "Original API Template")
|
|
tid = create_resp.json()["id"]
|
|
|
|
resp = client.put(
|
|
f"/api/v1/audio-processing-templates/{tid}",
|
|
json={
|
|
"name": "Updated API Template",
|
|
"filters": [{"filter_id": "inverter", "options": {}}],
|
|
},
|
|
headers=AUTH,
|
|
)
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert data["name"] == "Updated API Template"
|
|
assert len(data["filters"]) == 1
|
|
|
|
def test_update_nonexistent_returns_404(self, client):
|
|
resp = client.put(
|
|
"/api/v1/audio-processing-templates/apt_nonexistent",
|
|
json={"name": "X"},
|
|
headers=AUTH,
|
|
)
|
|
assert resp.status_code == 404
|
|
|
|
def test_delete(self, client):
|
|
create_resp = _create(client, "To Delete API")
|
|
tid = create_resp.json()["id"]
|
|
_created_ids.remove(tid)
|
|
|
|
resp = client.delete(f"/api/v1/audio-processing-templates/{tid}", headers=AUTH)
|
|
assert resp.status_code == 204
|
|
|
|
resp2 = client.get(f"/api/v1/audio-processing-templates/{tid}", headers=AUTH)
|
|
assert resp2.status_code == 404
|
|
|
|
def test_delete_nonexistent_returns_404(self, client):
|
|
resp = client.delete("/api/v1/audio-processing-templates/apt_nonexistent", headers=AUTH)
|
|
assert resp.status_code == 404
|
|
|
|
|
|
class TestFilterRegistryAPI:
|
|
"""Test /api/v1/audio-filters endpoint."""
|
|
|
|
def test_list_filters(self, client):
|
|
resp = client.get("/api/v1/audio-filters", headers=AUTH)
|
|
if resp.status_code == 404:
|
|
pytest.skip("Audio filters registry endpoint not implemented")
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert "filters" in data
|
|
ids = {f["filter_id"] for f in data["filters"]}
|
|
assert "gain" in ids
|
|
assert "inverter" in ids
|