Exemplo n.º 1
0
async def test_ssdp_byebye(
    hass: HomeAssistant,
    ssdp_scanner_mock: Mock,
    connected_source_mock: DmsDeviceSource,
) -> None:
    """Test device is disconnected when byebye is received."""
    # First byebye will cause a disconnect
    ssdp_callback = ssdp_scanner_mock.async_register_callback.call_args.args[0]
    await ssdp_callback(
        ssdp.SsdpServiceInfo(
            ssdp_usn=MOCK_DEVICE_USN,
            ssdp_udn=MOCK_DEVICE_UDN,
            ssdp_headers={"NTS": "ssdp:byebye"},
            ssdp_st=MOCK_DEVICE_TYPE,
            upnp={},
        ),
        ssdp.SsdpChange.BYEBYE,
    )

    # Device should be gone
    assert not connected_source_mock.available

    # Second byebye will do nothing
    await ssdp_callback(
        ssdp.SsdpServiceInfo(
            ssdp_usn=MOCK_DEVICE_USN,
            ssdp_udn=MOCK_DEVICE_UDN,
            ssdp_headers={"NTS": "ssdp:byebye"},
            ssdp_st=MOCK_DEVICE_TYPE,
            upnp={},
        ),
        ssdp.SsdpChange.BYEBYE,
    )
async def test_multiple_ssdp_alive(
    hass: HomeAssistant,
    upnp_factory_mock: Mock,
    ssdp_scanner_mock: Mock,
    disconnected_source_mock: None,
) -> None:
    """Test multiple SSDP alive notifications is ok, only connects to device once."""
    upnp_factory_mock.async_create_device.reset_mock()

    # Contacting the device takes long enough that 2 simultaneous attempts could be made
    async def create_device_delayed(_location):
        """Delay before continuing with async_create_device.

        This gives a chance for parallel calls to `device_connect` to occur.
        """
        await asyncio.sleep(0.1)
        return DEFAULT

    upnp_factory_mock.async_create_device.side_effect = create_device_delayed

    # Send two SSDP notifications with the new device URL
    ssdp_callback = ssdp_scanner_mock.async_register_callback.call_args.args[0]
    await ssdp_callback(
        ssdp.SsdpServiceInfo(
            ssdp_usn=MOCK_DEVICE_USN,
            ssdp_location=NEW_DEVICE_LOCATION,
            ssdp_st=MOCK_DEVICE_TYPE,
            upnp={},
        ),
        ssdp.SsdpChange.ALIVE,
    )
    await ssdp_callback(
        ssdp.SsdpServiceInfo(
            ssdp_usn=MOCK_DEVICE_USN,
            ssdp_location=NEW_DEVICE_LOCATION,
            ssdp_st=MOCK_DEVICE_TYPE,
            upnp={},
        ),
        ssdp.SsdpChange.ALIVE,
    )
    await hass.async_block_till_done()

    # Check device is contacted exactly once
    upnp_factory_mock.async_create_device.assert_awaited_once_with(
        NEW_DEVICE_LOCATION)

    # Device should be available
    await assert_source_available(hass)
