from collections.abc import Sequence from fastapi.testclient import TestClient from app.ha.exceptions import HaTimeoutError from app.ha.models import HaEntitySummary from app.ha.reader import HaReader from app.main import app class FakeHaReader(HaReader): def __init__(self) -> None: pass def read_entities(self) -> Sequence[HaEntitySummary]: return [HaEntitySummary(entity_id="sensor.temperature", domain="sensor")] class TimeoutHaReader(HaReader): def __init__(self) -> None: pass def read_entities(self) -> Sequence[HaEntitySummary]: raise HaTimeoutError("contains internal details that must not leak") def test_openapi_docs_are_available() -> None: with TestClient(app) as client: response = client.get("/docs") assert response.status_code == 200 assert "SillyHome Next API" in response.text def test_entities_returns_reader_data() -> None: with TestClient(app) as client: app.state.ha_reader = FakeHaReader() response = client.get("/v1/entities") assert response.status_code == 200 assert response.json() == [ { "entity_id": "sensor.temperature", "domain": "sensor", "state_class": None, "device_class": None, "unit_of_measurement": None, } ] def test_entities_returns_503_without_home_assistant_config() -> None: with TestClient(app) as client: response = client.get("/v1/entities") assert response.status_code == 503 def test_entities_maps_ha_errors_without_leaking_details() -> None: with TestClient(app) as client: app.state.ha_reader = TimeoutHaReader() response = client.get("/v1/entities") assert response.status_code == 504 assert response.json() == {"detail": "Home Assistant request timed out."}