async def test_onboarding_user_already_done(hass, hass_storage, aiohttp_client): """Test creating a new user when user step already done.""" mock_storage(hass_storage, {"done": [views.STEP_USER]}) with patch.object(onboarding, "STEPS", ["hello", "world"]): assert await async_setup_component(hass, "onboarding", {}) await hass.async_block_till_done() client = await aiohttp_client(hass.http.app) resp = await client.post( "/api/onboarding/users", json={ "client_id": CLIENT_ID, "name": "Test Name", "username": "******", "password": "******", "language": "en", }, ) assert resp.status == HTTP_FORBIDDEN
def test_recorder_setup_failure(): """Test some exceptions.""" hass = get_test_home_assistant() with patch.object(Recorder, "_setup_connection") as setup, patch( "homeassistant.components.recorder.time.sleep"): setup.side_effect = ImportError("driver not found") rec = Recorder( hass, auto_purge=True, keep_days=7, commit_interval=1, uri="sqlite://", db_max_retries=10, db_retry_wait=3, entity_filter=CONFIG_SCHEMA({DOMAIN: {}}), exclude_t=[], db_integrity_check=False, ) rec.start() rec.join() hass.stop()
async def test_invalid_for_template(hass, calls): """Test for invalid for template.""" assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: { "trigger": { "platform": "numeric_state", "entity_id": "test.entity", "above": 8, "below": 12, "for": "{{ five }}", }, "action": {"service": "test.automation"}, } }, ) with patch.object(numeric_state_trigger, "_LOGGER") as mock_logger: hass.states.async_set("test.entity", 9) await hass.async_block_till_done() assert mock_logger.error.called
async def test_if_fails_setup_bad_for(hass, calls): """Test for setup failure for bad for.""" assert await async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: { "trigger": { "platform": "numeric_state", "entity_id": "test.entity", "above": 8, "below": 12, "for": {"invalid": 5}, }, "action": {"service": "homeassistant.turn_on"}, } }, ) with patch.object(numeric_state_trigger, "_LOGGER") as mock_logger: hass.states.async_set("test.entity", 9) await hass.async_block_till_done() assert mock_logger.error.called
async def test_unload_entry(hass): """Test being able to unload an entry.""" host = "1.2.3.4" entry = MockConfigEntry(domain=dynalite.DOMAIN, data={CONF_HOST: host}) entry.add_to_hass(hass) with patch( "homeassistant.components.dynalite.bridge.DynaliteDevices.async_setup", return_value=True, ): assert await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() assert len(hass.config_entries.async_entries(dynalite.DOMAIN)) == 1 with patch.object(hass.config_entries, "async_forward_entry_unload", return_value=True) as mock_unload: assert await hass.config_entries.async_unload(entry.entry_id) await hass.async_block_till_done() assert mock_unload.call_count == len(dynalite.ENTITY_PLATFORMS) expected_calls = [ call(entry, platform) for platform in dynalite.ENTITY_PLATFORMS ] for cur_call in mock_unload.mock_calls: assert cur_call in expected_calls
async def test_alexa_config_report_state(hass, cloud_prefs): """Test Alexa config should expose using prefs.""" conf = alexa_config.AlexaConfig(hass, ALEXA_SCHEMA({}), cloud_prefs, None) assert cloud_prefs.alexa_report_state is False assert conf.should_report_state is False assert conf.is_reporting_states is False with patch.object(conf, "async_get_access_token", AsyncMock(return_value="hello")): await cloud_prefs.async_update(alexa_report_state=True) await hass.async_block_till_done() assert cloud_prefs.alexa_report_state is True assert conf.should_report_state is True assert conf.is_reporting_states is True await cloud_prefs.async_update(alexa_report_state=False) await hass.async_block_till_done() assert cloud_prefs.alexa_report_state is False assert conf.should_report_state is False assert conf.is_reporting_states is False
async def test_pair_abort_errors_on_finish(hass, controller, exception, expected): """Test various pairing errors.""" device = setup_mock_accessory(controller) discovery_info = get_device_discovery_info(device) # Device is discovered result = await hass.config_entries.flow.async_init( "homekit_controller", context={"source": "zeroconf"}, data=discovery_info ) assert get_flow_context(hass, result) == { "hkid": "00:00:00:00:00:00", "title_placeholders": {"name": "TestDevice"}, "unique_id": "00:00:00:00:00:00", "source": "zeroconf", } # User initiates pairing - this triggers the device to show a pairing code # and then HA to show a pairing form finish_pairing = tests.async_mock.AsyncMock(side_effect=exception("error")) with patch.object(device, "start_pairing", return_value=finish_pairing): result = await hass.config_entries.flow.async_configure(result["flow_id"]) assert result["type"] == "form" assert get_flow_context(hass, result) == { "hkid": "00:00:00:00:00:00", "title_placeholders": {"name": "TestDevice"}, "unique_id": "00:00:00:00:00:00", "source": "zeroconf", } # User enters pairing code result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={"pairing_code": "111-22-333"} ) assert result["type"] == "abort" assert result["reason"] == expected
async def test_setup_defined_hosts_known_auth(hass): """Test we don't initiate a config entry if config bridge is known.""" MockConfigEntry(domain="hue", data={"host": "0.0.0.0"}).add_to_hass(hass) with patch.object(hue, "async_setup_entry", return_value=mock_coro(True)): assert ( await async_setup_component( hass, hue.DOMAIN, { hue.DOMAIN: { hue.CONF_BRIDGES: [ { hue.CONF_HOST: "0.0.0.0", hue.CONF_ALLOW_HUE_GROUPS: False, hue.CONF_ALLOW_UNREACHABLE: True, }, {hue.CONF_HOST: "1.1.1.1"}, ] } }, ) is True ) # Flow started for discovered bridge assert len(hass.config_entries.flow.async_progress()) == 1 # Config stored for domain. assert hass.data[hue.DATA_CONFIGS] == { "0.0.0.0": { hue.CONF_HOST: "0.0.0.0", hue.CONF_ALLOW_HUE_GROUPS: False, hue.CONF_ALLOW_UNREACHABLE: True, }, "1.1.1.1": {hue.CONF_HOST: "1.1.1.1"}, }
async def test_set_temperature_wrong_mode(hass, device_climate_mock): """Test setting temperature service call for wrong HVAC mode.""" with patch.object( zigpy.zcl.clusters.manufacturer_specific.ManufacturerSpecificCluster, "ep_attribute", "sinope_manufacturer_specific", ): device_climate = await device_climate_mock( CLIMATE_SINOPE, { "occupied_cooling_setpoint": 2500, "occupied_heating_setpoint": 2000, "system_mode": Thermostat.SystemMode.Dry, "unoccupied_cooling_setpoint": 1600, "unoccupied_heating_setpoint": 2700, }, manuf=SINOPE, ) entity_id = await find_entity_id(DOMAIN, device_climate, hass) thrm_cluster = device_climate.device.endpoints[1].thermostat state = hass.states.get(entity_id) assert state.state == HVAC_MODE_DRY await hass.services.async_call( DOMAIN, SERVICE_SET_TEMPERATURE, {ATTR_ENTITY_ID: entity_id, ATTR_TEMPERATURE: 24}, blocking=True, ) state = hass.states.get(entity_id) assert state.attributes[ATTR_TARGET_TEMP_LOW] is None assert state.attributes[ATTR_TARGET_TEMP_HIGH] is None assert state.attributes[ATTR_TEMPERATURE] is None assert thrm_cluster.write_attributes.await_count == 0
async def test_hue_activate_scene(hass, mock_api): """Test successful hue_activate_scene.""" config_entry = config_entries.ConfigEntry( 1, hue.DOMAIN, "Mock Title", { "host": "mock-host", "username": "******" }, "test", config_entries.CONN_CLASS_LOCAL_POLL, system_options={}, options={ CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False }, ) hue_bridge = bridge.HueBridge(hass, config_entry) mock_api.mock_group_responses.append(GROUP_RESPONSE) mock_api.mock_scene_responses.append(SCENE_RESPONSE) with patch("aiohue.Bridge", return_value=mock_api), patch.object( hass.config_entries, "async_forward_entry_setup"): assert await hue_bridge.async_setup() is True assert hue_bridge.api is mock_api call = Mock() call.data = {"group_name": "Group 1", "scene_name": "Cozy dinner"} with patch("aiohue.Bridge", return_value=mock_api): assert await hue_bridge.hue_activate_scene(call) is None assert len(mock_api.mock_requests) == 3 assert mock_api.mock_requests[2]["json"]["scene"] == "scene_1" assert mock_api.mock_requests[2]["path"] == "groups/group_1/action"
async def test_reload(hass): """Test we can reload.""" assert await async_setup_component( hass, DOMAIN, { "climate": { "platform": "generic_thermostat", "name": "test", "heater": "switch.any", "target_sensor": "sensor.any", } }, ) await hass.async_block_till_done() assert len(hass.states.async_all()) == 1 assert hass.states.get("climate.test") is not None yaml_path = path.join( _get_fixtures_base_path(), "fixtures", "generic_thermostat/configuration.yaml", ) with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path): await hass.services.async_call( GENERIC_THERMOSTAT_DOMAIN, SERVICE_RELOAD, {}, blocking=True, ) await hass.async_block_till_done() assert len(hass.states.async_all()) == 1 assert hass.states.get("climate.test") is None assert hass.states.get("climate.reload")
async def test_max_queue_message(loop, ws_server): """Test that we connect if we are not connected.""" server_msgs = [] async def handle_server_msg(msg): """handle a server msg.""" incoming = msg.json() server_msgs.append(incoming["payload"]) return { "msgid": incoming["msgid"], "payload": incoming["payload"]["hello"] } grs = await create_grs(loop, ws_server, handle_server_msg) # Test we can handle sending more messages than queue fits with patch.object(grs, "_async_message_sender"): gather_task = asyncio.gather( *[grs.async_send_message({"hello": i}) for i in range(150)], return_exceptions=True, ) # One per message for i in range(150): await asyncio.sleep(0) # Start handling messages. await grs._async_on_connect() # One per message for i in range(150): await asyncio.sleep(0) assert len(server_msgs) == 100 results = await gather_task assert len(results) == 150 assert sum(isinstance(result, ErrorResponse) for result in results) == 50
async def test_flow_entry_created_from_user_input(): """Test that create data from user input. Test when the form should show when no configurations exists """ hass = Mock() flow = config_flow.IpmaFlowHandler() flow.hass = hass test_data = {"name": "home", CONF_LONGITUDE: "0", CONF_LATITUDE: "0"} # Test that entry created when user_input name not exists with patch( "homeassistant.components.ipma.config_flow.IpmaFlowHandler._show_config_form" ) as config_form, patch.object( flow.hass.config_entries, "async_entries", return_value=[], ) as config_entries: result = await flow.async_step_user(user_input=test_data) assert result["type"] == "create_entry" assert result["data"] == test_data assert len(config_entries.mock_calls) == 1 assert not config_form.mock_calls
async def test_file_value_template(hass, entity_reg): """Test the File sensor with JSON entries.""" config = { "sensor": { "platform": "file", "name": "file2", "file_path": "mock.file2", "value_template": "{{ value_json.temperature }}", } } data = '{"temperature": 29, "humidity": 31}\n' '{"temperature": 26, "humidity": 36}' m_open = mock_open(read_data=data) with patch("homeassistant.components.file.sensor.open", m_open, create=True), patch.object(hass.config, "is_allowed_path", return_value=True): assert await async_setup_component(hass, "sensor", config) await hass.async_block_till_done() state = hass.states.get("sensor.file2") assert state.state == "26"
async def test_node_by_samba_no_history_files(): """Test the Node/Pro not having any history files where expected.""" # Mock the tempfile that current measurements get loaded into: measurements_response = load_fixture("node_measurements_samba_list_response.json") mock_measurements_tmp_file = MagicMock() mock_measurements_tmp_file.read.return_value = measurements_response.encode() # Mock the history file that SMBConnection returns: mock_history_tmp_file = MagicMock() with patch.object( tempfile, "NamedTemporaryFile", side_effect=[mock_measurements_tmp_file, mock_history_tmp_file], ), patch("smb.SMBConnection.SMBConnection.connect"), patch( "smb.SMBConnection.SMBConnection.retrieveFile", ), patch( "smb.SMBConnection.SMBConnection.listPath", return_value=[] ), patch( "smb.SMBConnection.SMBConnection.close" ): with pytest.raises(NodeProError): async with NodeSamba(TEST_NODE_IP_ADDRESS, TEST_NODE_PASSWORD) as node: await node.async_get_history()
async def test_network_error_during_refresh(hass, caplog): """Test network failures during refreshes.""" entry = MockConfigEntry( domain=DOMAIN, data=DEFAULT_DATA, options=DEFAULT_OPTIONS, unique_id=DEFAULT_DATA["server_id"], ) mock_plex_server = MockPlexServer() with patch("plexapi.server.PlexServer", return_value=mock_plex_server), patch( "plexapi.myplex.MyPlexAccount", return_value=MockPlexAccount() ), patch( "homeassistant.components.plex.PlexWebsocket", autospec=True ) as mock_websocket: entry.add_to_hass(hass) assert await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() server_id = mock_plex_server.machineIdentifier loaded_server = hass.data[DOMAIN][SERVERS][server_id] trigger_plex_update(mock_websocket) await hass.async_block_till_done() sensor = hass.states.get("sensor.plex_plex_server_1") assert sensor.state == str(len(mock_plex_server.accounts)) with patch.object(mock_plex_server, "clients", side_effect=RequestException): await loaded_server._async_update_platforms() await hass.async_block_till_done() assert ( f"Could not connect to Plex server: {DEFAULT_DATA[CONF_SERVER]}" in caplog.text )
async def test_hap_setup_works(): """Test a successful setup of a accesspoint.""" hass = Mock() entry = Mock() home = Mock() entry.data = { HMIPC_HAPID: "ABC123", HMIPC_AUTHTOKEN: "123", HMIPC_NAME: "hmip" } hap = HomematicipHAP(hass, entry) with patch.object(hap, "get_hap", return_value=home): assert await hap.async_setup() assert hap.home is home assert len(hass.config_entries.async_forward_entry_setup.mock_calls) == 8 assert hass.config_entries.async_forward_entry_setup.mock_calls[0][1] == ( entry, "alarm_control_panel", ) assert hass.config_entries.async_forward_entry_setup.mock_calls[1][1] == ( entry, "binary_sensor", )
async def test_scenes(hass): """Test that scenes works.""" data = deepcopy(DECONZ_WEB_REQUEST) data["groups"] = deepcopy(GROUPS) gateway = await setup_deconz_integration(hass, get_state_response=data) assert "scene.light_group_scene" in gateway.deconz_ids assert len(hass.states.async_all()) == 1 light_group_scene = hass.states.get("scene.light_group_scene") assert light_group_scene group_scene = gateway.api.groups["1"].scenes["1"] with patch.object(group_scene, "_request", return_value=True) as set_callback: await hass.services.async_call( "scene", "turn_on", {"entity_id": "scene.light_group_scene"}, blocking=True ) await hass.async_block_till_done() set_callback.assert_called_with("put", "/groups/1/scenes/1/recall", json={}) await gateway.async_reset() assert len(hass.states.async_all()) == 0
async def test_empty_update(hass): """Test updating with no state from monoprice.""" monoprice = MockMonoprice() await _setup_monoprice(hass, monoprice) # Changing media player to new state await _call_media_player_service( hass, SERVICE_VOLUME_SET, {"entity_id": ZONE_1_ID, "volume_level": 0.0} ) await _call_media_player_service( hass, SERVICE_SELECT_SOURCE, {"entity_id": ZONE_1_ID, "source": "one"} ) monoprice.set_source(11, 3) monoprice.set_volume(11, 38) with patch.object(MockMonoprice, "zone_status", return_value=None): await async_update_entity(hass, ZONE_1_ID) await hass.async_block_till_done() state = hass.states.get(ZONE_1_ID) assert state.attributes[ATTR_MEDIA_VOLUME_LEVEL] == 0.0 assert state.attributes[ATTR_INPUT_SOURCE] == "one"
def test_saving_state_with_exception(hass, hass_recorder, caplog): """Test saving and restoring a state.""" hass = hass_recorder() entity_id = "test.recorder" state = "restoring_from_db" attributes = {"test_attr": 5, "test_attr_10": "nice"} def _throw_if_state_in_session(*args, **kwargs): for obj in hass.data[DATA_INSTANCE].event_session: if isinstance(obj, States): raise OperationalError( "insert the state", "fake params", "forced to fail" ) with patch("time.sleep"), patch.object( hass.data[DATA_INSTANCE].event_session, "flush", side_effect=_throw_if_state_in_session, ): hass.states.set(entity_id, "fail", attributes) wait_recording_done(hass) assert "Error executing query" in caplog.text assert "Error saving events" not in caplog.text caplog.clear() hass.states.set(entity_id, state, attributes) wait_recording_done(hass) with session_scope(hass=hass) as session: db_states = list(session.query(States)) assert len(db_states) >= 1 assert "Error executing query" not in caplog.text assert "Error saving events" not in caplog.text
async def test_bad_hostname(hass): """Test when an invalid address is provided.""" mock_plex_account = MockPlexAccount() await async_process_ha_core_config( hass, {"internal_url": "http://example.local:8123"}, ) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": "user"} ) assert result["type"] == "form" assert result["step_id"] == "user" with patch( "plexapi.myplex.MyPlexAccount", return_value=mock_plex_account ), patch.object( MockResource, "connect", side_effect=requests.exceptions.ConnectionError ), patch( "plexauth.PlexAuth.initiate_auth" ), patch( "plexauth.PlexAuth.token", return_value=MOCK_TOKEN ): result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={} ) assert result["type"] == "external" result = await hass.config_entries.flow.async_configure(result["flow_id"]) assert result["type"] == "external_done" result = await hass.config_entries.flow.async_configure(result["flow_id"]) assert result["type"] == "form" assert result["step_id"] == "user" assert result["errors"][CONF_HOST] == "not_found"
async def test_reload_notify(hass): """Verify we can reload the notify service.""" assert await async_setup_component( hass, notify.DOMAIN, { notify.DOMAIN: [ { "name": DOMAIN, "platform": DOMAIN, "resource": "http://127.0.0.1/off", }, ] }, ) await hass.async_block_till_done() assert hass.services.has_service(notify.DOMAIN, DOMAIN) yaml_path = path.join( _get_fixtures_base_path(), "fixtures", "rest/configuration.yaml", ) with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path): await hass.services.async_call( DOMAIN, SERVICE_RELOAD, {}, blocking=True, ) await hass.async_block_till_done() assert not hass.services.has_service(notify.DOMAIN, DOMAIN) assert hass.services.has_service(notify.DOMAIN, "rest_reloaded")
async def test_flow_entry_config_entry_already_exists(): """Test that create data from user input and config_entry already exists. Test when the form should show when user puts existing name in the config gui. Then the form should show with error """ hass = Mock() flow = config_flow.IpmaFlowHandler() flow.hass = hass test_data = {"name": "home", CONF_LONGITUDE: "0", CONF_LATITUDE: "0"} # Test that entry created when user_input name not exists with patch( "homeassistant.components.ipma.config_flow.IpmaFlowHandler._show_config_form" ) as config_form, patch.object( flow.hass.config_entries, "async_entries", return_value={"home": test_data} ) as config_entries: await flow.async_step_user(user_input=test_data) assert len(config_form.mock_calls) == 1 assert len(config_entries.mock_calls) == 1 assert len(flow._errors) == 1
async def test_lock_get_usercode_service(hass, mock_openzwave): """Test the zwave lock get_usercode service.""" mock_network = hass.data[const.DATA_NETWORK] = MagicMock() node = MockNode(node_id=12) value0 = MockValue(data=None, node=node, index=0) value1 = MockValue(data="1234", node=node, index=1) node.get_values.return_value = {value0.value_id: value0, value1.value_id: value1} await setup_ozw(hass, mock_openzwave) await hass.async_block_till_done() with patch.object(lock, "_LOGGER") as mock_logger: mock_network.nodes = {node.node_id: node} await hass.services.async_call( lock.DOMAIN, lock.SERVICE_GET_USERCODE, {const.ATTR_NODE_ID: node.node_id, lock.ATTR_CODE_SLOT: 1}, ) await hass.async_block_till_done() # This service only seems to write to the log assert mock_logger.info.called assert len(mock_logger.info.mock_calls) == 1 assert mock_logger.info.mock_calls[0][1][2] == "1234"
async def test_flow_show_form() -> None: """Test show form scenarios first time. Test when the form should show when no configurations exists """ hass = Mock() flow = config_flow.SmhiFlowHandler() flow.hass = hass # Test show form when Home Assistant config exists and # home is already configured, then new config is allowed with patch.object(flow, "_show_config_form", return_value=None) as config_form, patch.object( flow, "_homeassistant_location_exists", return_value=True), patch.object( config_flow, "smhi_locations", return_value={ "test": "something", "name_exist": "config" }, ): await flow.async_step_user() assert len(config_form.mock_calls) == 1 # Test show form when Home Assistant config not and # home is not configured with patch.object(flow, "_show_config_form", return_value=None) as config_form, patch.object( flow, "_homeassistant_location_exists", return_value=False), patch.object( config_flow, "smhi_locations", return_value={ "test": "something", "name_exist": "config" }, ): await flow.async_step_user() assert len(config_form.mock_calls) == 1
async def test_flow_entry_created_user_input_faulty() -> None: """Test that create data from user input and are faulty. Test when the form should show when user puts faulty location in the config gui. Then the form should show with error """ hass = Mock() flow = config_flow.SmhiFlowHandler() flow.hass = hass test_data = {"name": "home", CONF_LONGITUDE: "0", CONF_LATITUDE: "0"} # Test that entry created when user_input name not exists with patch.object(flow, "_check_location", return_value=True), patch.object( flow, "_show_config_form", return_value=None) as config_form, patch.object( flow, "_name_in_configuration_exists", return_value=False), patch.object( flow, "_homeassistant_location_exists", return_value=False), patch.object( config_flow, "smhi_locations", return_value={ "test": "something", "name_exist": "config" }, ), patch.object(flow, "_check_location", return_value=False): await flow.async_step_user(user_input=test_data) assert len(config_form.mock_calls) == 1 assert len(flow._errors) == 1
def test_create_triggers_save(hass, registry): """Test that registering entry triggers a save.""" with patch.object(registry, "async_schedule_save") as mock_schedule_save: registry.async_get_or_create("light", "hue", "1234") assert len(mock_schedule_save.mock_calls) == 1
async def test_homekit_ignored_missing_devices( hass, hk_driver, debounce_patcher, device_reg, entity_reg ): """Test HomeKit handles a device in the entity registry but missing from the device registry.""" entry = await async_init_integration(hass) homekit = HomeKit( hass, None, None, None, {}, {"light.demo": {}}, DEFAULT_SAFE_MODE, advertise_ip=None, entry_id=entry.entry_id, ) homekit.driver = hk_driver # pylint: disable=protected-access homekit._filter = Mock(return_value=True) homekit.bridge = HomeBridge(hass, hk_driver, "mock_bridge") config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_hass(hass) device_entry = device_reg.async_get_or_create( config_entry_id=config_entry.entry_id, sw_version="0.16.0", model="Powerwall 2", manufacturer="Tesla", connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create( "binary_sensor", "powerwall", "battery_charging", device_id=device_entry.id, device_class=DEVICE_CLASS_BATTERY_CHARGING, ) entity_reg.async_get_or_create( "sensor", "powerwall", "battery", device_id=device_entry.id, device_class=DEVICE_CLASS_BATTERY, ) light = entity_reg.async_get_or_create( "light", "powerwall", "demo", device_id=device_entry.id ) # Delete the device to make sure we fallback # to using the platform device_reg.async_remove_device(device_entry.id) hass.states.async_set(light.entity_id, STATE_ON) def _mock_get_accessory(*args, **kwargs): return [None, "acc", None] with patch.object(homekit.bridge, "add_accessory"), patch( f"{PATH_HOMEKIT}.show_setup_message" ), patch(f"{PATH_HOMEKIT}.get_accessory") as mock_get_acc, patch( "pyhap.accessory_driver.AccessoryDriver.start" ): await homekit.async_start() await hass.async_block_till_done() mock_get_acc.assert_called_with( hass, hk_driver, ANY, ANY, { "platform": "Tesla Powerwall", "linked_battery_charging_sensor": "binary_sensor.powerwall_battery_charging", "linked_battery_sensor": "sensor.powerwall_battery", }, )
async def test_homekit_finds_linked_motion_sensors( hass, hk_driver, debounce_patcher, device_reg, entity_reg ): """Test HomeKit start method.""" entry = await async_init_integration(hass) homekit = HomeKit( hass, None, None, None, {}, {"camera.camera_demo": {}}, DEFAULT_SAFE_MODE, advertise_ip=None, entry_id=entry.entry_id, ) homekit.driver = hk_driver # pylint: disable=protected-access homekit._filter = Mock(return_value=True) homekit.bridge = HomeBridge(hass, hk_driver, "mock_bridge") config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_hass(hass) device_entry = device_reg.async_get_or_create( config_entry_id=config_entry.entry_id, sw_version="0.16.0", model="Camera Server", manufacturer="Ubq", connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) binary_motion_sensor = entity_reg.async_get_or_create( "binary_sensor", "camera", "motion_sensor", device_id=device_entry.id, device_class=DEVICE_CLASS_MOTION, ) camera = entity_reg.async_get_or_create( "camera", "camera", "demo", device_id=device_entry.id ) hass.states.async_set( binary_motion_sensor.entity_id, STATE_ON, {ATTR_DEVICE_CLASS: DEVICE_CLASS_MOTION}, ) hass.states.async_set(camera.entity_id, STATE_ON) def _mock_get_accessory(*args, **kwargs): return [None, "acc", None] with patch.object(homekit.bridge, "add_accessory"), patch( f"{PATH_HOMEKIT}.show_setup_message" ), patch(f"{PATH_HOMEKIT}.get_accessory") as mock_get_acc, patch( "pyhap.accessory_driver.AccessoryDriver.start" ): await homekit.async_start() await hass.async_block_till_done() mock_get_acc.assert_called_with( hass, hk_driver, ANY, ANY, { "manufacturer": "Ubq", "model": "Camera Server", "sw_version": "0.16.0", "linked_motion_sensor": "binary_sensor.camera_motion_sensor", }, )
async def test_neighbors(tmpdir): """Test neighbor loading.""" ext_pid = t.EUI64.convert("aa:bb:cc:dd:ee:ff:01:02") ieee_1 = make_ieee(1) nwk_1 = 0x1111 nei_1 = zdo_t.Neighbor(ext_pid, ieee_1, nwk_1, 2, 1, 1, 0, 0, 0, 15, 250) ieee_2 = make_ieee(2) nwk_2 = 0x2222 nei_2 = zdo_t.Neighbor(ext_pid, ieee_2, nwk_2, 1, 1, 2, 0, 0, 0, 15, 250) ieee_3 = make_ieee(3) nwk_3 = 0x3333 nei_3 = zdo_t.Neighbor(ext_pid, ieee_3, nwk_3, 1, 1, 2, 0, 0, 0, 15, 250) db = os.path.join(str(tmpdir), "test.db") app = await make_app(db) app.handle_join(nwk_1, ieee_1, 0) dev_1 = app.get_device(ieee_1) dev_1.node_desc = zdo_t.NodeDescriptor(2, 64, 128, 4174, 82, 82, 0, 82, 0) ep1 = dev_1.add_endpoint(1) ep1.status = zigpy.endpoint.Status.ZDO_INIT ep1.profile_id = 260 ep1.device_type = 0x1234 app.device_initialized(dev_1) # 2nd device app.handle_join(nwk_2, ieee_2, 0) dev_2 = app.get_device(ieee_2) dev_2.node_desc = zdo_t.NodeDescriptor(1, 64, 142, 4476, 82, 82, 0, 82, 0) ep2 = dev_2.add_endpoint(1) ep2.status = zigpy.endpoint.Status.ZDO_INIT ep2.profile_id = 260 ep2.device_type = 0x1234 app.device_initialized(dev_2) neighbors = zdo_t.Neighbors(2, 0, [nei_2, nei_3]) p1 = patch.object( dev_1.zdo, "request", new=AsyncMock(return_value=(zdo_t.Status.SUCCESS, neighbors)), ) with p1: res = await dev_1.neighbors.scan() assert res neighbors = zdo_t.Neighbors(2, 0, [nei_1, nei_3]) p1 = patch.object( dev_2.zdo, "request", new=AsyncMock(return_value=(zdo_t.Status.SUCCESS, neighbors)), ) with p1: res = await dev_2.neighbors.scan() assert res await app.pre_shutdown() del dev_1, dev_2 # Everything should've been saved - check that it re-loads app2 = await make_app(db) dev_1 = app2.get_device(ieee_1) dev_2 = app2.get_device(ieee_2) assert len(dev_1.neighbors) == 2 assert dev_1.neighbors[0].device is dev_2 assert dev_1.neighbors[1].device is None assert dev_1.neighbors[1].neighbor.ieee == ieee_3 assert len(dev_2.neighbors.neighbors) == 2 assert dev_2.neighbors[0].device is dev_1 assert dev_2.neighbors[1].device is None assert dev_2.neighbors[1].neighbor.ieee == ieee_3 await app2.pre_shutdown() os.unlink(db)