Exemplo n.º 3
0
async def test_duplicate_ssdp_ignored(hass: HomeAssistant) -> None:
    """Test that duplicate ssdp form is note 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_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            upnp={
                "presentationURL":
                "http://192.168.1.123:80/discovery/device.xml",
                "port": 80,
                "UDN": "uuid:83747482",
            },
        ),
    )
    assert result["type"] == "abort"
    assert result["reason"] == "already_configured"
Exemplo n.º 4
0
async def test_ssdp_discovery_existing_device_update(hass, mock_ssdp_yamaha,
                                                     mock_get_source_ip):
    """Test when the SSDP discovered device is a musiccast device, but it already exists with another IP."""
    mock_entry = MockConfigEntry(
        domain=DOMAIN,
        unique_id="1234567890",
        data={
            CONF_HOST: "192.168.188.18",
            "model": "MC20",
            "serial": "1234567890"
        },
    )
    mock_entry.add_to_hass(hass)
    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://127.0.0.1/desc.xml",
            upnp={
                ssdp.ATTR_UPNP_MODEL_NAME: "MC20",
                ssdp.ATTR_UPNP_SERIAL: "1234567890",
            },
        ),
    )
    assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
    assert result["reason"] == "already_configured"
    assert mock_entry.data[CONF_HOST] == "127.0.0.1"
    assert mock_entry.data["upnp_description"] == "http://127.0.0.1/desc.xml"
Exemplo n.º 5
0
async def test_ssdp_discovery_successful_add_device(hass, mock_ssdp_yamaha,
                                                    mock_get_source_ip):
    """Test when the SSDP discovered device is a musiccast device and the user confirms it."""
    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://127.0.0.1/desc.xml",
            upnp={
                ssdp.ATTR_UPNP_MODEL_NAME: "MC20",
                ssdp.ATTR_UPNP_SERIAL: "1234567890",
            },
        ),
    )

    assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
    assert result["errors"] is None
    assert result["step_id"] == "confirm"

    result2 = await hass.config_entries.flow.async_configure(
        result["flow_id"],
        {},
    )

    assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
    assert isinstance(result2["result"], ConfigEntry)
    assert result2["data"] == {
        "host": "127.0.0.1",
        "serial": "1234567890",
        "upnp_description": "http://127.0.0.1/desc.xml",
    }
Exemplo n.º 6
0
async def test_catch_request_error_unavailable(
        hass: HomeAssistant, ssdp_scanner_mock: Mock) -> None:
    """Test the device is checked for availability before trying requests."""
    # DmsDevice notifies of disconnect via SSDP
    ssdp_callback = ssdp_scanner_mock.async_register_callback.call_args.args[0]
    await ssdp_callback(
        ssdp.SsdpServiceInfo(
            ssdp_usn=MOCK_DEVICE_USN,
            ssdp_udn=MOCK_DEVICE_UDN,
            ssdp_headers={"NTS": "ssdp:byebye"},
            ssdp_st=MOCK_DEVICE_TYPE,
            upnp={},
        ),
        ssdp.SsdpChange.BYEBYE,
    )

    # All attempts to use the device should give an error
    with pytest.raises(Unresolvable, match="DMS is not connected"):
        # Resolve object
        await async_resolve_media(hass, ":id")
    with pytest.raises(Unresolvable, match="DMS is not connected"):
        # Resolve path
        await async_resolve_media(hass, "/path")
    with pytest.raises(Unresolvable, match="DMS is not connected"):
        # Resolve search
        await async_resolve_media(hass, "?query")
    with pytest.raises(BrowseError, match="DMS is not connected"):
        # Browse object
        await async_browse_media(hass, ":id")
    with pytest.raises(BrowseError, match="DMS is not connected"):
        # Browse path
        await async_browse_media(hass, "/path")
    with pytest.raises(BrowseError, match="DMS is not connected"):
        # Browse search
        await async_browse_media(hass, "?query")
Exemplo n.º 7
0
async def test_ssdp(hass, aioclient_mock):
    """Test SSDP discovery initiates config properly."""

    mock_connection(aioclient_mock)

    url = "http://192.168.1.2/"
    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://192.168.1.2:5200/Printer.xml",
            upnp={
                ssdp.ATTR_UPNP_DEVICE_TYPE: "urn:schemas-upnp-org:device:Printer:1",
                ssdp.ATTR_UPNP_MANUFACTURER: "Samsung Electronics",
                ssdp.ATTR_UPNP_PRESENTATION_URL: url,
                ssdp.ATTR_UPNP_SERIAL: "00000000",
                ssdp.ATTR_UPNP_UDN: "uuid:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
            },
        ),
    )

    assert result["type"] == data_entry_flow.FlowResultType.FORM
    assert result["step_id"] == "confirm"
    assert CONF_URL in result["data_schema"].schema
    for k in result["data_schema"].schema:
        if k == CONF_URL:
            assert k.default() == url
Exemplo n.º 8
0
async def test_flow_import_incomplete_discovery(hass: HomeAssistant):
    """Test config flow: configured through configuration.yaml, but incomplete discovery."""
    incomplete_discovery = ssdp.SsdpServiceInfo(
        ssdp_usn=TEST_USN,
        ssdp_st=TEST_ST,
        ssdp_location=TEST_LOCATION,
        upnp={
            # ssdp.ATTR_UPNP_UDN: TEST_UDN,  # Not provided.
        },
    )

    async def register_callback(hass, callback, match_dict):
        """Immediately do callback."""
        await callback(incomplete_discovery, ssdp.SsdpChange.ALIVE)
        return MagicMock()

    with patch(
        "homeassistant.components.ssdp.async_register_callback",
        side_effect=register_callback,
    ), patch(
        "homeassistant.components.upnp.ssdp.async_get_discovery_info_by_st",
        return_value=[incomplete_discovery],
    ):
        result = await hass.config_entries.flow.async_init(
            DOMAIN, context={"source": config_entries.SOURCE_IMPORT}
        )
    assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
    assert result["reason"] == "incomplete_discovery"
Exemplo n.º 9
0
async def test_ssdp(hass):
    """Test SSDP discovery initiates config properly."""
    url = "http://192.168.100.1/"
    context = {"source": config_entries.SOURCE_SSDP}
    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context=context,
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="upnp:rootdevice",
            ssdp_location="http://192.168.100.1:60957/rootDesc.xml",
            upnp={
                ssdp.ATTR_UPNP_DEVICE_TYPE:
                "urn:schemas-upnp-org:device:InternetGatewayDevice:1",
                ssdp.ATTR_UPNP_FRIENDLY_NAME: "Mobile Wi-Fi",
                ssdp.ATTR_UPNP_MANUFACTURER: "Huawei",
                ssdp.ATTR_UPNP_MANUFACTURER_URL: "http://www.huawei.com/",
                ssdp.ATTR_UPNP_MODEL_NAME: "Huawei router",
                ssdp.ATTR_UPNP_MODEL_NUMBER: "12345678",
                ssdp.ATTR_UPNP_PRESENTATION_URL: url,
                ssdp.ATTR_UPNP_SERIAL: "00000000",
                ssdp.ATTR_UPNP_UDN:
                "uuid:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
            },
        ),
    )

    assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
    assert result["step_id"] == "user"
    assert result["data_schema"]({})[CONF_URL] == url
Exemplo n.º 10
0
async def test_discovery_via_usb_deconz_already_discovered(detect_mock, hass):
    """Test usb flow -- deconz discovered."""
    result = await hass.config_entries.flow.async_init(
        "deconz",
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://1.2.3.4:80/",
            upnp={
                ATTR_UPNP_MANUFACTURER_URL: "http://www.dresden-elektronik.de",
                ATTR_UPNP_SERIAL: "0000000000000000",
            },
        ),
        context={"source": SOURCE_SSDP},
    )
    await hass.async_block_till_done()
    discovery_info = usb.UsbServiceInfo(
        device="/dev/ttyZIGBEE",
        pid="AAAA",
        vid="AAAA",
        serial_number="1234",
        description="zigbee radio",
        manufacturer="test",
    )
    result = await hass.config_entries.flow.async_init(
        "zha", context={"source": SOURCE_USB}, data=discovery_info
    )
    await hass.async_block_till_done()

    assert result["type"] == "abort"
    assert result["reason"] == "not_zha_device"
Exemplo n.º 11
0
async def test_existing_ssdp(hass: HomeAssistant, service: MagicMock):
    """Test abort of already existing entry by ssdp."""

    MockConfigEntry(
        domain=DOMAIN,
        data={
            CONF_HOST: "192.168.1.5",
            CONF_VERIFY_SSL: VERIFY_SSL,
            CONF_USERNAME: USERNAME,
            CONF_PASSWORD: PASSWORD,
            CONF_MAC: MACS,
        },
        unique_id=SERIAL,
    ).add_to_hass(hass)

    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context={"source": SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://192.168.1.5:5000",
            upnp={
                ssdp.ATTR_UPNP_FRIENDLY_NAME: "mydsm",
                ssdp.ATTR_UPNP_SERIAL:
                "001132XXXX59",  # Existing in MACS[0], but SSDP does not have `-`
            },
        ),
    )
    assert result["type"] == data_entry_flow.FlowResultType.ABORT
    assert result["reason"] == "already_configured"
async def test_ssdp_already_configured(hass, mock_panel):
    """Test if a discovered panel has already been configured."""
    MockConfigEntry(
        domain="konnected",
        data={"host": "0.0.0.0", "port": 1234},
        unique_id="112233445566",
    ).add_to_hass(hass)
    mock_panel.get_status.return_value = {
        "mac": "11:22:33:44:55:66",
        "model": "Konnected Pro",
    }

    result = await hass.config_entries.flow.async_init(
        config_flow.DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://0.0.0.0:1234/Device.xml",
            upnp={
                "manufacturer": config_flow.KONN_MANUFACTURER,
                "modelName": config_flow.KONN_MODEL_PRO,
            },
        ),
    )
    assert result["type"] == "abort"
    assert result["reason"] == "already_configured"
async def test_ssdp_already_configured(hass):
    """Test ssdp abort when the router is already configured."""
    MockConfigEntry(
        domain=DOMAIN,
        data={
            CONF_PASSWORD: PASSWORD
        },
        unique_id=SERIAL,
    ).add_to_hass(hass)

    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context={"source": SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location=SSDP_URL_SLL,
            upnp={
                ssdp.ATTR_UPNP_MODEL_NUMBER: "RBR20",
                ssdp.ATTR_UPNP_PRESENTATION_URL: URL,
                ssdp.ATTR_UPNP_SERIAL: SERIAL,
            },
        ),
    )
    assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
    assert result["reason"] == "already_configured"
Exemplo n.º 14
0
async def test_update_address(hass, aioclient_mock):
    """Make sure that connection status triggers a dispatcher send."""
    config_entry = await setup_deconz_integration(hass, aioclient_mock)
    gateway = get_gateway_from_config_entry(hass, config_entry)
    assert gateway.api.host == "1.2.3.4"

    with patch(
            "homeassistant.components.deconz.async_setup_entry",
            return_value=True,
    ) as mock_setup_entry:
        await hass.config_entries.flow.async_init(
            DECONZ_DOMAIN,
            data=ssdp.SsdpServiceInfo(
                ssdp_st="mock_st",
                ssdp_usn="mock_usn",
                ssdp_location="http://2.3.4.5:80/",
                upnp={
                    ATTR_UPNP_MANUFACTURER_URL: DECONZ_MANUFACTURERURL,
                    ATTR_UPNP_SERIAL: BRIDGEID,
                    ATTR_UPNP_UDN: "uuid:456DEF",
                },
            ),
            context={"source": SOURCE_SSDP},
        )
        await hass.async_block_till_done()

    assert gateway.api.host == "2.3.4.5"
    assert len(mock_setup_entry.mock_calls) == 1
Exemplo n.º 15
0
async def test_ssdp_port_5555(hass, service_5555):
    """Test ssdp step with port 5555."""
    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context={"source": SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location=SSDP_URL_SLL,
            upnp={
                ssdp.ATTR_UPNP_MODEL_NUMBER: MODELS_PORT_5555[0],
                ssdp.ATTR_UPNP_PRESENTATION_URL: URL_SSL,
                ssdp.ATTR_UPNP_SERIAL: SERIAL,
            },
        ),
    )
    assert result["type"] == data_entry_flow.FlowResultType.FORM
    assert result["step_id"] == "user"

    result = await hass.config_entries.flow.async_configure(
        result["flow_id"], {CONF_PASSWORD: PASSWORD})
    assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
    assert result["result"].unique_id == SERIAL
    assert result["title"] == TITLE
    assert result["data"].get(CONF_HOST) == HOST
    assert result["data"].get(CONF_PORT) == PORT_5555
    assert result["data"].get(CONF_SSL) is True
    assert result["data"].get(CONF_USERNAME) == DEFAULT_USER
    assert result["data"][CONF_PASSWORD] == PASSWORD
Exemplo n.º 16
0
async def test_ssdp_discovery_update_configuration(hass, aioclient_mock):
    """Test if a discovered bridge is configured but updates with new attributes."""
    config_entry = await setup_deconz_integration(hass, aioclient_mock)

    with patch(
        "homeassistant.components.deconz.async_setup_entry",
        return_value=True,
    ) as mock_setup_entry:
        result = await hass.config_entries.flow.async_init(
            DECONZ_DOMAIN,
            data=ssdp.SsdpServiceInfo(
                ssdp_usn="mock_usn",
                ssdp_st="mock_st",
                ssdp_location="http://2.3.4.5:80/",
                upnp={
                    ATTR_UPNP_MANUFACTURER_URL: DECONZ_MANUFACTURERURL,
                    ATTR_UPNP_SERIAL: BRIDGEID,
                },
            ),
            context={"source": SOURCE_SSDP},
        )
        await hass.async_block_till_done()

    assert result["type"] == RESULT_TYPE_ABORT
    assert result["reason"] == "already_configured"
    assert config_entry.data[CONF_HOST] == "2.3.4.5"
    assert len(mock_setup_entry.mock_calls) == 1
Exemplo n.º 17
0
async def test_ssdp_ipv6(hass):
    """Test ssdp abort when using a ipv6 address."""
    MockConfigEntry(
        domain=DOMAIN,
        data={
            CONF_PASSWORD: PASSWORD
        },
        unique_id=SERIAL,
    ).add_to_hass(hass)

    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context={"source": SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location=SSDP_URLipv6,
            upnp={
                ssdp.ATTR_UPNP_MODEL_NUMBER: "RBR20",
                ssdp.ATTR_UPNP_PRESENTATION_URL: URL,
                ssdp.ATTR_UPNP_SERIAL: SERIAL,
            },
        ),
    )
    assert result["type"] == data_entry_flow.FlowResultType.ABORT
    assert result["reason"] == "not_ipv4_address"
async def test_form_ssdp_existing_entry_no_port_https(hass: HomeAssistant):
    """Test we update the ip of an existing entry from ssdp with no port and https."""

    entry = MockConfigEntry(
        domain=DOMAIN,
        data={CONF_HOST: f"https://{MOCK_HOSTNAME}/{ISY_URL_POSTFIX}"},
        unique_id=MOCK_UUID,
    )
    entry.add_to_hass(hass)

    with patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE):
        result = await hass.config_entries.flow.async_init(
            DOMAIN,
            context={"source": SOURCE_SSDP},
            data=ssdp.SsdpServiceInfo(
                ssdp_usn="mock_usn",
                ssdp_st="mock_st",
                ssdp_location=f"https://3.3.3.3/{ISY_URL_POSTFIX}",
                upnp={
                    ssdp.ATTR_UPNP_FRIENDLY_NAME: "myisy",
                    ssdp.ATTR_UPNP_UDN: f"{UDN_UUID_PREFIX}{MOCK_UUID}",
                },
            ),
        )
        await hass.async_block_till_done()

    assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
    assert result["reason"] == "already_configured"
    assert entry.data[CONF_HOST] == f"https://3.3.3.3:443/{ISY_URL_POSTFIX}"
Exemplo n.º 19
0
async def test_form_ssdp_gets_form_with_ignored_entry(hass):
    """Test we can still setup if there is an ignored entry."""

    entry = MockConfigEntry(
        domain=UNIFI_DOMAIN,
        data={"not_controller_key": None},
        source=config_entries.SOURCE_IGNORE,
    )
    entry.add_to_hass(hass)
    result = await hass.config_entries.flow.async_init(
        UNIFI_DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://1.2.3.4:41417/rootDesc.xml",
            upnp={
                "friendlyName": "UniFi Dream Machine New",
                "modelDescription": "UniFi Dream Machine Pro",
                "serialNumber": "e0:63:da:20:14:a9",
            },
        ),
    )
    assert result["type"] == "form"
    assert result["step_id"] == "user"
    assert result["errors"] == {}
    context = next(flow["context"]
                   for flow in hass.config_entries.flow.async_progress()
                   if flow["flow_id"] == result["flow_id"])
    assert context["title_placeholders"] == {
        "host": "1.2.3.4",
        "site": "default",
    }
async def test_form_ssdp_already_configured(hass: HomeAssistant) -> None:
    """Test ssdp abort when the serial number is already configured."""

    MockConfigEntry(
        domain=DOMAIN,
        data={
            CONF_HOST: f"http://{MOCK_HOSTNAME}{ISY_URL_POSTFIX}"
        },
        unique_id=MOCK_UUID,
    ).add_to_hass(hass)

    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context={"source": SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location=f"http://{MOCK_HOSTNAME}{ISY_URL_POSTFIX}",
            upnp={
                ssdp.ATTR_UPNP_FRIENDLY_NAME: "myisy",
                ssdp.ATTR_UPNP_UDN: f"{UDN_UUID_PREFIX}{MOCK_UUID}",
            },
        ),
    )
    assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
Exemplo n.º 21
0
async def test_form_ssdp(hass):
    """Test we get the form with ssdp source."""

    result = await hass.config_entries.flow.async_init(
        UNIFI_DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://192.168.208.1:41417/rootDesc.xml",
            upnp={
                "friendlyName": "UniFi Dream Machine",
                "modelDescription": "UniFi Dream Machine Pro",
                "serialNumber": "e0:63:da:20:14:a9",
            },
        ),
    )
    assert result["type"] == "form"
    assert result["step_id"] == "user"
    assert result["errors"] == {}
    context = next(flow["context"]
                   for flow in hass.config_entries.flow.async_progress()
                   if flow["flow_id"] == result["flow_id"])
    assert context["title_placeholders"] == {
        "host": "192.168.208.1",
        "site": "default",
    }
Exemplo n.º 22
0
async def test_form_ssdp_aborts_if_serial_already_exists(hass):
    """Test we abort if the serial is already configured."""

    entry = MockConfigEntry(
        domain=UNIFI_DOMAIN,
        data={"controller": {
            "host": "1.2.3.4",
            "site": "site_id"
        }},
        unique_id="e0:63:da:20:14:a9",
    )
    entry.add_to_hass(hass)
    result = await hass.config_entries.flow.async_init(
        UNIFI_DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://192.168.208.1:41417/rootDesc.xml",
            upnp={
                "friendlyName": "UniFi Dream Machine",
                "modelDescription": "UniFi Dream Machine Pro",
                "serialNumber": "e0:63:da:20:14:a9",
            },
        ),
    )
    assert result["type"] == "abort"
    assert result["reason"] == "already_configured"
async def test_form_ssdp_aborts_before_checking_remoteid_if_host_known(hass):
    """Test we abort without connecting if the host is already known."""

    config_entry = MockConfigEntry(
        domain=DOMAIN,
        data={"host": "2.2.2.2", "name": "any"},
    )
    config_entry.add_to_hass(hass)

    config_entry_without_host = MockConfigEntry(
        domain=DOMAIN,
        data={"name": "other"},
    )
    config_entry_without_host.add_to_hass(hass)

    harmonyapi = _get_mock_harmonyapi(connect=True)

    with patch(
        "homeassistant.components.harmony.util.HarmonyAPI",
        return_value=harmonyapi,
    ):
        result = await hass.config_entries.flow.async_init(
            DOMAIN,
            context={"source": config_entries.SOURCE_SSDP},
            data=ssdp.SsdpServiceInfo(
                ssdp_usn="mock_usn",
                ssdp_st="mock_st",
                ssdp_location="http://2.2.2.2:8088/description",
                upnp={
                    "friendlyName": "Harmony Hub",
                },
            ),
        )
    assert result["type"] == "abort"
Exemplo n.º 24
0
async def test_ssdp_discovery_update_configuration(hass, aioclient_mock):
    """Test if a discovered bridge is configured and updated with new host."""
    create_mock_api_discovery(aioclient_mock, [("1.1.1.1", "aabbccddeeff")])
    entry = MockConfigEntry(domain="hue",
                            unique_id="aabbccddeeff",
                            data={"host": "0.0.0.0"})
    entry.add_to_hass(hass)

    result = await hass.config_entries.flow.async_init(
        const.DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://1.1.1.1/",
            upnp={
                ssdp.ATTR_UPNP_MANUFACTURER_URL:
                config_flow.HUE_MANUFACTURERURL[0],
                ssdp.ATTR_UPNP_SERIAL: "aabbccddeeff",
            },
        ),
    )

    assert result["type"] == "abort"
    assert result["reason"] == "already_configured"
    assert entry.data["host"] == "1.1.1.1"
Exemplo n.º 25
0
async def test_ssdp_discovery_dont_update_existing_hassio_configuration(
    hass, aioclient_mock
):
    """Test to ensure the SSDP discovery does not update an Hass.io entry."""
    config_entry = await setup_deconz_integration(
        hass, aioclient_mock, source=SOURCE_HASSIO
    )

    result = await hass.config_entries.flow.async_init(
        DECONZ_DOMAIN,
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location="http://1.2.3.4:80/",
            upnp={
                ATTR_UPNP_MANUFACTURER_URL: DECONZ_MANUFACTURERURL,
                ATTR_UPNP_SERIAL: BRIDGEID,
            },
        ),
        context={"source": SOURCE_SSDP},
    )

    assert result["type"] == RESULT_TYPE_ABORT
    assert result["reason"] == "already_configured"
    assert config_entry.data[CONF_HOST] == "1.2.3.4"
Exemplo n.º 26
0
async def test_become_available(
    hass: HomeAssistant,
    upnp_factory_mock: Mock,
    ssdp_scanner_mock: Mock,
    disconnected_source_mock: None,
) -> None:
    """Test a device becoming available after the entity is constructed."""
    # Mock device is now available.
    upnp_factory_mock.async_create_device.side_effect = None
    upnp_factory_mock.async_create_device.reset_mock()

    # Send an SSDP notification from the now alive device
    ssdp_callback = ssdp_scanner_mock.async_register_callback.call_args.args[0]
    await ssdp_callback(
        ssdp.SsdpServiceInfo(
            ssdp_usn=MOCK_DEVICE_USN,
            ssdp_location=NEW_DEVICE_LOCATION,
            ssdp_st=MOCK_DEVICE_TYPE,
            upnp={},
        ),
        ssdp.SsdpChange.ALIVE,
    )
    await hass.async_block_till_done()

    # Check device was created from the supplied URL
    upnp_factory_mock.async_create_device.assert_awaited_once_with(NEW_DEVICE_LOCATION)
    # Quick check of the state to verify the entity has a connected DmsDevice
    await assert_source_available(hass)
Exemplo n.º 27
0
async def test_config_flow_ssdp(hass):
    """Successful flow initialized by ssdp discovery."""
    result = await hass.config_entries.flow.async_init(
        DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data=ssdp.SsdpServiceInfo(
            ssdp_usn="mock_usn",
            ssdp_st="mock_st",
            ssdp_location=TEST_SSDP_LOCATION,
            upnp={
                ssdp.ATTR_UPNP_MANUFACTURER: TEST_MANUFACTURER,
                ssdp.ATTR_UPNP_MODEL_NAME: TEST_MODEL,
                ssdp.ATTR_UPNP_SERIAL: TEST_SERIALNUMBER,
            },
        ),
    )

    assert result["type"] == "form"
    assert result["step_id"] == "confirm"

    result = await hass.config_entries.flow.async_configure(
        result["flow_id"],
        {},
    )

    assert result["type"] == "create_entry"
    assert result["title"] == TEST_NAME
    assert result["data"] == {
        CONF_HOST: TEST_HOST,
        CONF_MODEL: TEST_MODEL,
        CONF_TYPE: TEST_RECEIVER_TYPE,
        CONF_MANUFACTURER: TEST_MANUFACTURER,
        CONF_SERIAL_NUMBER: TEST_SERIALNUMBER,
    }
Exemplo n.º 28
0
 def _generate_fake_ssdp_listener(*args, **kwargs):
     info = None
     if not no_device:
         info = ssdp.SsdpServiceInfo(
             ssdp_usn="",
             ssdp_st=scanner.SSDP_ST,
             upnp={},
             ssdp_headers=capabilities or CAPABILITIES,
         )
     return _patched_ssdp_listener(info, *args, **kwargs)
Exemplo n.º 29
0
async def test_service_info_compatibility(hass, caplog):
    """Test compatibility with old-style dict.

    To be removed in 2022.6
    """
    discovery_info = ssdp.SsdpServiceInfo(
        ssdp_st="mock-st",
        ssdp_location="http://1.1.1.1",
        ssdp_usn="uuid:mock-udn::mock-st",
        ssdp_server="mock-server",
        ssdp_ext="",
        ssdp_headers=_ssdp_headers(
            {
                "st": "mock-st",
                "location": "http://1.1.1.1",
                "usn": "uuid:mock-udn::mock-st",
                "server": "mock-server",
                "ext": "",
            }
        ),
        upnp={ssdp.ATTR_UPNP_DEVICE_TYPE: "ABC"},
    )

    with patch("homeassistant.helpers.frame._REPORTED_INTEGRATIONS", set()):
        assert discovery_info["ssdp_st"] == "mock-st"
    assert "Detected integration that accessed discovery_info['ssdp_st']" in caplog.text

    with patch("homeassistant.helpers.frame._REPORTED_INTEGRATIONS", set()):
        assert discovery_info.get("ssdp_location") == "http://1.1.1.1"
    assert (
        "Detected integration that accessed discovery_info.get('ssdp_location')"
        in caplog.text
    )

    with patch("homeassistant.helpers.frame._REPORTED_INTEGRATIONS", set()):
        assert "ssdp_usn" in discovery_info
    assert (
        "Detected integration that accessed discovery_info.__contains__('ssdp_usn')"
        in caplog.text
    )

    # Root item
    assert discovery_info["ssdp_usn"] == "uuid:mock-udn::mock-st"
    assert discovery_info.get("ssdp_usn") == "uuid:mock-udn::mock-st"
    assert "ssdp_usn" in discovery_info

    # SSDP header
    assert discovery_info["st"] == "mock-st"
    assert discovery_info.get("st") == "mock-st"
    assert "st" in discovery_info

    # UPnP item
    assert discovery_info[ssdp.ATTR_UPNP_DEVICE_TYPE] == "ABC"
    assert discovery_info.get(ssdp.ATTR_UPNP_DEVICE_TYPE) == "ABC"
    assert ssdp.ATTR_UPNP_DEVICE_TYPE in discovery_info
Exemplo n.º 30
0
 def _async_start_flow(*_) -> None:
     discovery_flow.async_create_flow(
         self._hass,
         DOMAIN,
         context={"source": config_entries.SOURCE_SSDP},
         data=ssdp.SsdpServiceInfo(
             ssdp_usn="",
             ssdp_st=SSDP_ST,
             ssdp_headers=response,
             upnp={},
         ),
     )