mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 01:11:51 -04:00
Add base_coords for OptionsFlow and action call in waze_travel_time (#166642)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user