"""Fixtures for tests that run against a Home Assistant instance.""" from __future__ import annotations from collections.abc import Generator from copy import deepcopy from typing import Any from unittest.mock import AsyncMock, MagicMock, patch from homeassistant.const import CONF_HOST, CONF_TOKEN from homeassistant.core import HomeAssistant import pytest from pytest_homeassistant_custom_component.common import MockConfigEntry from custom_components.ninlight.api import NinlightClient from custom_components.ninlight.const import DOMAIN from tests_unit.samples import ( HOST_RGB, INFO_RGB, MAC_RGB, SETTINGS_COMPILED, STATE_RGB, TOKEN, ) CLIENT_PATCH_TARGETS = [ "custom_components.ninlight.NinlightClient", "custom_components.ninlight.config_flow.NinlightClient", ] @pytest.fixture(autouse=True) def auto_enable_custom_integrations(enable_custom_integrations: None) -> Generator[None]: """Load custom_components/ in every Home Assistant test.""" yield @pytest.fixture def lamp_state() -> dict[str, Any]: return deepcopy(STATE_RGB) @pytest.fixture def lamp_info() -> dict[str, Any]: return deepcopy(INFO_RGB) @pytest.fixture def lamp_settings() -> dict[str, Any]: return deepcopy(SETTINGS_COMPILED) @pytest.fixture def mock_client( lamp_state: dict[str, Any], lamp_info: dict[str, Any], lamp_settings: dict[str, Any] ) -> Generator[MagicMock]: """A lamp whose answers follow the mutable lamp_* fixtures.""" client = MagicMock(spec=NinlightClient) client.host = HOST_RGB client.get_state = AsyncMock(side_effect=lambda: deepcopy(lamp_state)) client.get_info = AsyncMock(side_effect=lambda: deepcopy(lamp_info)) client.get_settings = AsyncMock(side_effect=lambda: deepcopy(lamp_settings)) async def set_state(**fields: Any) -> dict[str, Any]: lamp_state.update(fields) return deepcopy(lamp_state) client.set_state = AsyncMock(side_effect=set_state) client.reboot = AsyncMock(return_value=None) client.fw_update = AsyncMock(return_value=None) patches = [patch(target, return_value=client) for target in CLIENT_PATCH_TARGETS] for p in patches: p.start() yield client for p in patches: p.stop() @pytest.fixture def mock_config_entry() -> MockConfigEntry: return MockConfigEntry( domain=DOMAIN, title="Klyqa GU10 RGB CW/WW 06b8", unique_id=MAC_RGB, data={CONF_HOST: HOST_RGB, CONF_TOKEN: TOKEN}, ) @pytest.fixture async def init_integration( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_client: MagicMock ) -> MockConfigEntry: mock_config_entry.add_to_hass(hass) assert await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() return mock_config_entry @pytest.fixture def mock_setup_entry() -> Generator[AsyncMock]: """Flow tests must not set the entry up for real.""" with patch("custom_components.ninlight.async_setup_entry", return_value=True) as mock: yield mock