Add base_coords for OptionsFlow and action call in waze_travel_time (#166642)

This commit is contained in:
Kevin Stillhammer
2026-04-11 16:28:02 +02:00
committed by GitHub
parent 2fa0bdb2dc
commit 822fae227a
11 changed files with 348 additions and 31 deletions
@@ -21,6 +21,7 @@ from homeassistant.helpers.selector import (
BooleanSelector,
DurationSelector,
DurationSelectorConfig,
LocationSelector,
SelectSelector,
SelectSelectorConfig,
SelectSelectorMode,
@@ -33,6 +34,7 @@ from .const import (
CONF_AVOID_FERRIES,
CONF_AVOID_SUBSCRIPTION_ROADS,
CONF_AVOID_TOLL_ROADS,
CONF_BASE_COORDINATES,
CONF_DESTINATION,
CONF_EXCL_FILTER,
CONF_INCL_FILTER,
@@ -52,6 +54,7 @@ from .const import (
VEHICLE_TYPES,
)
from .coordinator import WazeTravelTimeCoordinator, async_get_travel_times
from .helpers import base_coordinates_to_tuple, default_base_coordinates_for_region
PLATFORMS = [Platform.SENSOR]
@@ -103,6 +106,7 @@ SERVICE_GET_TRAVEL_TIMES_SCHEMA = vol.Schema(
vol.Optional(CONF_TIME_DELTA): DurationSelector(
DurationSelectorConfig(allow_negative=True, enable_second=False)
),
vol.Optional(CONF_BASE_COORDINATES): LocationSelector(),
}
)
@@ -137,6 +141,9 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
origin = origin_coordinates or service.data[CONF_ORIGIN]
destination = destination_coordinates or service.data[CONF_DESTINATION]
base_coordinates = base_coordinates_to_tuple(
service.data.get(CONF_BASE_COORDINATES)
)
time_delta = int(
timedelta(
@@ -158,6 +165,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
incl_filters=service.data.get(CONF_INCL_FILTER, DEFAULT_FILTER),
excl_filters=service.data.get(CONF_EXCL_FILTER, DEFAULT_FILTER),
time_delta=time_delta,
base_coordinates=base_coordinates,
)
return {"routes": [vars(route) for route in response]}
@@ -218,4 +226,24 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
config_entry.minor_version,
)
if config_entry.version == 2 and config_entry.minor_version == 2:
_LOGGER.debug(
"Migrating from version %s.%s",
config_entry.version,
config_entry.minor_version,
)
options = dict(config_entry.options)
options.setdefault(
CONF_BASE_COORDINATES,
default_base_coordinates_for_region(config_entry.data[CONF_REGION]),
)
hass.config_entries.async_update_entry(
config_entry, options=options, minor_version=3
)
_LOGGER.debug(
"Migration to version %s.%s successful",
config_entry.version,
config_entry.minor_version,
)
return True
@@ -13,12 +13,14 @@ from homeassistant.config_entries import (
ConfigFlowResult,
OptionsFlow,
)
from homeassistant.const import CONF_NAME, CONF_REGION
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, CONF_REGION
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.selector import (
BooleanSelector,
DurationSelector,
DurationSelectorConfig,
LocationSelector,
LocationSelectorConfig,
SelectSelector,
SelectSelectorConfig,
SelectSelectorMode,
@@ -32,6 +34,7 @@ from .const import (
CONF_AVOID_FERRIES,
CONF_AVOID_SUBSCRIPTION_ROADS,
CONF_AVOID_TOLL_ROADS,
CONF_BASE_COORDINATES,
CONF_DESTINATION,
CONF_EXCL_FILTER,
CONF_INCL_FILTER,
@@ -92,6 +95,9 @@ OPTIONS_SCHEMA = vol.Schema(
enable_second=False,
)
),
vol.Optional(CONF_BASE_COORDINATES): LocationSelector(
LocationSelectorConfig(radius=False)
),
}
)
@@ -114,18 +120,24 @@ CONFIG_SCHEMA = vol.Schema(
def default_options(
hass: HomeAssistant,
) -> dict[str, str | bool | list[str] | dict[str, int]]:
) -> dict[str, str | bool | list[str] | dict[str, int] | dict[str, float]]:
"""Get the default options."""
defaults = DEFAULT_OPTIONS.copy()
if hass.config.units is US_CUSTOMARY_SYSTEM:
defaults[CONF_UNITS] = IMPERIAL_UNITS
defaults[CONF_BASE_COORDINATES] = {
CONF_LATITUDE: hass.config.latitude,
CONF_LONGITUDE: hass.config.longitude,
}
return defaults
class WazeOptionsFlow(OptionsFlow):
"""Handle an options flow for Waze Travel Time."""
async def async_step_init(self, user_input=None) -> ConfigFlowResult:
async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
if user_input is not None:
if user_input.get(CONF_INCL_FILTER) is None:
@@ -151,7 +163,7 @@ class WazeConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Waze Travel Time."""
VERSION = 2
MINOR_VERSION = 2
MINOR_VERSION = 3
@staticmethod
@callback
@@ -5,6 +5,7 @@ from __future__ import annotations
DOMAIN = "waze_travel_time"
SEMAPHORE = "semaphore"
CONF_BASE_COORDINATES = "base_coordinates"
CONF_DESTINATION = "destination"
CONF_ORIGIN = "origin"
CONF_INCL_FILTER = "incl_filter"
@@ -33,7 +34,9 @@ UNITS = [METRIC_UNITS, IMPERIAL_UNITS]
REGIONS = ["us", "na", "eu", "il", "au"]
VEHICLE_TYPES = ["car", "taxi", "motorcycle"]
DEFAULT_OPTIONS: dict[str, str | bool | list[str] | dict[str, int]] = {
DEFAULT_OPTIONS: dict[
str, str | bool | list[str] | dict[str, int] | dict[str, float]
] = {
CONF_REALTIME: DEFAULT_REALTIME,
CONF_VEHICLE_TYPE: DEFAULT_VEHICLE_TYPE,
CONF_UNITS: METRIC_UNITS,
@@ -20,6 +20,7 @@ from .const import (
CONF_AVOID_FERRIES,
CONF_AVOID_SUBSCRIPTION_ROADS,
CONF_AVOID_TOLL_ROADS,
CONF_BASE_COORDINATES,
CONF_DESTINATION,
CONF_EXCL_FILTER,
CONF_INCL_FILTER,
@@ -32,6 +33,7 @@ from .const import (
IMPERIAL_UNITS,
SEMAPHORE,
)
from .helpers import base_coordinates_to_tuple
_LOGGER = logging.getLogger(__name__)
@@ -53,6 +55,7 @@ async def async_get_travel_times(
incl_filters: Collection[str] | None = None,
excl_filters: Collection[str] | None = None,
time_delta: int = 0,
base_coordinates: tuple[float, float] | None = None,
) -> list[CalcRoutesResponse]:
"""Get all available routes."""
@@ -77,6 +80,7 @@ async def async_get_travel_times(
real_time=realtime,
alternatives=3,
time_delta=time_delta,
base_coords=base_coordinates,
)
if len(routes) < 1:
@@ -211,6 +215,9 @@ class WazeTravelTimeCoordinator(DataUpdateCoordinator[WazeTravelTimeData]):
timedelta(**self.config_entry.options[CONF_TIME_DELTA]).total_seconds()
/ 60
)
base_coordinates = base_coordinates_to_tuple(
self.config_entry.options.get(CONF_BASE_COORDINATES)
)
routes = await async_get_travel_times(
self.client,
@@ -225,6 +232,7 @@ class WazeTravelTimeCoordinator(DataUpdateCoordinator[WazeTravelTimeData]):
incl_filter,
excl_filter,
time_delta,
base_coordinates,
)
if len(routes) < 1:
travel_data = WazeTravelTimeData(
@@ -4,6 +4,7 @@ import logging
from pywaze.route_calculator import WazeRouteCalculator, WRCError
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.httpx_client import get_async_client
from homeassistant.helpers.location import find_coordinates
@@ -11,6 +12,25 @@ from homeassistant.helpers.location import find_coordinates
_LOGGER = logging.getLogger(__name__)
def base_coordinates_to_tuple(
base_coordinates: dict[str, float] | None,
) -> tuple[float, float] | None:
"""Convert Home Assistant location data to Waze base coordinates."""
if base_coordinates is None:
return None
return (base_coordinates[CONF_LATITUDE], base_coordinates[CONF_LONGITUDE])
def default_base_coordinates_for_region(region: str) -> dict[str, float]:
"""Return pywaze's default base coordinates for a region."""
base_coordinates = WazeRouteCalculator.BASE_COORDS[region.upper()]
return {
CONF_LATITUDE: base_coordinates["lat"],
CONF_LONGITUDE: base_coordinates["lon"],
}
async def is_valid_config_entry(
hass: HomeAssistant, origin: str, destination: str, region: str
) -> bool:
@@ -69,3 +69,9 @@ get_travel_times:
required: false
selector:
duration:
base_coordinates:
required: false
example: '{"latitude": -27.9699373, "longitude": 153.4081865}'
selector:
location:
radius: false
@@ -26,6 +26,7 @@
"avoid_ferries": "Avoid ferries?",
"avoid_subscription_roads": "Avoid roads needing a vignette / subscription?",
"avoid_toll_roads": "Avoid toll roads?",
"base_coordinates": "Base coordinates",
"excl_filter": "Exact street name which must NOT be part of the selected route",
"incl_filter": "Exact street name which must be part of the selected route",
"realtime": "Realtime travel time?",
@@ -33,6 +34,9 @@
"units": "Units",
"vehicle_type": "Vehicle type"
},
"data_description": {
"base_coordinates": "When Waze finds multiple matching locations for an address, it selects the one closest to these coordinates."
},
"description": "Some options will allow you to force the integration to use a particular route or avoid a particular route in its time travel calculation."
}
}
@@ -77,6 +81,10 @@
"description": "Whether to avoid toll roads.",
"name": "[%key:component::waze_travel_time::options::step::init::data::avoid_toll_roads%]"
},
"base_coordinates": {
"description": "[%key:component::waze_travel_time::options::step::init::data_description::base_coordinates%]",
"name": "[%key:component::waze_travel_time::options::step::init::data::base_coordinates%]"
},
"destination": {
"description": "The destination of the route.",
"name": "[%key:component::waze_travel_time::config::step::user::data::destination%]"
@@ -1 +1,21 @@
"""Tests for the Waze Travel Time integration."""
from homeassistant.components.waze_travel_time.const import (
CONF_BASE_COORDINATES,
DEFAULT_OPTIONS,
)
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
from homeassistant.core import HomeAssistant
def get_default_options(
hass: HomeAssistant,
) -> dict[str, str | bool | list[str] | dict[str, int] | dict[str, float]]:
"""Return the default options for Waze Travel Time."""
return {
**DEFAULT_OPTIONS,
CONF_BASE_COORDINATES: {
CONF_LATITUDE: hass.config.latitude,
CONF_LONGITUDE: hass.config.longitude,
},
}
@@ -21,6 +21,7 @@ async def mock_config_fixture(hass: HomeAssistant, data, options):
options=options,
entry_id="test",
version=WazeConfigFlow.VERSION,
minor_version=WazeConfigFlow.MINOR_VERSION,
)
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
@@ -8,6 +8,7 @@ from homeassistant.components.waze_travel_time.const import (
CONF_AVOID_FERRIES,
CONF_AVOID_SUBSCRIPTION_ROADS,
CONF_AVOID_TOLL_ROADS,
CONF_BASE_COORDINATES,
CONF_DESTINATION,
CONF_EXCL_FILTER,
CONF_INCL_FILTER,
@@ -21,10 +22,11 @@ from homeassistant.components.waze_travel_time.const import (
DOMAIN,
IMPERIAL_UNITS,
)
from homeassistant.const import CONF_NAME, CONF_REGION
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, CONF_REGION
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from . import get_default_options
from .const import CONFIG_FLOW_USER_INPUT, MOCK_CONFIG
from tests.common import MockConfigEntry
@@ -63,6 +65,7 @@ async def test_reconfigure(hass: HomeAssistant) -> None:
data=MOCK_CONFIG,
options=DEFAULT_OPTIONS,
version=WazeConfigFlow.VERSION,
minor_version=WazeConfigFlow.MINOR_VERSION,
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
@@ -100,8 +103,9 @@ async def test_options(hass: HomeAssistant) -> None:
entry = MockConfigEntry(
domain=DOMAIN,
data=MOCK_CONFIG,
options=DEFAULT_OPTIONS,
options=get_default_options(hass),
version=WazeConfigFlow.VERSION,
minor_version=WazeConfigFlow.MINOR_VERSION,
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
@@ -118,6 +122,10 @@ async def test_options(hass: HomeAssistant) -> None:
CONF_AVOID_FERRIES: True,
CONF_AVOID_SUBSCRIPTION_ROADS: True,
CONF_AVOID_TOLL_ROADS: True,
CONF_BASE_COORDINATES: {
CONF_LATITUDE: 1.123,
CONF_LONGITUDE: -1.123,
},
CONF_EXCL_FILTER: ["ExcludeThis"],
CONF_INCL_FILTER: ["IncludeThis"],
CONF_REALTIME: False,
@@ -132,6 +140,10 @@ async def test_options(hass: HomeAssistant) -> None:
CONF_AVOID_FERRIES: True,
CONF_AVOID_SUBSCRIPTION_ROADS: True,
CONF_AVOID_TOLL_ROADS: True,
CONF_BASE_COORDINATES: {
CONF_LATITUDE: 1.123,
CONF_LONGITUDE: -1.123,
},
CONF_EXCL_FILTER: ["ExcludeThis"],
CONF_INCL_FILTER: ["IncludeThis"],
CONF_REALTIME: False,
@@ -144,6 +156,10 @@ async def test_options(hass: HomeAssistant) -> None:
CONF_AVOID_FERRIES: True,
CONF_AVOID_SUBSCRIPTION_ROADS: True,
CONF_AVOID_TOLL_ROADS: True,
CONF_BASE_COORDINATES: {
CONF_LATITUDE: 1.123,
CONF_LONGITUDE: -1.123,
},
CONF_EXCL_FILTER: ["ExcludeThis"],
CONF_INCL_FILTER: ["IncludeThis"],
CONF_REALTIME: False,
@@ -219,6 +235,7 @@ async def test_reset_filters(hass: HomeAssistant) -> None:
options=options,
entry_id="test",
version=WazeConfigFlow.VERSION,
minor_version=WazeConfigFlow.MINOR_VERSION,
)
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
@@ -251,3 +268,34 @@ async def test_reset_filters(hass: HomeAssistant) -> None:
CONF_UNITS: IMPERIAL_UNITS,
CONF_VEHICLE_TYPE: "taxi",
}
@pytest.mark.usefixtures("mock_update")
async def test_reset_base_coordinates(hass: HomeAssistant) -> None:
"""Test clearing base coordinates in the options flow."""
entry = MockConfigEntry(
domain=DOMAIN,
data=MOCK_CONFIG,
options=get_default_options(hass),
version=WazeConfigFlow.VERSION,
minor_version=WazeConfigFlow.MINOR_VERSION,
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
result = await hass.config_entries.options.async_init(entry.entry_id, data=None)
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_AVOID_FERRIES: False,
CONF_AVOID_SUBSCRIPTION_ROADS: False,
CONF_AVOID_TOLL_ROADS: False,
CONF_REALTIME: True,
CONF_UNITS: IMPERIAL_UNITS,
CONF_VEHICLE_TYPE: "taxi",
},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert CONF_BASE_COORDINATES not in entry.options
+187 -24
View File
@@ -6,6 +6,7 @@ from homeassistant.components.waze_travel_time.const import (
CONF_AVOID_FERRIES,
CONF_AVOID_SUBSCRIPTION_ROADS,
CONF_AVOID_TOLL_ROADS,
CONF_BASE_COORDINATES,
CONF_EXCL_FILTER,
CONF_INCL_FILTER,
CONF_REALTIME,
@@ -24,6 +25,7 @@ from homeassistant.components.waze_travel_time.const import (
METRIC_UNITS,
)
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_REGION
from homeassistant.core import HomeAssistant
from .const import MOCK_CONFIG
@@ -31,15 +33,56 @@ from .const import MOCK_CONFIG
from tests.common import MockConfigEntry
async def call_service_get_travel_times(
hass: HomeAssistant,
origin: str,
destination: str,
vehicle_type: str,
region: str,
units: str,
incl_filter: list[str] | None = None,
time_delta: dict[str, int] | None = None,
base_coordinates: dict[str, float] | None = None,
) -> dict:
"""Call the get_travel_times service."""
params = {
"origin": origin,
"destination": destination,
"vehicle_type": vehicle_type,
"region": region,
"units": units,
"incl_filter": incl_filter or [],
"time_delta": time_delta or {},
}
if base_coordinates is not None:
params["base_coordinates"] = base_coordinates
return await hass.services.async_call(
"waze_travel_time",
"get_travel_times",
params,
blocking=True,
return_response=True,
)
@pytest.mark.parametrize(
("data", "options"),
[(MOCK_CONFIG, DEFAULT_OPTIONS)],
)
@pytest.mark.parametrize(
("time_delta", "expected_time_delta"),
("time_delta", "expected_time_delta", "base_coordinates", "expected_base_coords"),
[
pytest.param({"hours": 1, "minutes": 30}, 90, id="positive"),
pytest.param({"hours": -1, "minutes": -30}, -90, id="negative"),
pytest.param({"hours": 1, "minutes": 30}, 90, None, None, id="positive"),
pytest.param(
{"hours": -1, "minutes": -30},
-90,
{CONF_LATITUDE: 40.7128, CONF_LONGITUDE: -74.0060},
(
40.7128,
-74.0060,
),
id="negative_with_base_coordinates",
),
],
)
@pytest.mark.usefixtures("mock_update", "mock_config")
@@ -48,22 +91,20 @@ async def test_service_get_travel_times(
mock_update,
time_delta: dict[str, int],
expected_time_delta: int,
base_coordinates: dict[str, float] | None,
expected_base_coords: tuple[float, float] | None,
) -> None:
"""Test service get_travel_times."""
response_data = await hass.services.async_call(
"waze_travel_time",
"get_travel_times",
{
"origin": "location1",
"destination": "location2",
"vehicle_type": "car",
"region": "us",
"units": "imperial",
"incl_filter": ["IncludeThis"],
"time_delta": time_delta,
},
blocking=True,
return_response=True,
response_data = await call_service_get_travel_times(
hass,
origin="location1",
destination="location2",
vehicle_type="car",
region="us",
units="imperial",
incl_filter=["IncludeThis"],
time_delta=time_delta,
base_coordinates=base_coordinates,
)
assert response_data == {
"routes": [
@@ -76,6 +117,7 @@ async def test_service_get_travel_times(
]
}
assert mock_update.call_args_list[-1].kwargs["time_delta"] == expected_time_delta
assert mock_update.call_args_list[-1].kwargs["base_coords"] == expected_base_coords
@pytest.mark.parametrize(
@@ -106,8 +148,8 @@ async def test_service_get_travel_times_empty_response(
@pytest.mark.usefixtures("mock_update")
async def test_migrate_entry_v1_v2(hass: HomeAssistant) -> None:
"""Test successful migration of entry data from v1 to v2.2."""
async def test_migrate_entry_v1_to_v2_3(hass: HomeAssistant) -> None:
"""Test successful migration of entry data from v1 to v2.3."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
version=1,
@@ -130,10 +172,14 @@ async def test_migrate_entry_v1_v2(hass: HomeAssistant) -> None:
assert updated_entry.state is ConfigEntryState.LOADED
assert updated_entry.version == 2
assert updated_entry.minor_version == 2
assert updated_entry.minor_version == 3
assert updated_entry.options[CONF_INCL_FILTER] == DEFAULT_FILTER
assert updated_entry.options[CONF_EXCL_FILTER] == DEFAULT_FILTER
assert updated_entry.options[CONF_TIME_DELTA] == DEFAULT_TIME_DELTA
assert updated_entry.options[CONF_BASE_COORDINATES] == {
CONF_LATITUDE: 40.713,
CONF_LONGITUDE: -74.006,
}
mock_entry = MockConfigEntry(
domain=DOMAIN,
@@ -159,15 +205,19 @@ async def test_migrate_entry_v1_v2(hass: HomeAssistant) -> None:
assert updated_entry.state is ConfigEntryState.LOADED
assert updated_entry.version == 2
assert updated_entry.minor_version == 2
assert updated_entry.minor_version == 3
assert updated_entry.options[CONF_INCL_FILTER] == ["IncludeThis"]
assert updated_entry.options[CONF_EXCL_FILTER] == ["ExcludeThis"]
assert updated_entry.options[CONF_TIME_DELTA] == DEFAULT_TIME_DELTA
assert updated_entry.options[CONF_BASE_COORDINATES] == {
CONF_LATITUDE: 40.713,
CONF_LONGITUDE: -74.006,
}
@pytest.mark.usefixtures("mock_update")
async def test_migrate_entry_v2_1_to_v2_2(hass: HomeAssistant) -> None:
"""Test successful migration of entry from version 2.1 to 2.2."""
async def test_migrate_entry_v2_1_to_v2_3(hass: HomeAssistant) -> None:
"""Test successful migration of entry from version 2.1 to 2.3."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
version=2,
@@ -193,5 +243,118 @@ async def test_migrate_entry_v2_1_to_v2_2(hass: HomeAssistant) -> None:
assert updated_entry.state is ConfigEntryState.LOADED
assert updated_entry.version == 2
assert updated_entry.minor_version == 2
assert updated_entry.minor_version == 3
assert updated_entry.options[CONF_TIME_DELTA] == DEFAULT_TIME_DELTA
assert updated_entry.options[CONF_BASE_COORDINATES] == {
CONF_LATITUDE: 40.713,
CONF_LONGITUDE: -74.006,
}
@pytest.mark.parametrize(
("region", "expected_base_coordinates"),
[
pytest.param(
"US",
{CONF_LATITUDE: 40.713, CONF_LONGITUDE: -74.006},
id="us",
),
pytest.param(
"NA",
{CONF_LATITUDE: 40.713, CONF_LONGITUDE: -74.006},
id="na",
),
pytest.param(
"EU",
{CONF_LATITUDE: 47.498, CONF_LONGITUDE: 19.040},
id="eu",
),
pytest.param(
"IL",
{CONF_LATITUDE: 31.768, CONF_LONGITUDE: 35.214},
id="il",
),
pytest.param(
"AU",
{CONF_LATITUDE: -35.281, CONF_LONGITUDE: 149.128},
id="au",
),
],
)
@pytest.mark.usefixtures("mock_update")
async def test_migrate_entry_v2_2_to_v2_3_adds_region_base_coordinates(
hass: HomeAssistant,
region: str,
expected_base_coordinates: dict[str, float],
) -> None:
"""Test migration adds pywaze's default base coordinates for each region."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
version=2,
minor_version=2,
data={**MOCK_CONFIG, CONF_REGION: region},
options={
CONF_REALTIME: DEFAULT_REALTIME,
CONF_VEHICLE_TYPE: DEFAULT_VEHICLE_TYPE,
CONF_UNITS: METRIC_UNITS,
CONF_AVOID_FERRIES: DEFAULT_AVOID_FERRIES,
CONF_AVOID_SUBSCRIPTION_ROADS: DEFAULT_AVOID_SUBSCRIPTION_ROADS,
CONF_AVOID_TOLL_ROADS: DEFAULT_AVOID_TOLL_ROADS,
CONF_INCL_FILTER: DEFAULT_FILTER,
CONF_EXCL_FILTER: DEFAULT_FILTER,
CONF_TIME_DELTA: DEFAULT_TIME_DELTA,
},
)
mock_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
updated_entry = hass.config_entries.async_get_entry(mock_entry.entry_id)
assert updated_entry.state is ConfigEntryState.LOADED
assert updated_entry.version == 2
assert updated_entry.minor_version == 3
assert updated_entry.options[CONF_BASE_COORDINATES] == expected_base_coordinates
@pytest.mark.usefixtures("mock_update")
async def test_migrate_entry_v2_2_to_v2_3_preserves_existing_base_coordinates(
hass: HomeAssistant,
) -> None:
"""Test migration preserves configured base coordinates."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
version=2,
minor_version=2,
data=MOCK_CONFIG,
options={
CONF_REALTIME: DEFAULT_REALTIME,
CONF_VEHICLE_TYPE: DEFAULT_VEHICLE_TYPE,
CONF_UNITS: METRIC_UNITS,
CONF_AVOID_FERRIES: DEFAULT_AVOID_FERRIES,
CONF_AVOID_SUBSCRIPTION_ROADS: DEFAULT_AVOID_SUBSCRIPTION_ROADS,
CONF_AVOID_TOLL_ROADS: DEFAULT_AVOID_TOLL_ROADS,
CONF_INCL_FILTER: DEFAULT_FILTER,
CONF_EXCL_FILTER: DEFAULT_FILTER,
CONF_TIME_DELTA: DEFAULT_TIME_DELTA,
CONF_BASE_COORDINATES: {
CONF_LATITUDE: 1.23,
CONF_LONGITUDE: 4.56,
},
},
)
mock_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
updated_entry = hass.config_entries.async_get_entry(mock_entry.entry_id)
assert updated_entry.state is ConfigEntryState.LOADED
assert updated_entry.version == 2
assert updated_entry.minor_version == 3
assert updated_entry.options[CONF_BASE_COORDINATES] == {
CONF_LATITUDE: 1.23,
CONF_LONGITUDE: 4.56,
}