Add reconfigure to LG webOS TV (#135360)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>pull/135379/head^2
parent
19f460614e
commit
a745e079e9
|
@ -20,7 +20,7 @@ from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
|
||||||
from . import async_control_connect, update_client_key
|
from . import async_control_connect
|
||||||
from .const import CONF_SOURCES, DEFAULT_NAME, DOMAIN, WEBOSTV_EXCEPTIONS
|
from .const import CONF_SOURCES, DEFAULT_NAME, DOMAIN, WEBOSTV_EXCEPTIONS
|
||||||
from .helpers import async_get_sources
|
from .helpers import async_get_sources
|
||||||
|
|
||||||
|
@ -53,14 +53,11 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> ConfigFlowResult:
|
) -> ConfigFlowResult:
|
||||||
"""Handle a flow initialized by the user."""
|
"""Handle a flow initialized by the user."""
|
||||||
errors: dict[str, str] = {}
|
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
self._host = user_input[CONF_HOST]
|
self._host = user_input[CONF_HOST]
|
||||||
return await self.async_step_pairing()
|
return await self.async_step_pairing()
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(step_id="user", data_schema=DATA_SCHEMA)
|
||||||
step_id="user", data_schema=DATA_SCHEMA, errors=errors
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_step_pairing(
|
async def async_step_pairing(
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
@ -69,13 +66,13 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
self._async_abort_entries_match({CONF_HOST: self._host})
|
self._async_abort_entries_match({CONF_HOST: self._host})
|
||||||
|
|
||||||
self.context["title_placeholders"] = {"name": self._name}
|
self.context["title_placeholders"] = {"name": self._name}
|
||||||
errors = {}
|
errors: dict[str, str] = {}
|
||||||
|
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
try:
|
try:
|
||||||
client = await async_control_connect(self._host, None)
|
client = await async_control_connect(self._host, None)
|
||||||
except WebOsTvPairError:
|
except WebOsTvPairError:
|
||||||
return self.async_abort(reason="error_pairing")
|
errors["base"] = "error_pairing"
|
||||||
except WEBOSTV_EXCEPTIONS:
|
except WEBOSTV_EXCEPTIONS:
|
||||||
errors["base"] = "cannot_connect"
|
errors["base"] = "cannot_connect"
|
||||||
else:
|
else:
|
||||||
|
@ -130,20 +127,56 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> ConfigFlowResult:
|
) -> ConfigFlowResult:
|
||||||
"""Dialog that informs the user that reauth is required."""
|
"""Dialog that informs the user that reauth is required."""
|
||||||
|
errors: dict[str, str] = {}
|
||||||
|
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
try:
|
try:
|
||||||
client = await async_control_connect(self._host, None)
|
client = await async_control_connect(self._host, None)
|
||||||
except WebOsTvPairError:
|
except WebOsTvPairError:
|
||||||
return self.async_abort(reason="error_pairing")
|
errors["base"] = "error_pairing"
|
||||||
except WEBOSTV_EXCEPTIONS:
|
except WEBOSTV_EXCEPTIONS:
|
||||||
return self.async_abort(reason="reauth_unsuccessful")
|
errors["base"] = "cannot_connect"
|
||||||
|
else:
|
||||||
|
reauth_entry = self._get_reauth_entry()
|
||||||
|
data = {CONF_HOST: self._host, CONF_CLIENT_SECRET: client.client_key}
|
||||||
|
return self.async_update_reload_and_abort(reauth_entry, data=data)
|
||||||
|
|
||||||
reauth_entry = self._get_reauth_entry()
|
return self.async_show_form(step_id="reauth_confirm", errors=errors)
|
||||||
update_client_key(self.hass, reauth_entry, client)
|
|
||||||
await self.hass.config_entries.async_reload(reauth_entry.entry_id)
|
|
||||||
return self.async_abort(reason="reauth_successful")
|
|
||||||
|
|
||||||
return self.async_show_form(step_id="reauth_confirm")
|
async def async_step_reconfigure(
|
||||||
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Handle reconfiguration of the integration."""
|
||||||
|
errors: dict[str, str] = {}
|
||||||
|
reconfigure_entry = self._get_reconfigure_entry()
|
||||||
|
|
||||||
|
if user_input is not None:
|
||||||
|
host = user_input[CONF_HOST]
|
||||||
|
client_key = reconfigure_entry.data.get(CONF_CLIENT_SECRET)
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = await async_control_connect(host, client_key)
|
||||||
|
except WebOsTvPairError:
|
||||||
|
errors["base"] = "error_pairing"
|
||||||
|
except WEBOSTV_EXCEPTIONS:
|
||||||
|
errors["base"] = "cannot_connect"
|
||||||
|
else:
|
||||||
|
await self.async_set_unique_id(client.hello_info["deviceUUID"])
|
||||||
|
self._abort_if_unique_id_mismatch(reason="wrong_device")
|
||||||
|
data = {CONF_HOST: host, CONF_CLIENT_SECRET: client.client_key}
|
||||||
|
return self.async_update_reload_and_abort(reconfigure_entry, data=data)
|
||||||
|
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="reconfigure",
|
||||||
|
data_schema=vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(
|
||||||
|
CONF_HOST, default=reconfigure_entry.data.get(CONF_HOST)
|
||||||
|
): cv.string
|
||||||
|
}
|
||||||
|
),
|
||||||
|
errors=errors,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class OptionsFlowHandler(OptionsFlow):
|
class OptionsFlowHandler(OptionsFlow):
|
||||||
|
|
|
@ -7,9 +7,7 @@ rules:
|
||||||
status: exempt
|
status: exempt
|
||||||
comment: The integration does not use common patterns.
|
comment: The integration does not use common patterns.
|
||||||
config-flow-test-coverage: done
|
config-flow-test-coverage: done
|
||||||
config-flow:
|
config-flow: done
|
||||||
status: todo
|
|
||||||
comment: make reauth flow more graceful
|
|
||||||
dependency-transparency: done
|
dependency-transparency: done
|
||||||
docs-actions:
|
docs-actions:
|
||||||
status: todo
|
status: todo
|
||||||
|
@ -66,7 +64,7 @@ rules:
|
||||||
icon-translations:
|
icon-translations:
|
||||||
status: exempt
|
status: exempt
|
||||||
comment: The only entity can use the device class.
|
comment: The only entity can use the device class.
|
||||||
reconfiguration-flow: todo
|
reconfiguration-flow: done
|
||||||
repair-issues:
|
repair-issues:
|
||||||
status: exempt
|
status: exempt
|
||||||
comment: The integration does not have anything to repair.
|
comment: The integration does not have anything to repair.
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"host": "[%key:common::config_flow::data::host%]"
|
"host": "[%key:common::config_flow::data::host%]"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"host": "Hostname or IP address of your webOS TV."
|
"host": "Hostname or IP address of your LG webOS TV."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pairing": {
|
"pairing": {
|
||||||
|
@ -18,17 +18,26 @@
|
||||||
"reauth_confirm": {
|
"reauth_confirm": {
|
||||||
"title": "[%key:component::webostv::config::step::pairing::title%]",
|
"title": "[%key:component::webostv::config::step::pairing::title%]",
|
||||||
"description": "[%key:component::webostv::config::step::pairing::description%]"
|
"description": "[%key:component::webostv::config::step::pairing::description%]"
|
||||||
|
},
|
||||||
|
"reconfigure": {
|
||||||
|
"data": {
|
||||||
|
"host": "[%key:common::config_flow::data::host%]"
|
||||||
|
},
|
||||||
|
"data_description": {
|
||||||
|
"host": "[%key:component::webostv::config::step::user::data_description::host%]"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"cannot_connect": "Failed to connect, please turn on your TV or check the IP address"
|
"cannot_connect": "Failed to connect, please turn on your TV and try again.",
|
||||||
|
"error_pairing": "Pairing failed, make sure to accept the pairing request on the TV and try again."
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
"error_pairing": "Connected to LG webOS TV but not paired",
|
|
||||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||||
"reauth_unsuccessful": "Re-authentication was unsuccessful, please turn on your TV and try again."
|
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
|
||||||
|
"wrong_device": "The configured device is not the same found on this Hostname or IP address."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
@ -38,6 +47,9 @@
|
||||||
"description": "Select enabled sources",
|
"description": "Select enabled sources",
|
||||||
"data": {
|
"data": {
|
||||||
"sources": "Sources list"
|
"sources": "Sources list"
|
||||||
|
},
|
||||||
|
"data_description": {
|
||||||
|
"sources": "List of sources to enable"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
"""Test the WebOS Tv config flow."""
|
"""Test the WebOS Tv config flow."""
|
||||||
|
|
||||||
from unittest.mock import AsyncMock
|
|
||||||
|
|
||||||
from aiowebostv import WebOsTvPairError
|
from aiowebostv import WebOsTvPairError
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -105,7 +103,7 @@ async def test_options_flow_cannot_retrieve(hass: HomeAssistant, client) -> None
|
||||||
"""Test options config flow cannot retrieve sources."""
|
"""Test options config flow cannot retrieve sources."""
|
||||||
entry = await setup_webostv(hass)
|
entry = await setup_webostv(hass)
|
||||||
|
|
||||||
client.connect = AsyncMock(side_effect=ConnectionRefusedError())
|
client.connect.side_effect = ConnectionRefusedError
|
||||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -113,7 +111,7 @@ async def test_options_flow_cannot_retrieve(hass: HomeAssistant, client) -> None
|
||||||
assert result["errors"] == {"base": "cannot_retrieve"}
|
assert result["errors"] == {"base": "cannot_retrieve"}
|
||||||
|
|
||||||
# recover
|
# recover
|
||||||
client.connect = AsyncMock(return_value=True)
|
client.connect.side_effect = None
|
||||||
result = await hass.config_entries.options.async_configure(
|
result = await hass.config_entries.options.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input=None,
|
user_input=None,
|
||||||
|
@ -139,7 +137,7 @@ async def test_form_cannot_connect(hass: HomeAssistant, client) -> None:
|
||||||
data=MOCK_USER_CONFIG,
|
data=MOCK_USER_CONFIG,
|
||||||
)
|
)
|
||||||
|
|
||||||
client.connect = AsyncMock(side_effect=ConnectionRefusedError())
|
client.connect.side_effect = ConnectionRefusedError
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input={}
|
result["flow_id"], user_input={}
|
||||||
)
|
)
|
||||||
|
@ -148,7 +146,7 @@ async def test_form_cannot_connect(hass: HomeAssistant, client) -> None:
|
||||||
assert result["errors"] == {"base": "cannot_connect"}
|
assert result["errors"] == {"base": "cannot_connect"}
|
||||||
|
|
||||||
# recover
|
# recover
|
||||||
client.connect = AsyncMock(return_value=True)
|
client.connect.side_effect = None
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input={}
|
result["flow_id"], user_input={}
|
||||||
)
|
)
|
||||||
|
@ -165,13 +163,22 @@ async def test_form_pairexception(hass: HomeAssistant, client) -> None:
|
||||||
data=MOCK_USER_CONFIG,
|
data=MOCK_USER_CONFIG,
|
||||||
)
|
)
|
||||||
|
|
||||||
client.connect = AsyncMock(side_effect=WebOsTvPairError("error"))
|
client.connect.side_effect = WebOsTvPairError
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input={}
|
result["flow_id"], user_input={}
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["reason"] == "error_pairing"
|
assert result["errors"] == {"base": "error_pairing"}
|
||||||
|
|
||||||
|
# recover
|
||||||
|
client.connect.side_effect = None
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input={}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
|
assert result["title"] == TV_NAME
|
||||||
|
|
||||||
|
|
||||||
async def test_entry_already_configured(hass: HomeAssistant, client) -> None:
|
async def test_entry_already_configured(hass: HomeAssistant, client) -> None:
|
||||||
|
@ -267,9 +274,7 @@ async def test_form_abort_uuid_configured(hass: HomeAssistant, client) -> None:
|
||||||
assert entry.data[CONF_HOST] == "new_host"
|
assert entry.data[CONF_HOST] == "new_host"
|
||||||
|
|
||||||
|
|
||||||
async def test_reauth_successful(
|
async def test_reauth_successful(hass: HomeAssistant, client) -> None:
|
||||||
hass: HomeAssistant, client, monkeypatch: pytest.MonkeyPatch
|
|
||||||
) -> None:
|
|
||||||
"""Test that the reauthorization is successful."""
|
"""Test that the reauthorization is successful."""
|
||||||
entry = await setup_webostv(hass)
|
entry = await setup_webostv(hass)
|
||||||
|
|
||||||
|
@ -282,7 +287,7 @@ async def test_reauth_successful(
|
||||||
assert result["step_id"] == "reauth_confirm"
|
assert result["step_id"] == "reauth_confirm"
|
||||||
assert entry.data[CONF_CLIENT_SECRET] == CLIENT_KEY
|
assert entry.data[CONF_CLIENT_SECRET] == CLIENT_KEY
|
||||||
|
|
||||||
monkeypatch.setattr(client, "client_key", "new_key")
|
client.client_key = "new_key"
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input={}
|
result["flow_id"], user_input={}
|
||||||
)
|
)
|
||||||
|
@ -293,15 +298,13 @@ async def test_reauth_successful(
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("side_effect", "reason"),
|
("side_effect", "error"),
|
||||||
[
|
[
|
||||||
(WebOsTvPairError, "error_pairing"),
|
(WebOsTvPairError, "error_pairing"),
|
||||||
(ConnectionRefusedError, "reauth_unsuccessful"),
|
(ConnectionRefusedError, "cannot_connect"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_reauth_errors(
|
async def test_reauth_errors(hass: HomeAssistant, client, side_effect, error) -> None:
|
||||||
hass: HomeAssistant, client, monkeypatch: pytest.MonkeyPatch, side_effect, reason
|
|
||||||
) -> None:
|
|
||||||
"""Test reauthorization errors."""
|
"""Test reauthorization errors."""
|
||||||
entry = await setup_webostv(hass)
|
entry = await setup_webostv(hass)
|
||||||
|
|
||||||
|
@ -318,5 +321,88 @@ async def test_reauth_errors(
|
||||||
result["flow_id"], user_input={}
|
result["flow_id"], user_input={}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["errors"] == {"base": error}
|
||||||
|
|
||||||
|
client.connect.side_effect = None
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input={}
|
||||||
|
)
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
assert result["type"] is FlowResultType.ABORT
|
||||||
assert result["reason"] == reason
|
assert result["reason"] == "reauth_successful"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_reconfigure_successful(hass: HomeAssistant, client) -> None:
|
||||||
|
"""Test that the reconfigure is successful."""
|
||||||
|
entry = await setup_webostv(hass)
|
||||||
|
|
||||||
|
result = await entry.start_reconfigure_flow(hass)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "reconfigure"
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={CONF_HOST: "new_host"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "reconfigure_successful"
|
||||||
|
assert entry.data[CONF_HOST] == "new_host"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("side_effect", "error"),
|
||||||
|
[
|
||||||
|
(WebOsTvPairError, "error_pairing"),
|
||||||
|
(ConnectionRefusedError, "cannot_connect"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_reconfigure_errors(
|
||||||
|
hass: HomeAssistant, client, side_effect, error
|
||||||
|
) -> None:
|
||||||
|
"""Test reconfigure errors."""
|
||||||
|
entry = await setup_webostv(hass)
|
||||||
|
|
||||||
|
result = await entry.start_reconfigure_flow(hass)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "reconfigure"
|
||||||
|
|
||||||
|
client.connect.side_effect = side_effect
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={CONF_HOST: "new_host"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["errors"] == {"base": error}
|
||||||
|
|
||||||
|
client.connect.side_effect = None
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={CONF_HOST: "new_host"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "reconfigure_successful"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_reconfigure_wrong_device(hass: HomeAssistant, client) -> None:
|
||||||
|
"""Test abort if reconfigure host is wrong webOS TV device."""
|
||||||
|
entry = await setup_webostv(hass)
|
||||||
|
|
||||||
|
result = await entry.start_reconfigure_flow(hass)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "reconfigure"
|
||||||
|
|
||||||
|
client.hello_info = {"deviceUUID": "wrong_uuid"}
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={CONF_HOST: "new_host"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "wrong_device"
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
"""The tests for the LG webOS TV platform."""
|
"""The tests for the LG webOS TV platform."""
|
||||||
|
|
||||||
from unittest.mock import Mock
|
|
||||||
|
|
||||||
from aiowebostv import WebOsTvPairError
|
from aiowebostv import WebOsTvPairError
|
||||||
import pytest
|
|
||||||
|
|
||||||
from homeassistant.components.media_player import ATTR_INPUT_SOURCE_LIST
|
from homeassistant.components.media_player import ATTR_INPUT_SOURCE_LIST
|
||||||
from homeassistant.components.webostv.const import CONF_SOURCES, DOMAIN
|
from homeassistant.components.webostv.const import CONF_SOURCES, DOMAIN
|
||||||
|
@ -15,12 +12,10 @@ from . import setup_webostv
|
||||||
from .const import ENTITY_ID
|
from .const import ENTITY_ID
|
||||||
|
|
||||||
|
|
||||||
async def test_reauth_setup_entry(
|
async def test_reauth_setup_entry(hass: HomeAssistant, client) -> None:
|
||||||
hass: HomeAssistant, client, monkeypatch: pytest.MonkeyPatch
|
|
||||||
) -> None:
|
|
||||||
"""Test reauth flow triggered by setup entry."""
|
"""Test reauth flow triggered by setup entry."""
|
||||||
monkeypatch.setattr(client, "is_connected", Mock(return_value=False))
|
client.is_connected.return_value = False
|
||||||
monkeypatch.setattr(client, "connect", Mock(side_effect=WebOsTvPairError))
|
client.connect.side_effect = WebOsTvPairError
|
||||||
entry = await setup_webostv(hass)
|
entry = await setup_webostv(hass)
|
||||||
|
|
||||||
assert entry.state is ConfigEntryState.SETUP_ERROR
|
assert entry.state is ConfigEntryState.SETUP_ERROR
|
||||||
|
@ -37,11 +32,9 @@ async def test_reauth_setup_entry(
|
||||||
assert flow["context"].get("entry_id") == entry.entry_id
|
assert flow["context"].get("entry_id") == entry.entry_id
|
||||||
|
|
||||||
|
|
||||||
async def test_key_update_setup_entry(
|
async def test_key_update_setup_entry(hass: HomeAssistant, client) -> None:
|
||||||
hass: HomeAssistant, client, monkeypatch: pytest.MonkeyPatch
|
|
||||||
) -> None:
|
|
||||||
"""Test key update from setup entry."""
|
"""Test key update from setup entry."""
|
||||||
monkeypatch.setattr(client, "client_key", "new_key")
|
client.client_key = "new_key"
|
||||||
entry = await setup_webostv(hass)
|
entry = await setup_webostv(hass)
|
||||||
|
|
||||||
assert entry.state is ConfigEntryState.LOADED
|
assert entry.state is ConfigEntryState.LOADED
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""The tests for the WebOS TV notify platform."""
|
"""The tests for the WebOS TV notify platform."""
|
||||||
|
|
||||||
from unittest.mock import Mock, call
|
from unittest.mock import call
|
||||||
|
|
||||||
from aiowebostv import WebOsTvPairError
|
from aiowebostv import WebOsTvPairError
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -74,14 +74,12 @@ async def test_notify(hass: HomeAssistant, client) -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_notify_not_connected(
|
async def test_notify_not_connected(hass: HomeAssistant, client) -> None:
|
||||||
hass: HomeAssistant, client, monkeypatch: pytest.MonkeyPatch
|
|
||||||
) -> None:
|
|
||||||
"""Test sending a message when client is not connected."""
|
"""Test sending a message when client is not connected."""
|
||||||
await setup_webostv(hass)
|
await setup_webostv(hass)
|
||||||
assert hass.services.has_service(NOTIFY_DOMAIN, SERVICE_NAME)
|
assert hass.services.has_service(NOTIFY_DOMAIN, SERVICE_NAME)
|
||||||
|
|
||||||
monkeypatch.setattr(client, "is_connected", Mock(return_value=False))
|
client.is_connected.return_value = False
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
NOTIFY_DOMAIN,
|
NOTIFY_DOMAIN,
|
||||||
SERVICE_NAME,
|
SERVICE_NAME,
|
||||||
|
@ -99,16 +97,13 @@ async def test_notify_not_connected(
|
||||||
|
|
||||||
|
|
||||||
async def test_icon_not_found(
|
async def test_icon_not_found(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant, caplog: pytest.LogCaptureFixture, client
|
||||||
caplog: pytest.LogCaptureFixture,
|
|
||||||
client,
|
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test notify icon not found error."""
|
"""Test notify icon not found error."""
|
||||||
await setup_webostv(hass)
|
await setup_webostv(hass)
|
||||||
assert hass.services.has_service(NOTIFY_DOMAIN, SERVICE_NAME)
|
assert hass.services.has_service(NOTIFY_DOMAIN, SERVICE_NAME)
|
||||||
|
|
||||||
monkeypatch.setattr(client, "send_message", Mock(side_effect=FileNotFoundError))
|
client.send_message.side_effect = FileNotFoundError
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
NOTIFY_DOMAIN,
|
NOTIFY_DOMAIN,
|
||||||
SERVICE_NAME,
|
SERVICE_NAME,
|
||||||
|
@ -134,19 +129,14 @@ async def test_icon_not_found(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_connection_errors(
|
async def test_connection_errors(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant, caplog: pytest.LogCaptureFixture, client, side_effect, error
|
||||||
caplog: pytest.LogCaptureFixture,
|
|
||||||
client,
|
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
|
||||||
side_effect,
|
|
||||||
error,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test connection errors scenarios."""
|
"""Test connection errors scenarios."""
|
||||||
await setup_webostv(hass)
|
await setup_webostv(hass)
|
||||||
assert hass.services.has_service("notify", SERVICE_NAME)
|
assert hass.services.has_service("notify", SERVICE_NAME)
|
||||||
|
|
||||||
monkeypatch.setattr(client, "is_connected", Mock(return_value=False))
|
client.is_connected.return_value = False
|
||||||
monkeypatch.setattr(client, "connect", Mock(side_effect=side_effect))
|
client.connect.side_effect = side_effect
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
NOTIFY_DOMAIN,
|
NOTIFY_DOMAIN,
|
||||||
SERVICE_NAME,
|
SERVICE_NAME,
|
||||||
|
@ -159,7 +149,7 @@ async def test_connection_errors(
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
assert client.mock_calls[0] == call.connect()
|
assert client.mock_calls[0] == call.connect()
|
||||||
assert client.connect.call_count == 1
|
assert client.connect.call_count == 2
|
||||||
client.send_message.assert_not_called()
|
client.send_message.assert_not_called()
|
||||||
assert error in caplog.text
|
assert error in caplog.text
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue