Implement bridge-backed Home Assistant integration
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user