"""Common test code.""" from typing import List, NamedTuple, Optional from unittest.mock import MagicMock, Mock from gogogate2_api import GogoGate2Api, InfoResponse from gogogate2_api.common import Door, DoorMode, DoorStatus, Network, Outputs, Wifi from homeassistant.components import persistent_notification from homeassistant.components.cover import DOMAIN as COVER_DOMAIN from homeassistant.components.gogogate2 import async_unload_entry from homeassistant.components.gogogate2.common import ( GogoGateDataUpdateCoordinator, get_data_update_coordinator, ) import homeassistant.components.gogogate2.const as const from homeassistant.components.homeassistant import DOMAIN as HA_DOMAIN from homeassistant.config import async_process_ha_core_config from homeassistant.config_entries import SOURCE_USER from homeassistant.const import CONF_UNIT_SYSTEM, CONF_UNIT_SYSTEM_METRIC from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import RESULT_TYPE_CREATE_ENTRY, RESULT_TYPE_FORM from homeassistant.setup import async_setup_component INFO_RESPONSE = InfoResponse( user="user1", gogogatename="gogogatename1", model="", apiversion="", remoteaccessenabled=False, remoteaccess="abcdefg.my-gogogate.com", firmwareversion="", apicode="API_CODE", door1=Door( door_id=1, permission=True, name="Door1", mode=DoorMode.GARAGE, status=DoorStatus.OPENED, sensor=True, sensorid=None, camera=False, events=2, temperature=None, ), door2=Door( door_id=2, permission=True, name=None, mode=DoorMode.GARAGE, status=DoorStatus.OPENED, sensor=True, sensorid=None, camera=False, events=2, temperature=None, ), door3=Door( door_id=3, permission=True, name="Door3", mode=DoorMode.GARAGE, status=DoorStatus.OPENED, sensor=True, sensorid=None, camera=False, events=2, temperature=None, ), outputs=Outputs(output1=True, output2=False, output3=True), network=Network(ip=""), wifi=Wifi(SSID="", linkquality="", signal=""), ) class ComponentData(NamedTuple): """Test data for a mocked component.""" api: GogoGate2Api data_update_coordinator: GogoGateDataUpdateCoordinator class ComponentFactory: """Manages the setup and unloading of the withing component and profiles.""" def __init__(self, hass: HomeAssistant, gogogate_api_mock: Mock) -> None: """Initialize the object.""" self._hass = hass self._gogogate_api_mock = gogogate_api_mock @property def api_class_mock(self): """Get the api class mock.""" return self._gogogate_api_mock async def configure_component( self, cover_config: Optional[List[dict]] = None ) -> None: """Configure the component.""" hass_config = { "homeassistant": {CONF_UNIT_SYSTEM: CONF_UNIT_SYSTEM_METRIC}, "cover": cover_config or [], } await async_process_ha_core_config(self._hass, hass_config.get("homeassistant")) assert await async_setup_component(self._hass, HA_DOMAIN, {}) assert await async_setup_component( self._hass, persistent_notification.DOMAIN, {} ) assert await async_setup_component(self._hass, COVER_DOMAIN, hass_config) assert await async_setup_component(self._hass, const.DOMAIN, hass_config) await self._hass.async_block_till_done() async def run_config_flow( self, config_data: dict, api_mock: Optional[GogoGate2Api] = None ) -> ComponentData: """Run a config flow.""" if api_mock is None: api_mock: GogoGate2Api = MagicMock(spec=GogoGate2Api) api_mock.info.return_value = INFO_RESPONSE self._gogogate_api_mock.reset_mocks() self._gogogate_api_mock.return_value = api_mock result = await self._hass.config_entries.flow.async_init( const.DOMAIN, context={"source": SOURCE_USER} ) assert result assert result["type"] == RESULT_TYPE_FORM assert result["step_id"] == "user" result = await self._hass.config_entries.flow.async_configure( result["flow_id"], user_input=config_data, ) assert result assert result["type"] == RESULT_TYPE_CREATE_ENTRY assert result["data"] == config_data await self._hass.async_block_till_done() config_entry = next( iter( entry for entry in self._hass.config_entries.async_entries(const.DOMAIN) if entry.unique_id == "abcdefg" ) ) return ComponentData( api=api_mock, data_update_coordinator=get_data_update_coordinator( self._hass, config_entry ), ) async def unload(self) -> None: """Unload all config entries.""" config_entries = self._hass.config_entries.async_entries(const.DOMAIN) for config_entry in config_entries: await async_unload_entry(self._hass, config_entry) await self._hass.async_block_till_done() assert not self._hass.states.async_entity_ids("gogogate")