Пример #1
0
async def test_catch_request_error(hass: HomeAssistant, dms_device_mock: Mock) -> None:
    """Test errors when making requests to the device are handled."""
    dms_device_mock.async_browse_metadata.side_effect = UpnpActionError(
        error_code=ContentDirectoryErrorCode.NO_SUCH_OBJECT
    )
    with pytest.raises(Unresolvable, match="No such object: bad_id"):
        await async_resolve_media(hass, ":bad_id")

    dms_device_mock.async_search_directory.side_effect = UpnpActionError(
        error_code=ContentDirectoryErrorCode.INVALID_SEARCH_CRITERIA
    )
    with pytest.raises(Unresolvable, match="Invalid query: bad query"):
        await async_resolve_media(hass, "?bad query")

    dms_device_mock.async_browse_metadata.side_effect = UpnpActionError(
        error_code=ContentDirectoryErrorCode.CANNOT_PROCESS_REQUEST
    )
    with pytest.raises(BrowseError, match="Server failure: "):
        await async_resolve_media(hass, ":good_id")

    dms_device_mock.async_browse_metadata.side_effect = UpnpError
    with pytest.raises(
        BrowseError, match="Server communication failure: UpnpError(.*)"
    ):
        await async_resolve_media(hass, ":bad_id")
async def test_catch_request_error(device_source_mock: DmsDeviceSource,
                                   dms_device_mock: Mock) -> None:
    """Test errors when making requests to the device are handled."""
    dms_device_mock.async_browse_metadata.side_effect = UpnpActionError(
        error_code=ContentDirectoryErrorCode.NO_SUCH_OBJECT)
    with pytest.raises(ActionError, match="No such object: bad_id"):
        await device_source_mock.async_resolve_media(":bad_id")

    dms_device_mock.async_search_directory.side_effect = UpnpActionError(
        error_code=ContentDirectoryErrorCode.INVALID_SEARCH_CRITERIA)
    with pytest.raises(ActionError, match="Invalid query: bad query"):
        await device_source_mock.async_resolve_media("?bad query")

    dms_device_mock.async_browse_metadata.side_effect = UpnpActionError(
        error_code=ContentDirectoryErrorCode.CANNOT_PROCESS_REQUEST)
    with pytest.raises(DeviceConnectionError, match="Server failure: "):
        await device_source_mock.async_resolve_media(":good_id")

    dms_device_mock.async_browse_metadata.side_effect = UpnpError
    with pytest.raises(DeviceConnectionError,
                       match="Server communication failure: UpnpError(.*)"):
        await device_source_mock.async_resolve_media(":bad_id")

    # UpnpConnectionErrors will cause the device_source_mock to disconnect from the device
    assert device_source_mock.available
    dms_device_mock.async_browse_metadata.side_effect = UpnpConnectionError
    with pytest.raises(DeviceConnectionError,
                       match="Server disconnected: UpnpConnectionError(.*)"):
        await device_source_mock.async_resolve_media(":bad_id")
    assert not device_source_mock.available
async def test_resolve_path_browsed_nothing(
    device_source_mock: DmsDeviceSource, dms_device_mock: Mock
) -> None:
    """Test async_resolve_path: action error results in browsing, but nothing found."""
    dms_device_mock.async_search_directory.side_effect = UpnpActionError()
    # No children
    dms_device_mock.async_browse_direct_children.side_effect = [
        DmsDevice.BrowseResult([], 0, 0, 0)
    ]
    with pytest.raises(Unresolvable, match="No contents for thing in thing/other"):
        await device_source_mock.async_resolve_path(r"thing/other")

    # There are children, but they don't match
    dms_device_mock.async_browse_direct_children.side_effect = [
        DmsDevice.BrowseResult(
            [
                didl_lite.Item(
                    id="nothingid", restricted="false", title="not thing", res=[]
                )
            ],
            1,
            1,
            0,
        )
    ]
    with pytest.raises(Unresolvable, match="Nothing found for thing in thing/other"):
        await device_source_mock.async_resolve_path(r"thing/other")
Пример #4
0
async def test_resolve_path_no_such_container(hass: HomeAssistant,
                                              dms_device_mock: Mock) -> None:
    """Test async_resolve_path: Explicit check for NO_SUCH_CONTAINER."""
    dms_device_mock.async_search_directory.side_effect = UpnpActionError(
        error_code=ContentDirectoryErrorCode.NO_SUCH_CONTAINER)
    with pytest.raises(Unresolvable, match="No such container: 0"):
        await async_resolve_media(hass, "thing/other")
