mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Bump stookwijzer to v1.5.1 (#131567)
This commit is contained in:
parent
1b62e12261
commit
4a8f3eea69
@ -7,8 +7,10 @@ from stookwijzer import Stookwijzer
|
|||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_LATITUDE, CONF_LOCATION, CONF_LONGITUDE, Platform
|
from homeassistant.const import CONF_LATITUDE, CONF_LOCATION, CONF_LONGITUDE, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import issue_registry as ir
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN, LOGGER
|
||||||
|
|
||||||
PLATFORMS = [Platform.SENSOR]
|
PLATFORMS = [Platform.SENSOR]
|
||||||
|
|
||||||
@ -16,8 +18,9 @@ PLATFORMS = [Platform.SENSOR]
|
|||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up Stookwijzer from a config entry."""
|
"""Set up Stookwijzer from a config entry."""
|
||||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = Stookwijzer(
|
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = Stookwijzer(
|
||||||
entry.data[CONF_LOCATION][CONF_LATITUDE],
|
async_get_clientsession(hass),
|
||||||
entry.data[CONF_LOCATION][CONF_LONGITUDE],
|
entry.data[CONF_LATITUDE],
|
||||||
|
entry.data[CONF_LONGITUDE],
|
||||||
)
|
)
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
return True
|
return True
|
||||||
@ -28,3 +31,42 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
|
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
|
||||||
del hass.data[DOMAIN][entry.entry_id]
|
del hass.data[DOMAIN][entry.entry_id]
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
|
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
"""Migrate old entry."""
|
||||||
|
LOGGER.debug("Migrating from version %s", entry.version)
|
||||||
|
|
||||||
|
if entry.version == 1:
|
||||||
|
latitude, longitude = await Stookwijzer.async_transform_coordinates(
|
||||||
|
async_get_clientsession(hass),
|
||||||
|
entry.data[CONF_LOCATION][CONF_LATITUDE],
|
||||||
|
entry.data[CONF_LOCATION][CONF_LONGITUDE],
|
||||||
|
)
|
||||||
|
|
||||||
|
if not latitude or not longitude:
|
||||||
|
ir.async_create_issue(
|
||||||
|
hass,
|
||||||
|
DOMAIN,
|
||||||
|
"location_migration_failed",
|
||||||
|
is_fixable=False,
|
||||||
|
severity=ir.IssueSeverity.ERROR,
|
||||||
|
translation_key="location_migration_failed",
|
||||||
|
translation_placeholders={
|
||||||
|
"entry_title": entry.title,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
hass.config_entries.async_update_entry(
|
||||||
|
entry,
|
||||||
|
version=2,
|
||||||
|
data={
|
||||||
|
CONF_LATITUDE: latitude,
|
||||||
|
CONF_LONGITUDE: longitude,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
LOGGER.debug("Migration to version %s successful", entry.version)
|
||||||
|
|
||||||
|
return True
|
||||||
|
@ -4,10 +4,12 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from stookwijzer import Stookwijzer
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||||
from homeassistant.const import CONF_LATITUDE, CONF_LOCATION, CONF_LONGITUDE
|
from homeassistant.const import CONF_LATITUDE, CONF_LOCATION, CONF_LONGITUDE
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.selector import LocationSelector
|
from homeassistant.helpers.selector import LocationSelector
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
@ -16,21 +18,29 @@ from .const import DOMAIN
|
|||||||
class StookwijzerFlowHandler(ConfigFlow, domain=DOMAIN):
|
class StookwijzerFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
"""Config flow for Stookwijzer."""
|
"""Config flow for Stookwijzer."""
|
||||||
|
|
||||||
VERSION = 1
|
VERSION = 2
|
||||||
|
|
||||||
async def async_step_user(
|
async def async_step_user(
|
||||||
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 = {}
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
|
latitude, longitude = await Stookwijzer.async_transform_coordinates(
|
||||||
|
async_get_clientsession(self.hass),
|
||||||
|
user_input[CONF_LOCATION][CONF_LATITUDE],
|
||||||
|
user_input[CONF_LOCATION][CONF_LONGITUDE],
|
||||||
|
)
|
||||||
|
if latitude and longitude:
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title="Stookwijzer",
|
title="Stookwijzer",
|
||||||
data=user_input,
|
data={CONF_LATITUDE: latitude, CONF_LONGITUDE: longitude},
|
||||||
)
|
)
|
||||||
|
errors["base"] = "unknown"
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="user",
|
step_id="user",
|
||||||
|
errors=errors,
|
||||||
data_schema=vol.Schema(
|
data_schema=vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(
|
vol.Required(
|
||||||
|
@ -1,16 +1,7 @@
|
|||||||
"""Constants for the Stookwijzer integration."""
|
"""Constants for the Stookwijzer integration."""
|
||||||
|
|
||||||
from enum import StrEnum
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Final
|
from typing import Final
|
||||||
|
|
||||||
DOMAIN: Final = "stookwijzer"
|
DOMAIN: Final = "stookwijzer"
|
||||||
LOGGER = logging.getLogger(__package__)
|
LOGGER = logging.getLogger(__package__)
|
||||||
|
|
||||||
|
|
||||||
class StookwijzerState(StrEnum):
|
|
||||||
"""Stookwijzer states for sensor entity."""
|
|
||||||
|
|
||||||
BLUE = "blauw"
|
|
||||||
ORANGE = "oranje"
|
|
||||||
RED = "rood"
|
|
||||||
|
@ -17,16 +17,6 @@ async def async_get_config_entry_diagnostics(
|
|||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""Return diagnostics for a config entry."""
|
"""Return diagnostics for a config entry."""
|
||||||
client: Stookwijzer = hass.data[DOMAIN][entry.entry_id]
|
client: Stookwijzer = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
|
||||||
last_updated = None
|
|
||||||
if client.last_updated:
|
|
||||||
last_updated = client.last_updated.isoformat()
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"state": client.state,
|
"advice": client.advice,
|
||||||
"last_updated": last_updated,
|
|
||||||
"lqi": client.lqi,
|
|
||||||
"windspeed": client.windspeed,
|
|
||||||
"weather": client.weather,
|
|
||||||
"concentrations": client.concentrations,
|
|
||||||
}
|
}
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/stookwijzer",
|
"documentation": "https://www.home-assistant.io/integrations/stookwijzer",
|
||||||
"integration_type": "service",
|
"integration_type": "service",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"requirements": ["stookwijzer==1.3.0"]
|
"requirements": ["stookwijzer==1.5.1"]
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import DOMAIN, StookwijzerState
|
from .const import DOMAIN
|
||||||
|
|
||||||
SCAN_INTERVAL = timedelta(minutes=60)
|
SCAN_INTERVAL = timedelta(minutes=60)
|
||||||
|
|
||||||
@ -30,37 +30,33 @@ async def async_setup_entry(
|
|||||||
class StookwijzerSensor(SensorEntity):
|
class StookwijzerSensor(SensorEntity):
|
||||||
"""Defines a Stookwijzer binary sensor."""
|
"""Defines a Stookwijzer binary sensor."""
|
||||||
|
|
||||||
_attr_attribution = "Data provided by stookwijzer.nu"
|
_attr_attribution = "Data provided by atlasleefomgeving.nl"
|
||||||
_attr_device_class = SensorDeviceClass.ENUM
|
_attr_device_class = SensorDeviceClass.ENUM
|
||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
_attr_name = None
|
_attr_translation_key = "advice"
|
||||||
_attr_translation_key = "stookwijzer"
|
|
||||||
|
|
||||||
def __init__(self, client: Stookwijzer, entry: ConfigEntry) -> None:
|
def __init__(self, client: Stookwijzer, entry: ConfigEntry) -> None:
|
||||||
"""Initialize a Stookwijzer device."""
|
"""Initialize a Stookwijzer device."""
|
||||||
self._client = client
|
self._client = client
|
||||||
self._attr_options = [cls.value for cls in StookwijzerState]
|
self._attr_options = ["code_yellow", "code_orange", "code_red"]
|
||||||
self._attr_unique_id = entry.entry_id
|
self._attr_unique_id = entry.entry_id
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, f"{entry.entry_id}")},
|
identifiers={(DOMAIN, entry.entry_id)},
|
||||||
name="Stookwijzer",
|
manufacturer="Atlas Leefomgeving",
|
||||||
manufacturer="stookwijzer.nu",
|
|
||||||
entry_type=DeviceEntryType.SERVICE,
|
entry_type=DeviceEntryType.SERVICE,
|
||||||
configuration_url="https://www.stookwijzer.nu",
|
configuration_url="https://www.atlasleefomgeving.nl/stookwijzer",
|
||||||
)
|
)
|
||||||
|
|
||||||
def update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
"""Update the data from the Stookwijzer handler."""
|
"""Update the data from the Stookwijzer handler."""
|
||||||
self._client.update()
|
await self._client.async_update()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
"""Return if entity is available."""
|
"""Return if entity is available."""
|
||||||
return self._client.state is not None
|
return self._client.advice is not None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self) -> str | None:
|
def native_value(self) -> str | None:
|
||||||
"""Return the state of the device."""
|
"""Return the state of the device."""
|
||||||
if self._client.state is None:
|
return self._client.advice
|
||||||
return None
|
|
||||||
return StookwijzerState(self._client.state).value
|
|
||||||
|
@ -7,17 +7,27 @@
|
|||||||
"location": "[%key:common::config_flow::data::location%]"
|
"location": "[%key:common::config_flow::data::location%]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
"sensor": {
|
"sensor": {
|
||||||
"stookwijzer": {
|
"advice": {
|
||||||
|
"name": "Advice code",
|
||||||
"state": {
|
"state": {
|
||||||
"blauw": "Blue",
|
"code_yellow": "Yellow",
|
||||||
"oranje": "Orange",
|
"code_orange": "Orange",
|
||||||
"rood": "Red"
|
"code_red": "Red"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"location_migration_failed": {
|
||||||
|
"description": "The Stookwijzer integration was unable to automatically migrate your location to a new format the updated integrations uses.\n\nMake sure you are connected to the internet and restart Home Assistant to try again.\n\nIf this doesn't resolve the error, remove and re-add the integration.",
|
||||||
|
"title": "Migration of your location failed"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2746,7 +2746,7 @@ steamodd==4.21
|
|||||||
stookalert==0.1.4
|
stookalert==0.1.4
|
||||||
|
|
||||||
# homeassistant.components.stookwijzer
|
# homeassistant.components.stookwijzer
|
||||||
stookwijzer==1.3.0
|
stookwijzer==1.5.1
|
||||||
|
|
||||||
# homeassistant.components.streamlabswater
|
# homeassistant.components.streamlabswater
|
||||||
streamlabswater==1.0.1
|
streamlabswater==1.0.1
|
||||||
|
@ -2195,7 +2195,7 @@ steamodd==4.21
|
|||||||
stookalert==0.1.4
|
stookalert==0.1.4
|
||||||
|
|
||||||
# homeassistant.components.stookwijzer
|
# homeassistant.components.stookwijzer
|
||||||
stookwijzer==1.3.0
|
stookwijzer==1.5.1
|
||||||
|
|
||||||
# homeassistant.components.streamlabswater
|
# homeassistant.components.streamlabswater
|
||||||
streamlabswater==1.0.1
|
streamlabswater==1.0.1
|
||||||
|
92
tests/components/stookwijzer/conftest.py
Normal file
92
tests/components/stookwijzer/conftest.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
"""Fixtures for Stookwijzer integration tests."""
|
||||||
|
|
||||||
|
from collections.abc import Generator
|
||||||
|
from unittest.mock import AsyncMock, MagicMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.stookwijzer.const import DOMAIN
|
||||||
|
from homeassistant.const import CONF_LATITUDE, CONF_LOCATION, CONF_LONGITUDE
|
||||||
|
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="Stookwijzer",
|
||||||
|
domain=DOMAIN,
|
||||||
|
data={
|
||||||
|
CONF_LATITUDE: 200000.1234567890,
|
||||||
|
CONF_LONGITUDE: 450000.1234567890,
|
||||||
|
},
|
||||||
|
version=2,
|
||||||
|
entry_id="12345",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_v1_config_entry() -> MockConfigEntry:
|
||||||
|
"""Return the default mocked version 1 config entry."""
|
||||||
|
return MockConfigEntry(
|
||||||
|
title="Stookwijzer",
|
||||||
|
domain=DOMAIN,
|
||||||
|
data={
|
||||||
|
CONF_LOCATION: {
|
||||||
|
CONF_LATITUDE: 1.0,
|
||||||
|
CONF_LONGITUDE: 1.1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
version=1,
|
||||||
|
entry_id="12345",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_setup_entry() -> Generator[AsyncMock]:
|
||||||
|
"""Mock setting up a config entry."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.stookwijzer.async_setup_entry", return_value=True
|
||||||
|
) as mock_setup:
|
||||||
|
yield mock_setup
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_stookwijzer() -> Generator[MagicMock]:
|
||||||
|
"""Return a mocked Stookwijzer client."""
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.stookwijzer.Stookwijzer",
|
||||||
|
autospec=True,
|
||||||
|
) as stookwijzer_mock,
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.stookwijzer.config_flow.Stookwijzer",
|
||||||
|
new=stookwijzer_mock,
|
||||||
|
),
|
||||||
|
):
|
||||||
|
stookwijzer_mock.async_transform_coordinates.return_value = (
|
||||||
|
200000.123456789,
|
||||||
|
450000.123456789,
|
||||||
|
)
|
||||||
|
|
||||||
|
client = stookwijzer_mock.return_value
|
||||||
|
client.advice = "code_yellow"
|
||||||
|
|
||||||
|
yield stookwijzer_mock
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
async def init_integration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_stookwijzer: MagicMock,
|
||||||
|
) -> MockConfigEntry:
|
||||||
|
"""Set up the Stookwijzer 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
|
@ -0,0 +1,6 @@
|
|||||||
|
# serializer version: 1
|
||||||
|
# name: test_get_diagnostics
|
||||||
|
dict({
|
||||||
|
'advice': 'code_yellow',
|
||||||
|
})
|
||||||
|
# ---
|
60
tests/components/stookwijzer/snapshots/test_sensor.ambr
Normal file
60
tests/components/stookwijzer/snapshots/test_sensor.ambr
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# serializer version: 1
|
||||||
|
# name: test_entities[sensor.stookwijzer_advice_code-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'options': list([
|
||||||
|
'code_yellow',
|
||||||
|
'code_orange',
|
||||||
|
'code_red',
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'sensor.stookwijzer_advice_code',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Advice code',
|
||||||
|
'platform': 'stookwijzer',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'advice',
|
||||||
|
'unique_id': '12345',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_entities[sensor.stookwijzer_advice_code-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by atlasleefomgeving.nl',
|
||||||
|
'device_class': 'enum',
|
||||||
|
'friendly_name': 'Stookwijzer Advice code',
|
||||||
|
'options': list([
|
||||||
|
'code_yellow',
|
||||||
|
'code_orange',
|
||||||
|
'code_red',
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.stookwijzer_advice_code',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'code_yellow',
|
||||||
|
})
|
||||||
|
# ---
|
@ -1,6 +1,8 @@
|
|||||||
"""Tests for the Stookwijzer config flow."""
|
"""Tests for the Stookwijzer config flow."""
|
||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import AsyncMock, MagicMock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.stookwijzer.const import DOMAIN
|
from homeassistant.components.stookwijzer.const import DOMAIN
|
||||||
from homeassistant.config_entries import SOURCE_USER
|
from homeassistant.config_entries import SOURCE_USER
|
||||||
@ -9,35 +11,65 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
|
||||||
|
|
||||||
async def test_full_user_flow(hass: HomeAssistant) -> None:
|
async def test_full_user_flow(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_stookwijzer: MagicMock,
|
||||||
|
mock_setup_entry: AsyncMock,
|
||||||
|
) -> None:
|
||||||
"""Test the full user configuration flow."""
|
"""Test the full user configuration flow."""
|
||||||
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.get("type") is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result.get("step_id") == "user"
|
assert result["step_id"] == "user"
|
||||||
assert "flow_id" in result
|
|
||||||
|
|
||||||
with patch(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
"homeassistant.components.stookwijzer.async_setup_entry", return_value=True
|
|
||||||
) as mock_setup_entry:
|
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input={
|
user_input={CONF_LOCATION: {CONF_LATITUDE: 1.0, CONF_LONGITUDE: 1.1}},
|
||||||
CONF_LOCATION: {
|
|
||||||
CONF_LATITUDE: 1.0,
|
|
||||||
CONF_LONGITUDE: 1.1,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result2.get("type") is FlowResultType.CREATE_ENTRY
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
assert result2.get("data") == {
|
assert result["title"] == "Stookwijzer"
|
||||||
"location": {
|
assert result["data"] == {
|
||||||
"latitude": 1.0,
|
CONF_LATITUDE: 200000.123456789,
|
||||||
"longitude": 1.1,
|
CONF_LONGITUDE: 450000.123456789,
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
assert len(mock_stookwijzer.async_transform_coordinates.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("mock_setup_entry")
|
||||||
|
async def test_connection_error(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_stookwijzer: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test user configuration flow while connection fails."""
|
||||||
|
original_return_value = mock_stookwijzer.async_transform_coordinates.return_value
|
||||||
|
mock_stookwijzer.async_transform_coordinates.return_value = (None, None)
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "user"
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={CONF_LOCATION: {CONF_LATITUDE: 1.0, CONF_LONGITUDE: 1.1}},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["errors"] == {"base": "unknown"}
|
||||||
|
|
||||||
|
# Ensure we can continue the flow, when it now works
|
||||||
|
mock_stookwijzer.async_transform_coordinates.return_value = original_return_value
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={CONF_LOCATION: {CONF_LATITUDE: 1.0, CONF_LONGITUDE: 1.1}},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
|
22
tests/components/stookwijzer/test_diagnostics.py
Normal file
22
tests/components/stookwijzer/test_diagnostics.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
"""Test the Stookwijzer diagnostics."""
|
||||||
|
|
||||||
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||||
|
from tests.typing import ClientSessionGenerator
|
||||||
|
|
||||||
|
|
||||||
|
async def test_get_diagnostics(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
hass_client: ClientSessionGenerator,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
) -> None:
|
||||||
|
"""Test the Stookwijzer diagnostics."""
|
||||||
|
assert (
|
||||||
|
await get_diagnostics_for_config_entry(hass, hass_client, init_integration)
|
||||||
|
== snapshot
|
||||||
|
)
|
55
tests/components/stookwijzer/test_init.py
Normal file
55
tests/components/stookwijzer/test_init.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
"""Test the Stookwijzer init."""
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from homeassistant.components.stookwijzer.const import DOMAIN
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import issue_registry as ir
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
async def test_migrate_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_v1_config_entry: MockConfigEntry,
|
||||||
|
mock_stookwijzer: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test successful migration of entry data."""
|
||||||
|
assert mock_v1_config_entry.version == 1
|
||||||
|
|
||||||
|
mock_v1_config_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(mock_v1_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_v1_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
assert len(mock_stookwijzer.async_transform_coordinates.mock_calls) == 1
|
||||||
|
|
||||||
|
assert mock_v1_config_entry.version == 2
|
||||||
|
assert mock_v1_config_entry.data == {
|
||||||
|
CONF_LATITUDE: 200000.123456789,
|
||||||
|
CONF_LONGITUDE: 450000.123456789,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_entry_migration_failure(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_v1_config_entry: MockConfigEntry,
|
||||||
|
mock_stookwijzer: MagicMock,
|
||||||
|
issue_registry: ir.IssueRegistry,
|
||||||
|
) -> None:
|
||||||
|
"""Test successful migration of entry data."""
|
||||||
|
assert mock_v1_config_entry.version == 1
|
||||||
|
|
||||||
|
# Failed getting the transformed coordinates
|
||||||
|
mock_stookwijzer.async_transform_coordinates.return_value = (None, None)
|
||||||
|
|
||||||
|
mock_v1_config_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(mock_v1_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_v1_config_entry.state is ConfigEntryState.MIGRATION_ERROR
|
||||||
|
assert issue_registry.async_get_issue(DOMAIN, "location_migration_failed")
|
||||||
|
|
||||||
|
assert len(mock_stookwijzer.async_transform_coordinates.mock_calls) == 1
|
20
tests/components/stookwijzer/test_sensor.py
Normal file
20
tests/components/stookwijzer/test_sensor.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
"""Tests for the Stookwijzer sensor platform."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, snapshot_platform
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("init_integration")
|
||||||
|
async def test_entities(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
) -> None:
|
||||||
|
"""Test the Stookwijzer entities."""
|
||||||
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
Loading…
x
Reference in New Issue
Block a user