1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-28 08:02:23 +01:00
Files
esphome/tests/integration/test_host_mode_api_password.py

70 lines
2.6 KiB
Python

"""Integration test for API password authentication."""
from __future__ import annotations
import asyncio
from aioesphomeapi import APIConnectionError, InvalidAuthAPIError
import pytest
from .types import APIClientConnectedFactory, RunCompiledFunction
@pytest.mark.asyncio
async def test_host_mode_api_password(
yaml_config: str,
run_compiled: RunCompiledFunction,
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test API authentication with password."""
async with run_compiled(yaml_config):
# Connect with correct password
async with api_client_connected(password="test_password_123") as client:
# Verify we can get device info
device_info = await client.device_info()
assert device_info is not None
assert device_info.uses_password is True
assert device_info.name == "host-mode-api-password"
# Subscribe to states to ensure authenticated connection works
loop = asyncio.get_running_loop()
state_future: asyncio.Future[bool] = loop.create_future()
states = {}
def on_state(state):
states[state.key] = state
if not state_future.done():
state_future.set_result(True)
client.subscribe_states(on_state)
# Wait for at least one state with timeout
try:
await asyncio.wait_for(state_future, timeout=5.0)
except TimeoutError:
pytest.fail("No states received within timeout")
# Should have received at least one state (the test sensor)
assert len(states) > 0
# Test with wrong password - should fail
# Try connecting with wrong password
try:
async with api_client_connected(
password="wrong_password", timeout=5
) as client:
# If we get here without exception, try to use the connection
# which should fail if auth failed
await client.device_info_and_list_entities()
# If we successfully got device info and entities, auth didn't fail properly
pytest.fail("Connection succeeded with wrong password")
except (InvalidAuthAPIError, APIConnectionError) as e:
# Expected - auth should fail
# Accept either InvalidAuthAPIError or generic APIConnectionError
# since the client might not always distinguish
assert (
"password" in str(e).lower()
or "auth" in str(e).lower()
or "invalid" in str(e).lower()
)