Пример #5
0
async def test_browse_search_invalid(hass: HomeAssistant,
                                     dms_device_mock: Mock) -> None:
    """Test searching with an invalid query gives a BrowseError."""
    query = "title == FooBar"
    dms_device_mock.async_search_directory.side_effect = UpnpActionError(
        error_code=ContentDirectoryErrorCode.INVALID_SEARCH_CRITERIA)
    with pytest.raises(BrowseError, match=f"Invalid query: {query}"):
        await async_browse_media(hass, f"?{query}")
Пример #6
0
async def test_resolve_path_browsed(hass: HomeAssistant, dms_device_mock: Mock) -> None:
    """Test async_resolve_path: action error results in browsing."""
    path: Final = "path/to/thing"
    object_ids: Final = ["path_id", "to_id", "thing_id"]
    res_url: Final = "foo/bar"
    res_mime: Final = "audio/mpeg"

    # Setup expected calls
    search_directory_result = []
    for ob_id, ob_title in zip(object_ids, path.split("/")):
        didl_item = didl_lite.Item(
            id=ob_id,
            restricted="false",
            title=ob_title,
            res=[],
        )
        search_directory_result.append(DmsDevice.BrowseResult([didl_item], 1, 1, 0))
    dms_device_mock.async_search_directory.side_effect = [
        search_directory_result[0],
        # 2nd level can't be searched (this happens with Kodi)
        UpnpActionError(),
        search_directory_result[2],
    ]

    browse_children_result: BrowseResultList = []
    for title in ("Irrelevant", "to", "Ignored"):
        browse_children_result.append(
            didl_lite.Item(id=f"{title}_id", restricted="false", title=title, res=[])
        )
    dms_device_mock.async_browse_direct_children.side_effect = [
        DmsDevice.BrowseResult(browse_children_result, 3, 3, 0)
    ]

    dms_device_mock.async_browse_metadata.return_value = didl_lite.Item(
        id=object_ids[-1],
        restricted="false",
        title="thing",
        res=[didl_lite.Resource(uri=res_url, protocol_info=f"http-get:*:{res_mime}:")],
    )

    # Perform the action to test
    result = await async_resolve_media(hass, path)
    # All levels should have an attempted search
    assert dms_device_mock.async_search_directory.await_args_list == [
        call(
            parent_id,
            search_criteria=f'@parentID="{parent_id}" and dc:title="{title}"',
            metadata_filter=["id", "upnp:class", "dc:title"],
            requested_count=1,
        )
        for parent_id, title in zip(["0"] + object_ids[:-1], path.split("/"))
    ]
    assert result.didl_metadata.id == object_ids[-1]
    # 2nd level should also be browsed
    assert dms_device_mock.async_browse_direct_children.await_args_list == [
        call("path_id", metadata_filter=["id", "upnp:class", "dc:title"])
    ]
async def test_resolve_path_browsed(device_source_mock: DmsDeviceSource,
                                    dms_device_mock: Mock) -> None:
    """Test async_resolve_path: action error results in browsing."""
    path: Final = "path/to/thing"
    object_ids: Final = ["path_id", "to_id", "thing_id"]

    search_directory_result = []
    for ob_id, ob_title in zip(object_ids, path.split("/")):
        didl_item = didl_lite.Item(
            id=ob_id,
            restricted="false",
            title=ob_title,
            res=[],
        )
        search_directory_result.append(
            DmsDevice.BrowseResult([didl_item], 1, 1, 0))
    dms_device_mock.async_search_directory.side_effect = [
        search_directory_result[0],
        # 2nd level can't be searched (this happens with Kodi)
        UpnpActionError(),
        search_directory_result[2],
    ]

    browse_children_result: BrowseResultList = []
    for title in ("Irrelevant", "to", "Ignored"):
        browse_children_result.append(
            didl_lite.Item(id=f"{title}_id",
                           restricted="false",
                           title=title,
                           res=[]))
    dms_device_mock.async_browse_direct_children.side_effect = [
        DmsDevice.BrowseResult(browse_children_result, 3, 3, 0)
    ]

    result = await device_source_mock.async_resolve_path(path)
    # All levels should have an attempted search
    assert dms_device_mock.async_search_directory.await_args_list == [
        call(
            parent_id,
            search_criteria=f'@parentID="{parent_id}" and dc:title="{title}"',
            metadata_filter=["id", "upnp:class", "dc:title"],
            requested_count=1,
        ) for parent_id, title in zip(["0"] + object_ids[:-1], path.split("/"))
    ]
    assert result == object_ids[-1]
    # 2nd level should also be browsed
    assert dms_device_mock.async_browse_direct_children.await_args_list == [
        call("path_id", metadata_filter=["id", "upnp:class", "dc:title"])
    ]