text: """Helper for HomematicIP Cloud Tests."""
  import json
  
  from asynctest import Mock, patch
  from homematicip.aio.class_maps import (
      TYPE_CLASS_MAP,
      TYPE_GROUP_MAP,
      TYPE_SECURITY_EVENT_MAP,
  )
  from homematicip.aio.device import AsyncDevice
  from homematicip.aio.group import AsyncGroup
  from homematicip.aio.home import AsyncHome
  from homematicip.home import Home
  
  from homeassistant import config_entries
  from homeassistant.components.homematicip_cloud import DOMAIN as HMIPC_DOMAIN
  from homeassistant.components.homematicip_cloud.device import (
      ATTR_IS_GROUP,
      ATTR_MODEL_TYPE,
  )
  from homeassistant.components.homematicip_cloud.hap import HomematicipHAP
  from homeassistant.helpers.typing import HomeAssistantType
  from homeassistant.setup import async_setup_component
  
  from tests.common import load_fixture
  
  HAPID = "3014F7110000000000000001"
  HAPPIN = "5678"
  AUTH_TOKEN = "1234"
  HOME_JSON = "homematicip_cloud.json"
  FIXTURE_DATA = load_fixture(HOME_JSON)
  
  
  def get_and_check_entity_basics(hass, mock_hap, entity_id, entity_name, device_model):
      """Get and test basic device."""
      ha_state = hass.states.get(entity_id)
      assert ha_state is not None
      if device_model:
          assert ha_state.attributes[ATTR_MODEL_TYPE] == device_model
      assert ha_state.name == entity_name
  
      hmip_device = mock_hap.hmip_device_by_entity_id.get(entity_id)
  
      if hmip_device:
          if isinstance(hmip_device, AsyncDevice):
              assert ha_state.attributes[ATTR_IS_GROUP] is False
          elif isinstance(hmip_device, AsyncGroup):
              assert ha_state.attributes[ATTR_IS_GROUP]
      return ha_state, hmip_device
  
  
  async def async_manipulate_test_data(
      hass, hmip_device, attribute, new_value, channel=1, fire_device=None
  ):
      """Set new value on hmip device."""
      if channel == 1:
          setattr(hmip_device, attribute, new_value)
      if hasattr(hmip_device, "functionalChannels"):
          functional_channel = hmip_device.functionalChannels[channel]
          setattr(functional_channel, attribute, new_value)
  
      fire_target = hmip_device if fire_device is None else fire_device
  
      if isinstance(fire_target, AsyncHome):
          fire_target.fire_update_event(
              fire_target._rawJSONData  # pylint: disable=protected-access
          )
      else:
          fire_target.fire_update_event()
  
      await hass.async_block_till_done()
  
  
  class HomeFactory:
      """Factory to create a HomematicIP Cloud Home."""
  
      def __init__(
          self,
          hass: HomeAssistantType,
          mock_connection,
          hmip_config_entry: config_entries.ConfigEntry,
      ):
          """Initialize the Factory."""
          self.hass = hass
          self.mock_connection = mock_connection
          self.hmip_config_entry = hmip_config_entry
  
      async def async_get_mock_hap(
          self, test_devices=[], test_groups=[]
      ) -> HomematicipHAP:
          """Create a mocked homematic access point."""
          home_name = self.hmip_config_entry.data["name"]
          mock_home = (
              HomeTemplate(
                  connection=self.mock_connection,
                  home_name=home_name,
                  test_devices=test_devices,
                  test_groups=test_groups,
              )
              .init_home()
              .get_async_home_mock()
          )
  
          self.hmip_config_entry.add_to_hass(self.hass)
          with patch(
              "homeassistant.components.homematicip_cloud.hap.HomematicipHAP.get_hap",
              return_value=mock_home,
          ):
              assert await async_setup_component(self.hass, HMIPC_DOMAIN, {})
  
          await self.hass.async_block_till_done()
  
          hap = self.hass.data[HMIPC_DOMAIN][HAPID]
          mock_home.on_update(hap.async_update)
          mock_home.on_create(hap.async_create_entity)
          return hap
  
  
  class HomeTemplate(Home):
      """
      Home template as builder for home mock.
  
      It is based on the upstream libs home class to generate hmip devices
      and groups based on the given homematicip_cloud.json.
  
      All further testing activities should be done by using the AsyncHome mock,
      that is generated by get_async_home_mock(self).
  
      The class also generated mocks of devices and groups for further testing.
      """
  
      _typeClassMap = TYPE_CLASS_MAP
      _typeGroupMap = TYPE_GROUP_MAP
      _typeSecurityEventMap = TYPE_SECURITY_EVENT_MAP
  
      def __init__(self, connection=None, home_name="", test_devices=[], test_groups=[]):
          """Init template with connection."""
          super().__init__(connection=connection)
          self.label = "Access Point"
          self.name = home_name
          self.model_type = "HmIP-HAP"
          self.init_json_state = None
          self.test_devices = test_devices
          self.test_groups = test_groups
  
      def _cleanup_json(self, json):
          if self.test_devices is not None:
              new_devices = {}
              for json_device in json["devices"].items():
                  if json_device[1]["label"] in self.test_devices:
                      new_devices.update([json_device])
              json["devices"] = new_devices
  
          if self.test_groups is not None:
              new_groups = {}
              for json_group in json["groups"].items():
                  if json_group[1]["label"] in self.test_groups:
                      new_groups.update([json_group])
              json["groups"] = new_groups
  
          return json
  
      def init_home(self):
          """Init template with json."""
          self.init_json_state = self._cleanup_json(json.loads(FIXTURE_DATA))
          self.update_home(json_state=self.init_json_state, clearConfig=True)
          return self
  
      def update_home(self, json_state, clearConfig: bool = False):
          """Update home and ensure that mocks are created."""
          result = super().update_home(json_state, clearConfig)
          self._generate_mocks()
          return result
  
      def _generate_mocks(self):
          """Generate mocks for groups and devices."""
          mock_devices = []
          for device in self.devices:
              mock_devices.append(_get_mock(device))
          self.devices = mock_devices
  
          mock_groups = []
          for group in self.groups:
              mock_groups.append(_get_mock(group))
          self.groups = mock_groups
  
      def download_configuration(self):
          """Return the initial json config."""
          return self.init_json_state
  
      def get_async_home_mock(self):
          """
          Create Mock for Async_Home. based on template to be used for testing.
  
          It adds collections of mocked devices and groups to the home objects,
          and sets required attributes.
          """
          mock_home = Mock(
              spec=AsyncHome, wraps=self, label="Access Point", modelType="HmIP-HAP"
          )
          mock_home.__dict__.update(self.__dict__)
  
          return mock_home
  
  
  def _get_mock(instance):
      """Create a mock and copy instance attributes over mock."""
      if isinstance(instance, Mock):
          instance.__dict__.update(
              instance._mock_wraps.__dict__  # pylint: disable=protected-access
          )
          return instance
  
      mock = Mock(spec=instance, wraps=instance)
      mock.__dict__.update(instance.__dict__)
      return mock
  