Add additional method of retrieving UUID for LG soundbar configuration (#77856)

This commit is contained in:
Chris McCurdy 2022-09-07 11:43:05 -04:00 committed by GitHub
parent cd5967c4c6
commit 52c8c80f91
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 182 additions and 5 deletions

View file

@ -1,5 +1,5 @@
"""Config flow to configure the LG Soundbar integration."""
from queue import Queue
from queue import Full, Queue
import socket
import temescal
@ -20,18 +20,29 @@ def test_connect(host, port):
uuid_q = Queue(maxsize=1)
name_q = Queue(maxsize=1)
def queue_add(attr_q, data):
try:
attr_q.put_nowait(data)
except Full:
pass
def msg_callback(response):
if response["msg"] == "MAC_INFO_DEV" and "s_uuid" in response["data"]:
uuid_q.put_nowait(response["data"]["s_uuid"])
if (
response["msg"] in ["MAC_INFO_DEV", "PRODUCT_INFO"]
and "s_uuid" in response["data"]
):
queue_add(uuid_q, response["data"]["s_uuid"])
if (
response["msg"] == "SPK_LIST_VIEW_INFO"
and "s_user_name" in response["data"]
):
name_q.put_nowait(response["data"]["s_user_name"])
queue_add(name_q, response["data"]["s_user_name"])
try:
connection = temescal.temescal(host, port=port, callback=msg_callback)
connection.get_mac_info()
if uuid_q.empty():
connection.get_product_info()
connection.get_info()
details = {"name": name_q.get(timeout=10), "uuid": uuid_q.get(timeout=10)}
return details

View file

@ -1,5 +1,5 @@
"""Test the lg_soundbar config flow."""
from unittest.mock import MagicMock, patch
from unittest.mock import DEFAULT, MagicMock, Mock, call, patch
from homeassistant import config_entries
from homeassistant.components.lg_soundbar.const import DEFAULT_PORT, DOMAIN
@ -43,6 +43,172 @@ async def test_form(hass):
assert len(mock_setup_entry.mock_calls) == 1
async def test_form_uuid_missing_from_mac_info(hass):
"""Test we get the form, but uuid is missing from the initial get_mac_info function call."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == "form"
assert result["errors"] == {}
with patch(
"homeassistant.components.lg_soundbar.config_flow.temescal", return_value=Mock()
) as mock_temescal, patch(
"homeassistant.components.lg_soundbar.async_setup_entry", return_value=True
) as mock_setup_entry:
tmock = mock_temescal.temescal
tmock.return_value = Mock()
instance = tmock.return_value
def temescal_side_effect(addr, port, callback):
product_info = {"msg": "PRODUCT_INFO", "data": {"s_uuid": "uuid"}}
instance.get_product_info.side_effect = lambda: callback(product_info)
info = {"msg": "SPK_LIST_VIEW_INFO", "data": {"s_user_name": "name"}}
instance.get_info.side_effect = lambda: callback(info)
return DEFAULT
tmock.side_effect = temescal_side_effect
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_HOST: "1.1.1.1",
},
)
await hass.async_block_till_done()
assert result2["type"] == "create_entry"
assert result2["title"] == "name"
assert result2["data"] == {
CONF_HOST: "1.1.1.1",
CONF_PORT: DEFAULT_PORT,
}
assert len(mock_setup_entry.mock_calls) == 1
async def test_form_uuid_present_in_both_functions_uuid_q_empty(hass):
"""Get the form, uuid present in both get_mac_info and get_product_info calls.
Value from get_mac_info is not added to uuid_q before get_product_info is run.
"""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == "form"
assert result["errors"] == {}
mock_uuid_q = MagicMock()
mock_name_q = MagicMock()
with patch(
"homeassistant.components.lg_soundbar.config_flow.temescal", return_value=Mock()
) as mock_temescal, patch(
"homeassistant.components.lg_soundbar.config_flow.Queue",
return_value=MagicMock(),
) as mock_q, patch(
"homeassistant.components.lg_soundbar.async_setup_entry", return_value=True
) as mock_setup_entry:
mock_q.side_effect = [mock_uuid_q, mock_name_q]
mock_uuid_q.empty.return_value = True
mock_uuid_q.get.return_value = "uuid"
mock_name_q.get.return_value = "name"
tmock = mock_temescal.temescal
tmock.return_value = Mock()
instance = tmock.return_value
def temescal_side_effect(addr, port, callback):
mac_info = {"msg": "MAC_INFO_DEV", "data": {"s_uuid": "uuid"}}
instance.get_mac_info.side_effect = lambda: callback(mac_info)
product_info = {"msg": "PRODUCT_INFO", "data": {"s_uuid": "uuid"}}
instance.get_product_info.side_effect = lambda: callback(product_info)
info = {"msg": "SPK_LIST_VIEW_INFO", "data": {"s_user_name": "name"}}
instance.get_info.side_effect = lambda: callback(info)
return DEFAULT
tmock.side_effect = temescal_side_effect
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_HOST: "1.1.1.1",
},
)
await hass.async_block_till_done()
assert result2["type"] == "create_entry"
assert result2["title"] == "name"
assert result2["data"] == {
CONF_HOST: "1.1.1.1",
CONF_PORT: DEFAULT_PORT,
}
assert len(mock_setup_entry.mock_calls) == 1
mock_uuid_q.empty.assert_called_once()
mock_uuid_q.put_nowait.has_calls([call("uuid"), call("uuid")])
mock_uuid_q.get.assert_called_once()
async def test_form_uuid_present_in_both_functions_uuid_q_not_empty(hass):
"""Get the form, uuid present in both get_mac_info and get_product_info calls.
Value from get_mac_info is added to uuid_q before get_product_info is run.
"""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == "form"
assert result["errors"] == {}
mock_uuid_q = MagicMock()
mock_name_q = MagicMock()
with patch(
"homeassistant.components.lg_soundbar.config_flow.temescal", return_value=Mock()
) as mock_temescal, patch(
"homeassistant.components.lg_soundbar.config_flow.Queue",
return_value=MagicMock(),
) as mock_q, patch(
"homeassistant.components.lg_soundbar.async_setup_entry", return_value=True
) as mock_setup_entry:
mock_q.side_effect = [mock_uuid_q, mock_name_q]
mock_uuid_q.empty.return_value = False
mock_uuid_q.get.return_value = "uuid"
mock_name_q.get.return_value = "name"
tmock = mock_temescal.temescal
tmock.return_value = Mock()
instance = tmock.return_value
def temescal_side_effect(addr, port, callback):
mac_info = {"msg": "MAC_INFO_DEV", "data": {"s_uuid": "uuid"}}
instance.get_mac_info.side_effect = lambda: callback(mac_info)
info = {"msg": "SPK_LIST_VIEW_INFO", "data": {"s_user_name": "name"}}
instance.get_info.side_effect = lambda: callback(info)
return DEFAULT
tmock.side_effect = temescal_side_effect
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_HOST: "1.1.1.1",
},
)
await hass.async_block_till_done()
assert result2["type"] == "create_entry"
assert result2["title"] == "name"
assert result2["data"] == {
CONF_HOST: "1.1.1.1",
CONF_PORT: DEFAULT_PORT,
}
assert len(mock_setup_entry.mock_calls) == 1
mock_uuid_q.empty.assert_called_once()
mock_uuid_q.put_nowait.assert_called_once()
mock_uuid_q.get.assert_called_once()
async def test_form_cannot_connect(hass):
"""Test we handle cannot connect error."""
result = await hass.config_entries.flow.async_init(