mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 17:27:10 +00:00
Raise ConfigEntryNotReady mqtt setup fails In LG ThinQ (#140488)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
This commit is contained in:
parent
35f9cc55f1
commit
83f2acddf8
@ -22,7 +22,7 @@ from homeassistant.helpers import device_registry as dr
|
|||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.event import async_track_time_interval
|
from homeassistant.helpers.event import async_track_time_interval
|
||||||
|
|
||||||
from .const import CONF_CONNECT_CLIENT_ID, MQTT_SUBSCRIPTION_INTERVAL
|
from .const import CONF_CONNECT_CLIENT_ID, DOMAIN, MQTT_SUBSCRIPTION_INTERVAL
|
||||||
from .coordinator import DeviceDataUpdateCoordinator, async_setup_device_coordinator
|
from .coordinator import DeviceDataUpdateCoordinator, async_setup_device_coordinator
|
||||||
from .mqtt import ThinQMQTT
|
from .mqtt import ThinQMQTT
|
||||||
|
|
||||||
@ -137,7 +137,15 @@ async def async_setup_mqtt(
|
|||||||
entry.runtime_data.mqtt_client = mqtt_client
|
entry.runtime_data.mqtt_client = mqtt_client
|
||||||
|
|
||||||
# Try to connect.
|
# Try to connect.
|
||||||
|
try:
|
||||||
result = await mqtt_client.async_connect()
|
result = await mqtt_client.async_connect()
|
||||||
|
except (AttributeError, ThinQAPIException, TypeError, ValueError) as exc:
|
||||||
|
raise ConfigEntryNotReady(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="failed_to_connect_mqtt",
|
||||||
|
translation_placeholders={"error": str(exc)},
|
||||||
|
) from exc
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
_LOGGER.error("Failed to set up mqtt connection")
|
_LOGGER.error("Failed to set up mqtt connection")
|
||||||
return
|
return
|
||||||
|
@ -43,7 +43,7 @@ class ThinQMQTT:
|
|||||||
|
|
||||||
async def async_connect(self) -> bool:
|
async def async_connect(self) -> bool:
|
||||||
"""Create a mqtt client and then try to connect."""
|
"""Create a mqtt client and then try to connect."""
|
||||||
try:
|
|
||||||
self.client = await ThinQMQTTClient(
|
self.client = await ThinQMQTTClient(
|
||||||
self.thinq_api, self.client_id, self.on_message_received
|
self.thinq_api, self.client_id, self.on_message_received
|
||||||
)
|
)
|
||||||
@ -52,9 +52,6 @@ class ThinQMQTT:
|
|||||||
|
|
||||||
# Connect to server and create certificate.
|
# Connect to server and create certificate.
|
||||||
return await self.client.async_prepare_mqtt()
|
return await self.client.async_prepare_mqtt()
|
||||||
except (ThinQAPIException, TypeError, ValueError):
|
|
||||||
_LOGGER.exception("Failed to connect")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def async_disconnect(self, event: Event | None = None) -> None:
|
async def async_disconnect(self, event: Event | None = None) -> None:
|
||||||
"""Unregister client and disconnects handlers."""
|
"""Unregister client and disconnects handlers."""
|
||||||
|
@ -1034,5 +1034,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"exceptions": {
|
||||||
|
"failed_to_connect_mqtt": {
|
||||||
|
"message": "Failed to connect MQTT: {error}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ def mock_uuid() -> Generator[AsyncMock]:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_thinq_api(mock_thinq_mqtt_client: AsyncMock) -> Generator[AsyncMock]:
|
def mock_config_thinq_api() -> Generator[AsyncMock]:
|
||||||
"""Mock a thinq api."""
|
"""Mock a thinq api."""
|
||||||
with (
|
with (
|
||||||
patch("homeassistant.components.lg_thinq.ThinQApi", autospec=True) as mock_api,
|
patch("homeassistant.components.lg_thinq.ThinQApi", autospec=True) as mock_api,
|
||||||
@ -77,6 +77,26 @@ def mock_thinq_api(mock_thinq_mqtt_client: AsyncMock) -> Generator[AsyncMock]:
|
|||||||
new=mock_api,
|
new=mock_api,
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
|
thinq_api = mock_api.return_value
|
||||||
|
thinq_api.async_get_device_list.return_value = ["air_conditioner"]
|
||||||
|
yield thinq_api
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_invalid_thinq_api(mock_config_thinq_api: AsyncMock) -> AsyncMock:
|
||||||
|
"""Mock an invalid thinq api."""
|
||||||
|
mock_config_thinq_api.async_get_device_list = AsyncMock(
|
||||||
|
side_effect=ThinQAPIException(
|
||||||
|
code="1309", message="Not allowed api call", headers=None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return mock_config_thinq_api
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_thinq_api() -> Generator[AsyncMock]:
|
||||||
|
"""Mock a thinq api."""
|
||||||
|
with patch("homeassistant.components.lg_thinq.ThinQApi", autospec=True) as mock_api:
|
||||||
thinq_api = mock_api.return_value
|
thinq_api = mock_api.return_value
|
||||||
thinq_api.async_get_device_list.return_value = [
|
thinq_api.async_get_device_list.return_value = [
|
||||||
load_json_object_fixture("air_conditioner/device.json", DOMAIN)
|
load_json_object_fixture("air_conditioner/device.json", DOMAIN)
|
||||||
@ -92,19 +112,10 @@ def mock_thinq_api(mock_thinq_mqtt_client: AsyncMock) -> Generator[AsyncMock]:
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_thinq_mqtt_client() -> Generator[AsyncMock]:
|
def mock_thinq_mqtt_client() -> Generator[AsyncMock]:
|
||||||
"""Mock a thinq api."""
|
"""Mock a thinq mqtt client."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.lg_thinq.mqtt.ThinQMQTTClient", autospec=True
|
"homeassistant.components.lg_thinq.mqtt.ThinQMQTTClient",
|
||||||
) as mock_api:
|
autospec=True,
|
||||||
yield mock_api
|
return_value=True,
|
||||||
|
):
|
||||||
|
yield
|
||||||
@pytest.fixture
|
|
||||||
def mock_invalid_thinq_api(mock_thinq_api: AsyncMock) -> AsyncMock:
|
|
||||||
"""Mock an invalid thinq api."""
|
|
||||||
mock_thinq_api.async_get_device_list = AsyncMock(
|
|
||||||
side_effect=ThinQAPIException(
|
|
||||||
code="1309", message="Not allowed api call", headers=None
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return mock_thinq_api
|
|
||||||
|
@ -15,7 +15,7 @@ from tests.common import MockConfigEntry
|
|||||||
|
|
||||||
async def test_config_flow(
|
async def test_config_flow(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_thinq_api: AsyncMock,
|
mock_config_thinq_api: AsyncMock,
|
||||||
mock_uuid: AsyncMock,
|
mock_uuid: AsyncMock,
|
||||||
mock_setup_entry: AsyncMock,
|
mock_setup_entry: AsyncMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -37,11 +37,12 @@ async def test_config_flow(
|
|||||||
CONF_CONNECT_CLIENT_ID: MOCK_CONNECT_CLIENT_ID,
|
CONF_CONNECT_CLIENT_ID: MOCK_CONNECT_CLIENT_ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
mock_thinq_api.async_get_device_list.assert_called_once()
|
mock_config_thinq_api.async_get_device_list.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
async def test_config_flow_invalid_pat(
|
async def test_config_flow_invalid_pat(
|
||||||
hass: HomeAssistant, mock_invalid_thinq_api: AsyncMock
|
hass: HomeAssistant,
|
||||||
|
mock_invalid_thinq_api: AsyncMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that an thinq flow should be aborted with an invalid PAT."""
|
"""Test that an thinq flow should be aborted with an invalid PAT."""
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
@ -55,7 +56,9 @@ async def test_config_flow_invalid_pat(
|
|||||||
|
|
||||||
|
|
||||||
async def test_config_flow_already_configured(
|
async def test_config_flow_already_configured(
|
||||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_thinq_api: AsyncMock
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_config_thinq_api: AsyncMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that thinq flow should be aborted when already configured."""
|
"""Test that thinq flow should be aborted when already configured."""
|
||||||
mock_config_entry.add_to_hass(hass)
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
@ -1,22 +1,29 @@
|
|||||||
"""Tests for the LG ThinQ integration."""
|
"""Tests for the LG ThinQ integration."""
|
||||||
|
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from . import setup_integration
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
async def test_load_unload_entry(
|
async def test_load_unload_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_thinq_api: AsyncMock,
|
mock_thinq_api: AsyncMock,
|
||||||
|
mock_thinq_mqtt_client: AsyncMock,
|
||||||
mock_config_entry: MockConfigEntry,
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test load and unload entry."""
|
"""Test load and unload entry."""
|
||||||
mock_config_entry.add_to_hass(hass)
|
with patch(
|
||||||
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
"homeassistant.components.lg_thinq.ThinQMQTT.async_connect",
|
||||||
await hass.async_block_till_done()
|
return_value=True,
|
||||||
|
):
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
@ -24,3 +31,21 @@ async def test_load_unload_entry(
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("exception", [AttributeError(), TypeError(), ValueError()])
|
||||||
|
async def test_config_not_ready(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_thinq_api: AsyncMock,
|
||||||
|
mock_thinq_mqtt_client: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
exception: Exception,
|
||||||
|
) -> None:
|
||||||
|
"""Test for setup failure exception occurred."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.lg_thinq.ThinQMQTT.async_connect",
|
||||||
|
side_effect=exception,
|
||||||
|
):
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
Loading…
x
Reference in New Issue
Block a user