async def test_zeroconf_device_exists_abort(hass): """Test we abort zeroconf flow if Brother printer already configured.""" with patch( "brother.Brother._get_data", return_value=json.loads( load_fixture("printer_data.json", "brother")), ): MockConfigEntry(domain=DOMAIN, unique_id="0123456789", data=CONFIG).add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="mock_host", addresses=["mock_host"], hostname="example.local.", name="Brother Printer", port=None, properties={}, type="mock_type", ), ) assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["reason"] == "already_configured"
async def test_zeroconf_confirm_connection_error( update_mock: MagicMock, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort zeroconf flow on Modern Forms connection error.""" aioclient_mock.post("http://192.168.1.123:80/mf", exc=aiohttp.ClientError) result = await hass.config_entries.flow.async_init( DOMAIN, context={ "source": SOURCE_ZEROCONF, CONF_HOST: "example.com", CONF_NAME: "test", }, data=zeroconf.ZeroconfServiceInfo( host="192.168.1.123", addresses=["192.168.1.123"], hostname="example.com.", name="mock_name", port=None, properties={}, type="mock_type", ), ) assert result.get("type") == RESULT_TYPE_ABORT assert result.get("reason") == "cannot_connect"
async def test_bridge_homekit(hass, aioclient_mock): """Test a bridge being discovered via HomeKit.""" create_mock_api_discovery(aioclient_mock, [("0.0.0.0", "bla")]) result = await hass.config_entries.flow.async_init( const.DOMAIN, context={"source": config_entries.SOURCE_HOMEKIT}, data=zeroconf.ZeroconfServiceInfo( host="0.0.0.0", addresses=["0.0.0.0"], hostname="mock_hostname", name="mock_name", port=None, properties={zeroconf.ATTR_PROPERTIES_ID: "aa:bb:cc:dd:ee:ff"}, type="mock_type", ), ) assert result["type"] == "form" assert result["step_id"] == "link" flow = next(flow for flow in hass.config_entries.flow.async_progress() if flow["flow_id"] == result["flow_id"]) assert flow["context"][ "unique_id"] == config_entries.DEFAULT_DISCOVERY_UNIQUE_ID
async def test_zeroconf_host_already_configured(hass, tmpdir): """Test starting a flow from discovery when the host is already configured.""" hass.config.config_dir = await hass.async_add_executor_job( tmpdir.mkdir, "tls_assets" ) config_entry = MockConfigEntry(domain=DOMAIN, data={CONF_HOST: "1.1.1.1"}) config_entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="1.1.1.1", hostname="LuTrOn-abc.local.", name="mock_name", port=None, properties={}, type="mock_type", ), ) await hass.async_block_till_done() assert result["type"] == "abort" assert result["reason"] == "already_configured"
async def test_service_info_compatibility(hass, caplog): """Test compatibility with old-style dict. To be removed in 2022.6 """ discovery_info = zeroconf.ZeroconfServiceInfo( host="mock_host", port=None, hostname="mock_hostname", type="mock_type", name="mock_name", properties={}, ) with patch("homeassistant.helpers.frame._REPORTED_INTEGRATIONS", set()): assert discovery_info["host"] == "mock_host" assert "Detected integration that accessed discovery_info['host']" in caplog.text with patch("homeassistant.helpers.frame._REPORTED_INTEGRATIONS", set()): assert discovery_info.get("host") == "mock_host" assert ("Detected integration that accessed discovery_info.get('host')" in caplog.text) assert discovery_info.get("host", "fallback_host") == "mock_host" assert discovery_info.get("invalid_key", "fallback_host") == "fallback_host"
async def test_discovery_connection(hass, mock_auth, mock_entry_setup): """Test a connection via discovery.""" mock_auth.side_effect = lambda hass, host, code: { "host": host, "gateway_id": "bla" } flow = await hass.config_entries.flow.async_init( "tradfri", context={"source": config_entries.SOURCE_HOMEKIT}, data=zeroconf.ZeroconfServiceInfo( host="123.123.123.123", addresses=["123.123.123.123"], hostname="mock_hostname", name="mock_name", port=None, properties={zeroconf.ATTR_PROPERTIES_ID: "homekit-id"}, type="mock_type", ), ) result = await hass.config_entries.flow.async_configure( flow["flow_id"], {"security_code": "abcd"}) assert len(mock_entry_setup.mock_calls) == 1 assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result["result"].unique_id == "homekit-id" assert result["result"].data == { "host": "123.123.123.123", "gateway_id": "bla", }
async def test_step_zeroconf(hass, setup_guardian): """Test the zeroconf step.""" zeroconf_data = zeroconf.ZeroconfServiceInfo( host="192.168.1.100", port=7777, hostname="GVC1-ABCD.local.", type="_api._udp.local.", name="Guardian Valve Controller API._api._udp.local.", properties={"_raw": {}}, ) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, data=zeroconf_data) assert result["type"] == data_entry_flow.RESULT_TYPE_FORM assert result["step_id"] == "discovery_confirm" result = await hass.config_entries.flow.async_configure(result["flow_id"], user_input={}) assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert result["title"] == "ABCDEF123456" assert result["data"] == { CONF_IP_ADDRESS: "192.168.1.100", CONF_PORT: 7777, CONF_UID: "ABCDEF123456", }
async def test_zeroconf_already_configured_no_reload_same_host( hass: core.HomeAssistant, ): """Test starting a flow from zeroconf when already configured does not reload if the host is the same.""" entry = MockConfigEntry( domain=DOMAIN, unique_id="already-registered-bond-id", data={ CONF_HOST: "stored-host", CONF_ACCESS_TOKEN: "correct-token" }, ) entry.add_to_hass(hass) with _patch_async_setup_entry() as mock_setup_entry, patch_bond_token( return_value={"token": "correct-token"}): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="stored-host", addresses=["stored-host"], hostname="mock_hostname", name="already-registered-bond-id.some-other-tail-info", port=None, properties={}, type="mock_type", ), ) await hass.async_block_till_done() assert result["type"] == "abort" assert result["reason"] == "already_configured" assert len(mock_setup_entry.mock_calls) == 0
async def test_step_homekit_zeroconf_ip_change(hass, source): """Test zeroconf with an ip change.""" conf = { CONF_IP_ADDRESS: "192.168.1.100", CONF_PASSWORD: "******", CONF_PORT: 8080, CONF_SSL: True, } entry = MockConfigEntry(domain=DOMAIN, unique_id="aa:bb:cc:dd:ee:ff", data=conf) entry.add_to_hass(hass) with patch( "homeassistant.components.rainmachine.config_flow.Client", return_value=_get_mock_client(), ): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": source}, data=zeroconf.ZeroconfServiceInfo( host="192.168.1.2", hostname="mock_hostname", name="mock_name", port=None, properties={}, type="mock_type", ), ) assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["reason"] == "already_configured" assert entry.data[CONF_IP_ADDRESS] == "192.168.1.2"
async def test_form_zeroconf_ipv4_address(hass): """Test we abort and update the ip address from zeroconf with an ipv4 address.""" config_entry = MockConfigEntry( domain=DOMAIN, unique_id="1CCAE3AAAAAA", data=VALID_CONFIG, options={CONF_EVENTS: ["event1", "event2", "event3"]}, ) config_entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="4.4.4.4", addresses=["4.4.4.4"], hostname="mock_hostname", name="Doorstation - abc123._axis-video._tcp.local.", port=None, properties={"macaddress": "1CCAE3AAAAAA"}, type="mock_type", ), ) assert result["type"] == "abort" assert result["reason"] == "already_configured" assert config_entry.data[CONF_HOST] == "4.4.4.4"
async def test_zeroconf_already_configured(hass: core.HomeAssistant): """Test starting a flow from discovery when already configured.""" entry = MockConfigEntry( domain=DOMAIN, unique_id="already-registered-bond-id", data={ CONF_HOST: "stored-host", CONF_ACCESS_TOKEN: "test-token" }, ) entry.add_to_hass(hass) with _patch_async_setup_entry() as mock_setup_entry: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="updated-host", addresses=["updated-host"], hostname="mock_hostname", name="already-registered-bond-id.some-other-tail-info", port=None, properties={}, type="mock_type", ), ) await hass.async_block_till_done() assert result["type"] == "abort" assert result["reason"] == "already_configured" assert entry.data["host"] == "updated-host" assert len(mock_setup_entry.mock_calls) == 1
async def test_zeroconf_during_onboarding( hass: HomeAssistant, mock_elgato_config_flow: MagicMock, mock_setup_entry: AsyncMock, mock_onboarding: MagicMock, ) -> None: """Test the zeroconf creates an entry during onboarding.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="127.0.0.1", addresses=["127.0.0.1"], hostname="example.local.", name="mock_name", port=9123, properties={"id": "AA:BB:CC:DD:EE:FF"}, type="mock_type", ), ) assert result.get("type") == FlowResultType.CREATE_ENTRY assert result.get("title") == "CN11A1A00001" assert result.get("data") == { CONF_HOST: "127.0.0.1", CONF_MAC: "AA:BB:CC:DD:EE:FF", CONF_PORT: 9123, } assert "result" in result assert result["result"].unique_id == "CN11A1A00001" assert len(mock_setup_entry.mock_calls) == 1 assert len(mock_elgato_config_flow.info.mock_calls) == 1 assert len(mock_onboarding.mock_calls) == 1
async def test_zeroconf_updates_existing_ip(hass): """Test we can setup from zeroconf discovery.""" entry = MockConfigEntry(domain=DOMAIN, data={CONF_IP_ADDRESS: "127.0.0.2"}, unique_id=MOCK_UUID) entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="127.0.0.1", addresses=["127.0.0.1"], hostname="mock_hostname", name="testfan", port=None, properties={ "name": "My Fan", "model": "Haiku", "uuid": MOCK_UUID }, type="mock_type", ), ) assert result["type"] == FlowResultType.ABORT assert result["reason"] == "already_configured" assert entry.data[CONF_IP_ADDRESS] == "127.0.0.1"
async def test_zeroconf_confirm_create_entry(hass): """Test zeroconf confirmation and create config entry.""" with patch( "brother.Brother._get_data", return_value=json.loads( load_fixture("printer_data.json", "brother")), ): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="mock_host", addresses=["mock_host"], hostname="example.local.", name="Brother Printer", port=None, properties={}, type="mock_type", ), ) assert result["step_id"] == "zeroconf_confirm" assert result["description_placeholders"]["model"] == "HL-L2340DW" assert result["description_placeholders"][ "serial_number"] == "0123456789" assert result["type"] == data_entry_flow.RESULT_TYPE_FORM result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={CONF_TYPE: "laser"}) assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert result["title"] == "HL-L2340DW 0123456789" assert result["data"][CONF_HOST] == "example.local" assert result["data"][CONF_TYPE] == "laser"
async def test_discovery_updates_unique_id(hass, mock_client): """Test a duplicate discovery host aborts and updates existing entry.""" entry = MockConfigEntry( domain=DOMAIN, data={CONF_HOST: "192.168.43.183", CONF_PORT: 6053, CONF_PASSWORD: ""}, ) entry.add_to_hass(hass) service_info = zeroconf.ZeroconfServiceInfo( host="192.168.43.183", addresses=["192.168.43.183"], hostname="test8266.local.", name="mock_name", port=6053, properties={"address": "test8266.local"}, type="mock_type", ) result = await hass.config_entries.flow.async_init( "esphome", context={"source": config_entries.SOURCE_ZEROCONF}, data=service_info ) assert result["type"] == RESULT_TYPE_ABORT assert result["reason"] == "already_configured" assert entry.unique_id == "test8266"
async def test_zeroconf_serial_already_exists(hass: HomeAssistant) -> None: """Test serial number already exists from zeroconf.""" config_entry = MockConfigEntry( domain=DOMAIN, data={ "host": "1.1.1.1", "name": "Envoy", "username": "******", "password": "******", }, unique_id="1234", title="Envoy", ) config_entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="1.1.1.1", hostname="mock_hostname", name="mock_name", port=None, properties={"serialnum": "1234"}, type="mock_type", ), ) assert result["type"] == "abort" assert result["reason"] == "already_configured"
async def test_discovery_invalid_api(hass, aioclient_mock): """Test discovery detecting invalid_api.""" service_info = zeroconf.ZeroconfServiceInfo( host="192.168.43.183", addresses=["192.168.43.183"], port=80, hostname="p1meter-ddeeff.local.", type="", name="", properties={ "api_enabled": "1", "path": "/api/not_v1", "product_name": "P1 meter", "product_type": "HWE-P1", "serial": "aabbccddeeff", }, ) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=service_info, ) assert result["type"] == RESULT_TYPE_ABORT assert result["reason"] == "unsupported_api_version"
async def test_import_discovery_integration( hass: HomeAssistant, source: str, type_in_discovery: str, nanoleaf_conf_file: dict[str, dict[str, str]], remove_config: bool, ) -> None: """ Test discovery integration import. Test with different discovery flow sources and corresponding types. Test with different .nanoleaf_conf files with device_id (>= 2021.4), host (< 2021.4) and combination. Test removing the .nanoleaf_conf file if it was the only device in the file. Test updating the .nanoleaf_conf file if it was not the only device in the file. """ with patch( "homeassistant.components.nanoleaf.config_flow.load_json", return_value=dict(nanoleaf_conf_file), ), patch( "homeassistant.components.nanoleaf.config_flow.Nanoleaf", return_value=_mock_nanoleaf(TEST_HOST, TEST_TOKEN), ), patch( "homeassistant.components.nanoleaf.config_flow.save_json", return_value=None, ) as mock_save_json, patch( "homeassistant.components.nanoleaf.config_flow.os.remove", return_value=None, ) as mock_remove, patch( "homeassistant.components.nanoleaf.async_setup_entry", return_value=True, ) as mock_setup_entry: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": source}, data=zeroconf.ZeroconfServiceInfo( host=TEST_HOST, addresses=[TEST_HOST], hostname="mock_hostname", name=f"{TEST_NAME}.{type_in_discovery}", port=None, properties={zeroconf.ATTR_PROPERTIES_ID: TEST_DEVICE_ID}, type=type_in_discovery, ), ) assert result["type"] == "create_entry" assert result["title"] == TEST_NAME assert result["data"] == { CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN, } if remove_config: mock_save_json.assert_not_called() mock_remove.assert_called_once() else: mock_save_json.assert_called_once() mock_remove.assert_not_called() await hass.async_block_till_done() assert len(mock_setup_entry.mock_calls) == 1
async def test_discovery_updates_unique_id(hass): """Test a duplicate discovery host aborts and updates existing entry.""" entry = MockConfigEntry( domain="tradfri", data={"host": "some-host"}, ) entry.add_to_hass(hass) flow = await hass.config_entries.flow.async_init( "tradfri", context={"source": config_entries.SOURCE_HOMEKIT}, data=zeroconf.ZeroconfServiceInfo( host="some-host", addresses=["some-host"], hostname="mock_hostname", name="mock_name", port=None, properties={zeroconf.ATTR_PROPERTIES_ID: "homekit-id"}, type="mock_type", ), ) assert flow["type"] == data_entry_flow.FlowResultType.ABORT assert flow["reason"] == "already_configured" assert entry.unique_id == "homekit-id"
async def test_duplicate_zerconf_ignored(hass: HomeAssistant) -> None: """Test that the duplicate zeroconf isn't shown.""" MockConfigEntry( domain=DOMAIN, data={ "host": "192.168.1.123" }, source=config_entries.SOURCE_IMPORT, unique_id="83747482", ).add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="192.168.1.123", addresses=["192.168.1.123"], hostname="example.local.", name="mock_name", port=80, properties={ "uuid": "83747482", "path": "/foo/" }, type="mock_type", ), ) assert result["type"] == "abort" assert result["reason"] == "already_configured"
async def test_update_address(hass): """Test update address works.""" config_entry = await setup_axis_integration(hass) device = hass.data[AXIS_DOMAIN][config_entry.unique_id] assert device.api.config.host == "1.2.3.4" with patch( "homeassistant.components.axis.async_setup_entry", return_value=True, ) as mock_setup_entry, respx.mock: mock_default_vapix_requests(respx, "2.3.4.5") await hass.config_entries.flow.async_init( AXIS_DOMAIN, data=zeroconf.ZeroconfServiceInfo( host="2.3.4.5", addresses=["2.3.4.5"], hostname="mock_hostname", name="name", port=80, properties={"macaddress": MAC}, type="mock_type", ), context={"source": SOURCE_ZEROCONF}, ) await hass.async_block_till_done() assert device.api.config.host == "2.3.4.5" assert len(mock_setup_entry.mock_calls) == 1
async def test_form_zeroconf_correct_oui_wrong_device(hass, doorbell_state_side_effect): """Test we can setup from zeroconf with the correct OUI source but not a doorstation.""" doorbirdapi = _get_mock_doorbirdapi_return_values( ready=[True], info={"WIFI_MAC_ADDR": "macaddr"} ) type(doorbirdapi).doorbell_state = MagicMock(side_effect=doorbell_state_side_effect) with patch( "homeassistant.components.doorbird.config_flow.DoorBird", return_value=doorbirdapi, ): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="192.168.1.5", addresses=["192.168.1.5"], hostname="mock_hostname", name="Doorstation - abc123._axis-video._tcp.local.", port=None, properties={"macaddress": "1CCAE3DOORBIRD"}, type="mock_type", ), ) await hass.async_block_till_done() assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["reason"] == "not_doorbird_device"
async def test_zeroconf_lutron_id_already_configured(hass): """Test starting a flow from discovery when lutron id already configured.""" config_entry = MockConfigEntry( domain=DOMAIN, data={CONF_HOST: "4.5.6.7"}, unique_id="abc" ) config_entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="1.1.1.1", hostname="LuTrOn-abc.local.", name="mock_name", port=None, properties={}, type="mock_type", ), ) await hass.async_block_till_done() assert result["type"] == "abort" assert result["reason"] == "already_configured" assert config_entry.data[CONF_HOST] == "1.1.1.1"
async def test_discovery_initiation(hass, mock_client, mock_zeroconf): """Test discovery importing works.""" mock_client.device_info = AsyncMock(return_value=MockDeviceInfo(False, "test8266")) service_info = zeroconf.ZeroconfServiceInfo( host="192.168.43.183", addresses=["192.168.43.183"], hostname="test8266.local.", name="mock_name", port=6053, properties={}, type="mock_type", ) flow = await hass.config_entries.flow.async_init( "esphome", context={"source": config_entries.SOURCE_ZEROCONF}, data=service_info ) result = await hass.config_entries.flow.async_configure( flow["flow_id"], user_input={} ) assert result["type"] == RESULT_TYPE_CREATE_ENTRY assert result["title"] == "test8266" assert result["data"][CONF_HOST] == "192.168.43.183" assert result["data"][CONF_PORT] == 6053 assert result["result"] assert result["result"].unique_id == "test8266"
async def test_zeroconf_updates_title(hass, config_entry): """Test that zeroconf updates title and aborts with same host.""" MockConfigEntry(domain=DOMAIN, data={ CONF_HOST: "different host" }).add_to_hass(hass) config_entry.add_to_hass(hass) assert len(hass.config_entries.async_entries(DOMAIN)) == 2 discovery_info = zeroconf.ZeroconfServiceInfo( host="192.168.1.1", addresses=["192.168.1.1"], hostname="mock_hostname", name="mock_name", port=23, properties={ "mtd-version": "27.0", "Machine Name": "zeroconf_test" }, type="mock_type", ) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info) await hass.async_block_till_done() assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert config_entry.title == "zeroconf_test" assert len(hass.config_entries.async_entries(DOMAIN)) == 2
async def test_discovery_already_configured_name(hass, mock_client): """Test discovery aborts if already configured via name.""" entry = MockConfigEntry( domain=DOMAIN, data={CONF_HOST: "192.168.43.183", CONF_PORT: 6053, CONF_PASSWORD: ""}, ) entry.add_to_hass(hass) mock_entry_data = MagicMock() mock_entry_data.device_info.name = "test8266" domain_data = DomainData.get(hass) domain_data.set_entry_data(entry, mock_entry_data) service_info = zeroconf.ZeroconfServiceInfo( host="192.168.43.184", addresses=["192.168.43.184"], hostname="test8266.local.", name="mock_name", port=6053, properties={"address": "test8266.local"}, type="mock_type", ) result = await hass.config_entries.flow.async_init( "esphome", context={"source": config_entries.SOURCE_ZEROCONF}, data=service_info ) assert result["type"] == RESULT_TYPE_ABORT assert result["reason"] == "already_configured" assert entry.unique_id == "test8266" assert entry.data[CONF_HOST] == "192.168.43.184"
async def test_zeroconf_with_mac_device_exists_abort( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test we abort zeroconf flow if a Modern Forms device already configured.""" await init_integration(hass, aioclient_mock, skip_setup=True) await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, data={ "host": "192.168.1.123", "hostname": "example.local.", "properties": {CONF_MAC: "AA:BB:CC:DD:EE:FF"}, }, ) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="192.168.1.123", addresses=["192.168.1.123"], hostname="example.local.", name="mock_name", port=None, properties={CONF_MAC: "AA:BB:CC:DD:EE:FF"}, type="mock_type", ), ) assert result.get("type") == RESULT_TYPE_ABORT assert result.get("reason") == "already_configured"
async def test_discovery_duplicate_data(hass, mock_client): """Test discovery aborts if same mDNS packet arrives.""" service_info = zeroconf.ZeroconfServiceInfo( host="192.168.43.183", addresses=["192.168.43.183"], hostname="test8266.local.", name="mock_name", port=6053, properties={"address": "test8266.local"}, type="mock_type", ) mock_client.device_info = AsyncMock(return_value=MockDeviceInfo(False, "test8266")) result = await hass.config_entries.flow.async_init( "esphome", data=service_info, context={"source": config_entries.SOURCE_ZEROCONF} ) assert result["type"] == RESULT_TYPE_FORM assert result["step_id"] == "discovery_confirm" result = await hass.config_entries.flow.async_init( "esphome", data=service_info, context={"source": config_entries.SOURCE_ZEROCONF} ) assert result["type"] == RESULT_TYPE_ABORT assert result["reason"] == "already_in_progress"
async def test_bridge_homekit_already_configured(hass, aioclient_mock): """Test if a HomeKit discovered bridge has already been configured.""" create_mock_api_discovery(aioclient_mock, [("0.0.0.0", "aabbccddeeff")]) MockConfigEntry(domain="hue", unique_id="aabbccddeeff", data={ "host": "0.0.0.0" }).add_to_hass(hass) result = await hass.config_entries.flow.async_init( const.DOMAIN, context={"source": config_entries.SOURCE_HOMEKIT}, data=zeroconf.ZeroconfServiceInfo( host="0.0.0.0", addresses=["0.0.0.0"], hostname="mock_hostname", name="mock_name", port=None, properties={zeroconf.ATTR_PROPERTIES_ID: "aa:bb:cc:dd:ee:ff"}, type="mock_type", ), ) assert result["type"] == "abort" assert result["reason"] == "already_configured"
def get_device_discovery_info( device, upper_case_props=False, missing_csharp=False) -> zeroconf.ZeroconfServiceInfo: """Turn a aiohomekit format zeroconf entry into a homeassistant one.""" result = zeroconf.ZeroconfServiceInfo( host="127.0.0.1", hostname=device.description.name, name=device.description.name, addresses=["127.0.0.1"], port=8080, properties={ "md": device.description.model, "pv": "1.0", zeroconf.ATTR_PROPERTIES_ID: device.description.id, "c#": device.description.config_num, "s#": device.description.state_num, "ff": "0", "ci": "0", "sf": "1", "sh": "", }, type="_hap._tcp.local.", ) if missing_csharp: del result.properties["c#"] if upper_case_props: result.properties = { key.upper(): val for (key, val) in result.properties.items() } return result