"""Tests for backend.api_server.APIServer REST endpoints.""" import sys from pathlib import Path from unittest.mock import MagicMock, patch import pytest import pytest_asyncio # Ensure project root is on path project_root = Path(__file__).resolve().parent.parent.parent sys.path.insert(0, str(project_root)) # ── GET /api/status ───────────────────────────────────────────────── @pytest.mark.asyncio async def test_get_status(api_client): resp = await api_client.get("/api/status") assert resp.status_code == 200 data = resp.json() assert "state" in data assert "is_transcribing" in data assert "version" in data assert "web_server" in data # ── GET /api/config ───────────────────────────────────────────────── @pytest.mark.asyncio async def test_get_config(api_client): resp = await api_client.get("/api/config") assert resp.status_code == 200 data = resp.json() # The config should be a dict (the raw config mapping) assert isinstance(data, dict) # ── PUT /api/config ───────────────────────────────────────────────── @pytest.mark.asyncio async def test_put_config(api_client, controller): """Updating config via PUT should persist and return success.""" # Patch reload_engine to avoid heavy lifting controller.reload_engine = MagicMock(return_value=(True, "ok")) controller.current_model_size = "base.en" controller.current_device_config = "auto" controller.config.set("transcription.model", "base.en") controller.config.set("transcription.device", "auto") resp = await api_client.put( "/api/config", json={"settings": {"display.font_size": 24}}, ) assert resp.status_code == 200 body = resp.json() assert body["status"] == "ok" # Verify the value was actually saved assert controller.config.get("display.font_size") == 24 # ── POST /api/start (engine not ready) ───────────────────────────── @pytest.mark.asyncio async def test_start_when_not_ready(api_client, controller): """Starting transcription without an engine should return 400.""" controller.transcription_engine = None resp = await api_client.post("/api/start") assert resp.status_code == 400 # ── POST /api/clear ───────────────────────────────────────────────── @pytest.mark.asyncio async def test_clear(api_client, controller): from client.transcription_engine_realtime import TranscriptionResult from datetime import datetime controller.transcriptions = [ TranscriptionResult(text="One", is_final=True, timestamp=datetime.now(), user_name="U"), ] resp = await api_client.post("/api/clear") assert resp.status_code == 200 body = resp.json() assert body["cleared"] == 1 assert len(controller.transcriptions) == 0 # ── GET /api/audio-devices ────────────────────────────────────────── @pytest.mark.asyncio async def test_get_audio_devices(api_client, controller): """Audio devices endpoint should return a list, even when mocked.""" # Mock sounddevice so the test works without audio hardware with patch("backend.app_controller.AppController.get_audio_devices", return_value=[{"index": 0, "name": "Mock Mic"}]): resp = await api_client.get("/api/audio-devices") assert resp.status_code == 200 data = resp.json() assert "devices" in data assert len(data["devices"]) >= 1 # ── GET /api/compute-devices ──────────────────────────────────────── @pytest.mark.asyncio async def test_get_compute_devices(api_client, controller): resp = await api_client.get("/api/compute-devices") assert resp.status_code == 200 data = resp.json() assert "devices" in data # At minimum we get the "Auto-detect" entry assert any(d["id"] == "auto" for d in data["devices"]) # ── GET /api/check-update ────────────────────────────────────────── @pytest.mark.asyncio async def test_check_update(api_client, controller): """check-update should return a dict with an 'available' key.""" with patch.object(controller, "check_for_updates", return_value={"available": False, "current_version": "1.0.0"}): resp = await api_client.get("/api/check-update") assert resp.status_code == 200 data = resp.json() assert "available" in data # ── GET /api/version ──────────────────────────────────────────────── @pytest.mark.asyncio async def test_version(api_client): resp = await api_client.get("/api/version") assert resp.status_code == 200 data = resp.json() assert "version" in data # Should be a non-empty string assert isinstance(data["version"], str) assert len(data["version"]) > 0