mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Add test coverage to Twente Milieu (#59640)
This commit is contained in:
parent
da8bfed793
commit
458bc92124
@ -1139,9 +1139,6 @@ omit =
|
|||||||
homeassistant/components/tuya/switch.py
|
homeassistant/components/tuya/switch.py
|
||||||
homeassistant/components/tuya/util.py
|
homeassistant/components/tuya/util.py
|
||||||
homeassistant/components/tuya/vacuum.py
|
homeassistant/components/tuya/vacuum.py
|
||||||
homeassistant/components/twentemilieu/__init__.py
|
|
||||||
homeassistant/components/twentemilieu/const.py
|
|
||||||
homeassistant/components/twentemilieu/sensor.py
|
|
||||||
homeassistant/components/twilio_call/notify.py
|
homeassistant/components/twilio_call/notify.py
|
||||||
homeassistant/components/twilio_sms/notify.py
|
homeassistant/components/twilio_sms/notify.py
|
||||||
homeassistant/components/twitter/notify.py
|
homeassistant/components/twitter/notify.py
|
||||||
|
@ -46,7 +46,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
|
|
||||||
# For backwards compat, set unique ID
|
# For backwards compat, set unique ID
|
||||||
if entry.unique_id is None:
|
if entry.unique_id is None:
|
||||||
hass.config_entries.async_update_entry(entry, unique_id=entry.data[CONF_ID])
|
hass.config_entries.async_update_entry(
|
||||||
|
entry, unique_id=str(entry.data[CONF_ID])
|
||||||
|
)
|
||||||
|
|
||||||
hass.data.setdefault(DOMAIN, {})[entry.data[CONF_ID]] = coordinator
|
hass.data.setdefault(DOMAIN, {})[entry.data[CONF_ID]] = coordinator
|
||||||
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
||||||
@ -58,5 +60,5 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
"""Unload Twente Milieu config entry."""
|
"""Unload Twente Milieu config entry."""
|
||||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
if unload_ok:
|
if unload_ok:
|
||||||
del hass.data[DOMAIN][entry.entry_id]
|
del hass.data[DOMAIN][entry.data[CONF_ID]]
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
@ -11,3 +11,5 @@ SCAN_INTERVAL = timedelta(hours=1)
|
|||||||
CONF_POST_CODE = "post_code"
|
CONF_POST_CODE = "post_code"
|
||||||
CONF_HOUSE_NUMBER = "house_number"
|
CONF_HOUSE_NUMBER = "house_number"
|
||||||
CONF_HOUSE_LETTER = "house_letter"
|
CONF_HOUSE_LETTER = "house_letter"
|
||||||
|
|
||||||
|
ENTRY_TYPE_SERVICE: Final = "service"
|
||||||
|
@ -5,5 +5,6 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/twentemilieu",
|
"documentation": "https://www.home-assistant.io/integrations/twentemilieu",
|
||||||
"requirements": ["twentemilieu==0.4.2"],
|
"requirements": ["twentemilieu==0.4.2"],
|
||||||
"codeowners": ["@frenck"],
|
"codeowners": ["@frenck"],
|
||||||
|
"quality_scale": "platinum",
|
||||||
"iot_class": "cloud_polling"
|
"iot_class": "cloud_polling"
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ from homeassistant.helpers.update_coordinator import (
|
|||||||
DataUpdateCoordinator,
|
DataUpdateCoordinator,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN, ENTRY_TYPE_SERVICE
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -97,7 +97,8 @@ class TwenteMilieuSensor(CoordinatorEntity, SensorEntity):
|
|||||||
self._attr_unique_id = f"{DOMAIN}_{entry.data[CONF_ID]}_{description.key}"
|
self._attr_unique_id = f"{DOMAIN}_{entry.data[CONF_ID]}_{description.key}"
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
configuration_url="https://www.twentemilieu.nl",
|
configuration_url="https://www.twentemilieu.nl",
|
||||||
identifiers={(DOMAIN, entry.data[CONF_ID])},
|
entry_type=ENTRY_TYPE_SERVICE,
|
||||||
|
identifiers={(DOMAIN, str(entry.data[CONF_ID]))},
|
||||||
manufacturer="Twente Milieu",
|
manufacturer="Twente Milieu",
|
||||||
name="Twente Milieu",
|
name="Twente Milieu",
|
||||||
)
|
)
|
||||||
|
88
tests/components/twentemilieu/conftest.py
Normal file
88
tests/components/twentemilieu/conftest.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
"""Fixtures for the Twente Milieu integration tests."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Generator
|
||||||
|
from datetime import date
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from twentemilieu import WasteType
|
||||||
|
|
||||||
|
from homeassistant.components.twentemilieu.const import (
|
||||||
|
CONF_HOUSE_LETTER,
|
||||||
|
CONF_HOUSE_NUMBER,
|
||||||
|
CONF_POST_CODE,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
|
from homeassistant.const import CONF_ID
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_config_entry() -> MockConfigEntry:
|
||||||
|
"""Return the default mocked config entry."""
|
||||||
|
return MockConfigEntry(
|
||||||
|
title="1234AB 1",
|
||||||
|
domain=DOMAIN,
|
||||||
|
data={
|
||||||
|
CONF_ID: 12345,
|
||||||
|
CONF_POST_CODE: "1234AB",
|
||||||
|
CONF_HOUSE_NUMBER: "1",
|
||||||
|
CONF_HOUSE_LETTER: "A",
|
||||||
|
},
|
||||||
|
unique_id="12345",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_setup_entry() -> Generator[None, None, None]:
|
||||||
|
"""Mock setting up a config entry."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.twentemilieu.async_setup_entry", return_value=True
|
||||||
|
):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_twentemilieu_config_flow() -> Generator[None, MagicMock, None]:
|
||||||
|
"""Return a mocked Twente Milieu client."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.twentemilieu.config_flow.TwenteMilieu", autospec=True
|
||||||
|
) as twentemilieu_mock:
|
||||||
|
twentemilieu = twentemilieu_mock.return_value
|
||||||
|
twentemilieu.unique_id.return_value = 12345
|
||||||
|
yield twentemilieu
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_twentemilieu() -> Generator[None, MagicMock, None]:
|
||||||
|
"""Return a mocked Twente Milieu client."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.twentemilieu.TwenteMilieu", autospec=True
|
||||||
|
) as twentemilieu_mock:
|
||||||
|
twentemilieu = twentemilieu_mock.return_value
|
||||||
|
twentemilieu.unique_id.return_value = 12345
|
||||||
|
twentemilieu.update.return_value = {
|
||||||
|
WasteType.NON_RECYCLABLE: date(2021, 11, 1),
|
||||||
|
WasteType.ORGANIC: date(2021, 11, 2),
|
||||||
|
WasteType.PACKAGES: date(2021, 11, 3),
|
||||||
|
WasteType.PAPER: None,
|
||||||
|
}
|
||||||
|
yield twentemilieu
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
async def init_integration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_twentemilieu: MagicMock,
|
||||||
|
) -> MockConfigEntry:
|
||||||
|
"""Set up the TwenteMilieu integration for testing."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
return mock_config_entry
|
@ -1,7 +1,9 @@
|
|||||||
"""Tests for the Twente Milieu config flow."""
|
"""Tests for the Twente Milieu config flow."""
|
||||||
import aiohttp
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from homeassistant import config_entries, data_entry_flow
|
from twentemilieu import TwenteMilieuAddressError, TwenteMilieuConnectionError
|
||||||
|
|
||||||
|
from homeassistant import config_entries
|
||||||
from homeassistant.components.twentemilieu import config_flow
|
from homeassistant.components.twentemilieu import config_flow
|
||||||
from homeassistant.components.twentemilieu.const import (
|
from homeassistant.components.twentemilieu.const import (
|
||||||
CONF_HOUSE_LETTER,
|
CONF_HOUSE_LETTER,
|
||||||
@ -10,116 +12,139 @@ from homeassistant.components.twentemilieu.const import (
|
|||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import SOURCE_USER
|
from homeassistant.config_entries import SOURCE_USER
|
||||||
from homeassistant.const import CONF_ID, CONTENT_TYPE_JSON
|
from homeassistant.const import CONF_ID
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.data_entry_flow import (
|
||||||
|
RESULT_TYPE_ABORT,
|
||||||
|
RESULT_TYPE_CREATE_ENTRY,
|
||||||
|
RESULT_TYPE_FORM,
|
||||||
|
)
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
|
||||||
|
|
||||||
FIXTURE_USER_INPUT = {
|
|
||||||
|
async def test_full_user_flow(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_twentemilieu_config_flow: MagicMock,
|
||||||
|
mock_setup_entry: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test registering an integration and finishing flow works."""
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.get("type") == RESULT_TYPE_FORM
|
||||||
|
assert result.get("step_id") == SOURCE_USER
|
||||||
|
assert "flow_id" in result
|
||||||
|
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={
|
||||||
CONF_POST_CODE: "1234AB",
|
CONF_POST_CODE: "1234AB",
|
||||||
CONF_HOUSE_NUMBER: "1",
|
CONF_HOUSE_NUMBER: "1",
|
||||||
CONF_HOUSE_LETTER: "A",
|
CONF_HOUSE_LETTER: "A",
|
||||||
}
|
},
|
||||||
|
|
||||||
|
|
||||||
async def test_show_set_form(hass: HomeAssistant) -> None:
|
|
||||||
"""Test that the setup form is served."""
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": SOURCE_USER}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result2.get("type") == RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["step_id"] == "user"
|
assert result2.get("title") == "12345"
|
||||||
|
assert result2.get("data") == {
|
||||||
|
CONF_ID: 12345,
|
||||||
async def test_connection_error(
|
CONF_POST_CODE: "1234AB",
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
CONF_HOUSE_NUMBER: "1",
|
||||||
) -> None:
|
CONF_HOUSE_LETTER: "A",
|
||||||
"""Test we show user form on Twente Milieu connection error."""
|
}
|
||||||
aioclient_mock.post(
|
|
||||||
"https://twentemilieuapi.ximmio.com/api/FetchAdress", exc=aiohttp.ClientError
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=FIXTURE_USER_INPUT
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
|
||||||
assert result["step_id"] == "user"
|
|
||||||
assert result["errors"] == {"base": "cannot_connect"}
|
|
||||||
|
|
||||||
|
|
||||||
async def test_invalid_address(
|
async def test_invalid_address(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
mock_twentemilieu_config_flow: MagicMock,
|
||||||
|
mock_setup_entry: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test we show user form on Twente Milieu invalid address error."""
|
"""Test full user flow when the user enters an incorrect address.
|
||||||
aioclient_mock.post(
|
|
||||||
"https://twentemilieuapi.ximmio.com/api/FetchAdress",
|
|
||||||
json={"dataList": []},
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=FIXTURE_USER_INPUT
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
|
||||||
assert result["step_id"] == "user"
|
|
||||||
assert result["errors"] == {"base": "invalid_address"}
|
|
||||||
|
|
||||||
|
|
||||||
async def test_address_already_set_up(
|
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
|
||||||
) -> None:
|
|
||||||
"""Test we abort if address has already been set up."""
|
|
||||||
MockConfigEntry(
|
|
||||||
domain=DOMAIN,
|
|
||||||
data={**FIXTURE_USER_INPUT, CONF_ID: "12345"},
|
|
||||||
title="12345",
|
|
||||||
unique_id="12345",
|
|
||||||
).add_to_hass(hass)
|
|
||||||
|
|
||||||
aioclient_mock.post(
|
|
||||||
"https://twentemilieuapi.ximmio.com/api/FetchAdress",
|
|
||||||
json={"dataList": [{"UniqueId": "12345"}]},
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
config_flow.DOMAIN,
|
|
||||||
context={"source": config_entries.SOURCE_USER},
|
|
||||||
data=FIXTURE_USER_INPUT,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
|
||||||
assert result["reason"] == "already_configured"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_full_flow_implementation(
|
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
|
||||||
) -> None:
|
|
||||||
"""Test registering an integration and finishing flow works."""
|
|
||||||
aioclient_mock.post(
|
|
||||||
"https://twentemilieuapi.ximmio.com/api/FetchAdress",
|
|
||||||
json={"dataList": [{"UniqueId": "12345"}]},
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
This tests also tests if the user recovers from it by entering a valid
|
||||||
|
address in the second attempt.
|
||||||
|
"""
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result.get("type") == RESULT_TYPE_FORM
|
||||||
assert result["step_id"] == "user"
|
assert result.get("step_id") == SOURCE_USER
|
||||||
|
assert "flow_id" in result
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
mock_twentemilieu_config_flow.unique_id.side_effect = TwenteMilieuAddressError
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
FIXTURE_USER_INPUT,
|
user_input={
|
||||||
|
CONF_POST_CODE: "1234",
|
||||||
|
CONF_HOUSE_NUMBER: "1",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result2.get("type") == RESULT_TYPE_FORM
|
||||||
assert result["title"] == "12345"
|
assert result2.get("step_id") == SOURCE_USER
|
||||||
assert result["data"][CONF_POST_CODE] == FIXTURE_USER_INPUT[CONF_POST_CODE]
|
assert result2.get("errors") == {"base": "invalid_address"}
|
||||||
assert result["data"][CONF_HOUSE_NUMBER] == FIXTURE_USER_INPUT[CONF_HOUSE_NUMBER]
|
assert "flow_id" in result2
|
||||||
assert result["data"][CONF_HOUSE_LETTER] == FIXTURE_USER_INPUT[CONF_HOUSE_LETTER]
|
|
||||||
|
mock_twentemilieu_config_flow.unique_id.side_effect = None
|
||||||
|
result3 = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={
|
||||||
|
CONF_POST_CODE: "1234AB",
|
||||||
|
CONF_HOUSE_NUMBER: "1",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result3.get("type") == RESULT_TYPE_CREATE_ENTRY
|
||||||
|
assert result3.get("title") == "12345"
|
||||||
|
assert result3.get("data") == {
|
||||||
|
CONF_ID: 12345,
|
||||||
|
CONF_POST_CODE: "1234AB",
|
||||||
|
CONF_HOUSE_NUMBER: "1",
|
||||||
|
CONF_HOUSE_LETTER: None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_connection_error(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_twentemilieu_config_flow: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test we show user form on Twente Milieu connection error."""
|
||||||
|
mock_twentemilieu_config_flow.unique_id.side_effect = TwenteMilieuConnectionError
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": SOURCE_USER},
|
||||||
|
data={
|
||||||
|
CONF_POST_CODE: "1234AB",
|
||||||
|
CONF_HOUSE_NUMBER: "1",
|
||||||
|
CONF_HOUSE_LETTER: "A",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.get("type") == RESULT_TYPE_FORM
|
||||||
|
assert result.get("step_id") == SOURCE_USER
|
||||||
|
assert result.get("errors") == {"base": "cannot_connect"}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_address_already_set_up(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_twentemilieu_config_flow: MagicMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test we abort if address has already been set up."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
config_flow.DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_USER},
|
||||||
|
data={
|
||||||
|
CONF_POST_CODE: "1234AB",
|
||||||
|
CONF_HOUSE_NUMBER: "1",
|
||||||
|
CONF_HOUSE_LETTER: "A",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.get("type") == RESULT_TYPE_ABORT
|
||||||
|
assert result.get("reason") == "already_configured"
|
||||||
|
60
tests/components/twentemilieu/test_init.py
Normal file
60
tests/components/twentemilieu/test_init.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
"""Tests for the Twente Milieu integration."""
|
||||||
|
from unittest.mock import AsyncMock, MagicMock, patch
|
||||||
|
|
||||||
|
from homeassistant.components.twentemilieu.const import DOMAIN
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
async def test_load_unload_config_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_twentemilieu: AsyncMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test the Twente Milieu configuration entry loading/unloading."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert not hass.data.get(DOMAIN)
|
||||||
|
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
||||||
|
|
||||||
|
|
||||||
|
@patch(
|
||||||
|
"homeassistant.components.twentemilieu.TwenteMilieu.update",
|
||||||
|
side_effect=RuntimeError,
|
||||||
|
)
|
||||||
|
async def test_config_entry_not_ready(
|
||||||
|
mock_request: MagicMock,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test the Twente Milieu configuration entry not ready."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_request.call_count == 1
|
||||||
|
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
|
async def test_update_config_entry_unique_id(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_twentemilieu: AsyncMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test the we update old config entries with an unique ID."""
|
||||||
|
mock_config_entry.unique_id = None
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_config_entry.unique_id == "12345"
|
78
tests/components/twentemilieu/test_sensor.py
Normal file
78
tests/components/twentemilieu/test_sensor.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
"""Tests for the Twente Milieu sensors."""
|
||||||
|
from homeassistant.components.twentemilieu.const import DOMAIN, ENTRY_TYPE_SERVICE
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_DEVICE_CLASS,
|
||||||
|
ATTR_FRIENDLY_NAME,
|
||||||
|
ATTR_ICON,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
|
DEVICE_CLASS_DATE,
|
||||||
|
STATE_UNKNOWN,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
async def test_waste_pickup_sensors(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test the Twente Milieu waste pickup sensors."""
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
device_registry = dr.async_get(hass)
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.non_recyclable_waste_pickup")
|
||||||
|
entry = entity_registry.async_get("sensor.non_recyclable_waste_pickup")
|
||||||
|
assert entry
|
||||||
|
assert state
|
||||||
|
assert entry.unique_id == "twentemilieu_12345_Non-recyclable"
|
||||||
|
assert state.state == "2021-11-01"
|
||||||
|
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Non-recyclable Waste Pickup"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_DATE
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:delete-empty"
|
||||||
|
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.organic_waste_pickup")
|
||||||
|
entry = entity_registry.async_get("sensor.organic_waste_pickup")
|
||||||
|
assert entry
|
||||||
|
assert state
|
||||||
|
assert entry.unique_id == "twentemilieu_12345_Organic"
|
||||||
|
assert state.state == "2021-11-02"
|
||||||
|
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Organic Waste Pickup"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_DATE
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:delete-empty"
|
||||||
|
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.packages_waste_pickup")
|
||||||
|
entry = entity_registry.async_get("sensor.packages_waste_pickup")
|
||||||
|
assert entry
|
||||||
|
assert state
|
||||||
|
assert entry.unique_id == "twentemilieu_12345_Plastic"
|
||||||
|
assert state.state == "2021-11-03"
|
||||||
|
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Packages Waste Pickup"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_DATE
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:delete-empty"
|
||||||
|
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.paper_waste_pickup")
|
||||||
|
entry = entity_registry.async_get("sensor.paper_waste_pickup")
|
||||||
|
assert entry
|
||||||
|
assert state
|
||||||
|
assert entry.unique_id == "twentemilieu_12345_Paper"
|
||||||
|
assert state.state == STATE_UNKNOWN
|
||||||
|
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Paper Waste Pickup"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_DATE
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:delete-empty"
|
||||||
|
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
|
||||||
|
|
||||||
|
assert entry.device_id
|
||||||
|
device_entry = device_registry.async_get(entry.device_id)
|
||||||
|
assert device_entry
|
||||||
|
assert device_entry.identifiers == {(DOMAIN, "12345")}
|
||||||
|
assert device_entry.manufacturer == "Twente Milieu"
|
||||||
|
assert device_entry.name == "Twente Milieu"
|
||||||
|
assert device_entry.entry_type == ENTRY_TYPE_SERVICE
|
||||||
|
assert device_entry.configuration_url == "https://www.twentemilieu.nl"
|
||||||
|
assert not device_entry.model
|
||||||
|
assert not device_entry.sw_version
|
Loading…
x
Reference in New Issue
Block a user