"""Tests for the asynchronous neutral Bridge API client.""" import json import pytest from aiohttp import web from aiohttp.test_utils import TestClient from custom_components.mb_secure.api import ( BridgeAuthenticationError, BridgeClient, ) TOKEN = "x" * 32 async def test_client_authenticates_and_parses_additive_info( aiohttp_client, socket_enabled: None, ) -> None: """The client authenticates locally and ignores additive response fields.""" async def info(request: web.Request) -> web.Response: assert request.headers["Authorization"] == f"Bearer {TOKEN}" return web.json_response( { "bridge_id": "bridge-installation-1", "bridge_version": "0.1.0", "api_version": 1, "connected": True, "capabilities": ["snapshot", "events"], "future_field": True, } ) app = web.Application() app.router.add_get("/v1/info", info) http_client: TestClient = await aiohttp_client(app) client = BridgeClient( http_client.session, host=str(http_client.make_url("/")), port=80, token=TOKEN, ) result = await client.async_get_info() assert result.bridge_id == "bridge-installation-1" assert result.connected async def test_client_maps_authentication_failures( aiohttp_client, socket_enabled: None, ) -> None: """HTTP authentication failures use the dedicated client exception.""" async def unauthorized(request: web.Request) -> web.Response: return web.json_response({}, status=401) app = web.Application() app.router.add_get("/v1/info", unauthorized) http_client: TestClient = await aiohttp_client(app) client = BridgeClient( http_client.session, host=str(http_client.make_url("/")), port=80, token=TOKEN, ) with pytest.raises(BridgeAuthenticationError): await client.async_get_info() async def test_client_parses_server_sent_domain_events( aiohttp_client, socket_enabled: None, ) -> None: """The event client accepts the mock's server-sent event framing.""" event_payload = { "revision": 2, "event_type": "state_changed", "object_type": "area", "object_id": "area-1", "state": "armed_away", } async def events(request: web.Request) -> web.StreamResponse: response = web.StreamResponse( status=200, headers={"Content-Type": "text/event-stream"}, ) await response.prepare(request) await response.write( f"event: domain_event\ndata: {json.dumps(event_payload)}\n\n".encode() ) await response.write_eof() return response app = web.Application() app.router.add_get("/v1/events", events) http_client: TestClient = await aiohttp_client(app) client = BridgeClient( http_client.session, host=str(http_client.make_url("/")), port=80, token=TOKEN, ) stream = client.async_events() event = await anext(stream) await stream.aclose() assert event.object_id == "area-1" assert event.revision == 2