From 82b4368d1de40c0454c2482a6e6a5942cf100dce Mon Sep 17 00:00:00 2001 From: G Johansson Date: Fri, 5 May 2023 21:19:16 +0200 Subject: [PATCH] Bump pytrafikverket to 0.3.1 (#92425) * Bump pytrafikverket 0.3.0 * 0.3.1 * mypy * Fix exceptions --- .../trafikverket_ferry/config_flow.py | 30 ++++++------- .../trafikverket_ferry/coordinator.py | 6 ++- .../trafikverket_ferry/manifest.json | 2 +- .../components/trafikverket_train/__init__.py | 11 +++-- .../trafikverket_train/config_flow.py | 43 +++++++++---------- .../trafikverket_train/manifest.json | 2 +- .../components/trafikverket_train/sensor.py | 15 +++++-- .../config_flow.py | 34 ++++++++------- .../coordinator.py | 10 ++++- .../trafikverket_weatherstation/manifest.json | 2 +- .../trafikverket_weatherstation/sensor.py | 7 ++- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../trafikverket_ferry/test_config_flow.py | 25 +++++------ .../trafikverket_ferry/test_coordinator.py | 17 ++++++-- .../trafikverket_train/test_config_flow.py | 33 ++++++++------ .../test_config_flow.py | 19 +++++--- 17 files changed, 154 insertions(+), 106 deletions(-) diff --git a/homeassistant/components/trafikverket_ferry/config_flow.py b/homeassistant/components/trafikverket_ferry/config_flow.py index a1f984e5556..2fb6cfb642a 100644 --- a/homeassistant/components/trafikverket_ferry/config_flow.py +++ b/homeassistant/components/trafikverket_ferry/config_flow.py @@ -5,6 +5,7 @@ from collections.abc import Mapping from typing import Any from pytrafikverket import TrafikverketFerry +from pytrafikverket.exceptions import InvalidAuthentication, NoFerryFound import voluptuous as vol from homeassistant import config_entries @@ -16,9 +17,6 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import CONF_FROM, CONF_TIME, CONF_TO, DOMAIN from .util import create_unique_id -ERROR_INVALID_AUTH = "Source: Security, message: Invalid authentication" -ERROR_INVALID_ROUTE = "No FerryAnnouncement found" - DATA_SCHEMA = vol.Schema( { vol.Required(CONF_API_KEY): selector.TextSelector( @@ -81,13 +79,12 @@ class TVFerryConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): await self.validate_input( api_key, self.entry.data[CONF_FROM], self.entry.data[CONF_TO] ) - except ValueError as err: - if str(err) == ERROR_INVALID_AUTH: - errors["base"] = "invalid_auth" - elif str(err) == ERROR_INVALID_ROUTE: - errors["base"] = "invalid_route" - else: - errors["base"] = "cannot_connect" + except InvalidAuthentication: + errors["base"] = "invalid_auth" + except NoFerryFound: + errors["base"] = "invalid_route" + except Exception: # pylint: disable=broad-exception-caught + errors["base"] = "cannot_connect" else: self.hass.config_entries.async_update_entry( self.entry, @@ -126,13 +123,12 @@ class TVFerryConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): try: await self.validate_input(api_key, ferry_from, ferry_to) - except ValueError as err: - if str(err) == ERROR_INVALID_AUTH: - errors["base"] = "invalid_auth" - elif str(err) == ERROR_INVALID_ROUTE: - errors["base"] = "invalid_route" - else: - errors["base"] = "cannot_connect" + except InvalidAuthentication: + errors["base"] = "invalid_auth" + except NoFerryFound: + errors["base"] = "invalid_route" + except Exception: # pylint: disable=broad-exception-caught + errors["base"] = "cannot_connect" else: if not errors: unique_id = create_unique_id( diff --git a/homeassistant/components/trafikverket_ferry/coordinator.py b/homeassistant/components/trafikverket_ferry/coordinator.py index 7c2c64d49f0..926b57092a7 100644 --- a/homeassistant/components/trafikverket_ferry/coordinator.py +++ b/homeassistant/components/trafikverket_ferry/coordinator.py @@ -6,11 +6,13 @@ import logging from typing import Any from pytrafikverket import TrafikverketFerry +from pytrafikverket.exceptions import InvalidAuthentication, NoFerryFound from pytrafikverket.trafikverket_ferry import FerryStop from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_API_KEY, CONF_WEEKDAY, WEEKDAYS from homeassistant.core import HomeAssistant +from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util import dt @@ -82,10 +84,12 @@ class TVDataUpdateCoordinator(DataUpdateCoordinator): ] = await self._ferry_api.async_get_next_ferry_stops( self._from, self._to, when, 3 ) - except ValueError as error: + except NoFerryFound as error: raise UpdateFailed( f"Departure {when} encountered a problem: {error}" ) from error + except InvalidAuthentication as error: + raise ConfigEntryAuthFailed(error) from error states = { "departure_time": routedata[0].departure_time, diff --git a/homeassistant/components/trafikverket_ferry/manifest.json b/homeassistant/components/trafikverket_ferry/manifest.json index 2dabb29c4d7..2221038caae 100644 --- a/homeassistant/components/trafikverket_ferry/manifest.json +++ b/homeassistant/components/trafikverket_ferry/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/trafikverket_ferry", "iot_class": "cloud_polling", "loggers": ["pytrafikverket"], - "requirements": ["pytrafikverket==0.2.3"] + "requirements": ["pytrafikverket==0.3.1"] } diff --git a/homeassistant/components/trafikverket_train/__init__.py b/homeassistant/components/trafikverket_train/__init__.py index 0bedb7141c6..8047cf2046d 100644 --- a/homeassistant/components/trafikverket_train/__init__.py +++ b/homeassistant/components/trafikverket_train/__init__.py @@ -2,6 +2,11 @@ from __future__ import annotations from pytrafikverket import TrafikverketTrain +from pytrafikverket.exceptions import ( + InvalidAuthentication, + MultipleTrainStationsFound, + NoTrainStationFound, +) from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_API_KEY @@ -21,9 +26,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: try: to_station = await train_api.async_get_train_station(entry.data[CONF_TO]) from_station = await train_api.async_get_train_station(entry.data[CONF_FROM]) - except ValueError as error: - if "Invalid authentication" in error.args[0]: - raise ConfigEntryAuthFailed from error + except InvalidAuthentication as error: + raise ConfigEntryAuthFailed from error + except (NoTrainStationFound, MultipleTrainStationsFound) as error: raise ConfigEntryNotReady( f"Problem when trying station {entry.data[CONF_FROM]} to" f" {entry.data[CONF_TO]}. Error: {error} " diff --git a/homeassistant/components/trafikverket_train/config_flow.py b/homeassistant/components/trafikverket_train/config_flow.py index 55db0f98244..fc23d3b953d 100644 --- a/homeassistant/components/trafikverket_train/config_flow.py +++ b/homeassistant/components/trafikverket_train/config_flow.py @@ -5,6 +5,11 @@ from collections.abc import Mapping from typing import Any from pytrafikverket import TrafikverketTrain +from pytrafikverket.exceptions import ( + InvalidAuthentication, + MultipleTrainStationsFound, + NoTrainStationFound, +) import voluptuous as vol from homeassistant import config_entries @@ -23,10 +28,6 @@ import homeassistant.util.dt as dt_util from .const import CONF_FROM, CONF_TIME, CONF_TO, DOMAIN from .util import create_unique_id -ERROR_INVALID_AUTH = "Source: Security, message: Invalid authentication" -ERROR_INVALID_STATION = "Could not find a station with the specified name" -ERROR_MULTIPLE_STATION = "Found multiple stations with the specified name" - DATA_SCHEMA = vol.Schema( { vol.Required(CONF_API_KEY): TextSelector(), @@ -86,15 +87,14 @@ class TVTrainConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): await self.validate_input( api_key, self.entry.data[CONF_FROM], self.entry.data[CONF_TO] ) - except ValueError as err: - if str(err) == ERROR_INVALID_AUTH: - errors["base"] = "invalid_auth" - elif str(err) == ERROR_INVALID_STATION: - errors["base"] = "invalid_station" - elif str(err) == ERROR_MULTIPLE_STATION: - errors["base"] = "more_stations" - else: - errors["base"] = "cannot_connect" + except InvalidAuthentication: + errors["base"] = "invalid_auth" + except NoTrainStationFound: + errors["base"] = "invalid_station" + except MultipleTrainStationsFound: + errors["base"] = "more_stations" + except Exception: # pylint: disable=broad-exception-caught + errors["base"] = "cannot_connect" else: self.hass.config_entries.async_update_entry( self.entry, @@ -131,15 +131,14 @@ class TVTrainConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): try: await self.validate_input(api_key, train_from, train_to) - except ValueError as err: - if str(err) == ERROR_INVALID_AUTH: - errors["base"] = "invalid_auth" - elif str(err) == ERROR_INVALID_STATION: - errors["base"] = "invalid_station" - elif str(err) == ERROR_MULTIPLE_STATION: - errors["base"] = "more_stations" - else: - errors["base"] = "cannot_connect" + except InvalidAuthentication: + errors["base"] = "invalid_auth" + except NoTrainStationFound: + errors["base"] = "invalid_station" + except MultipleTrainStationsFound: + errors["base"] = "more_stations" + except Exception: # pylint: disable=broad-exception-caught + errors["base"] = "cannot_connect" else: if train_time: if bool(dt_util.parse_time(train_time) is None): diff --git a/homeassistant/components/trafikverket_train/manifest.json b/homeassistant/components/trafikverket_train/manifest.json index bdd3dd9ab4a..7af7c6df761 100644 --- a/homeassistant/components/trafikverket_train/manifest.json +++ b/homeassistant/components/trafikverket_train/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/trafikverket_train", "iot_class": "cloud_polling", "loggers": ["pytrafikverket"], - "requirements": ["pytrafikverket==0.2.3"] + "requirements": ["pytrafikverket==0.3.1"] } diff --git a/homeassistant/components/trafikverket_train/sensor.py b/homeassistant/components/trafikverket_train/sensor.py index 678a0af2294..f48127b3e97 100644 --- a/homeassistant/components/trafikverket_train/sensor.py +++ b/homeassistant/components/trafikverket_train/sensor.py @@ -3,9 +3,13 @@ from __future__ import annotations from datetime import date, datetime, time, timedelta import logging -from typing import Any +from typing import TYPE_CHECKING, Any from pytrafikverket import TrafikverketTrain +from pytrafikverket.exceptions import ( + MultipleTrainAnnouncementFound, + NoTrainAnnouncementFound, +) from pytrafikverket.trafikverket_train import StationInfo, TrainStop from homeassistant.components.sensor import SensorDeviceClass, SensorEntity @@ -119,6 +123,8 @@ class TrainSensor(SensorEntity): name=name, configuration_url="https://api.trafikinfo.trafikverket.se/", ) + if TYPE_CHECKING: + assert from_station.name and to_station.name self._attr_unique_id = create_unique_id( from_station.name, to_station.name, departuretime, weekday ) @@ -134,6 +140,7 @@ class TrainSensor(SensorEntity): ) try: if self._time: + _LOGGER.debug("%s, %s, %s", self._from_station, self._to_station, when) _state = await self._train_api.async_get_train_stop( self._from_station, self._to_station, when ) @@ -141,7 +148,7 @@ class TrainSensor(SensorEntity): _state = await self._train_api.async_get_next_train_stop( self._from_station, self._to_station, when ) - except ValueError as error: + except (NoTrainAnnouncementFound, MultipleTrainAnnouncementFound) as error: _LOGGER.error("Departure %s encountered a problem: %s", when, error) if not _state: @@ -153,6 +160,8 @@ class TrainSensor(SensorEntity): self._attr_available = True # The original datetime doesn't provide a timezone so therefore attaching it here. + if TYPE_CHECKING: + assert _state.advertised_time_at_location self._attr_native_value = dt.as_utc(_state.advertised_time_at_location) if _state.time_at_location: self._attr_native_value = dt.as_utc(_state.time_at_location) @@ -165,7 +174,7 @@ class TrainSensor(SensorEntity): """Return extra state attributes.""" attributes: dict[str, Any] = { - ATTR_DEPARTURE_STATE: state.get_state().name, + ATTR_DEPARTURE_STATE: state.get_state().value, ATTR_CANCELED: state.canceled, ATTR_DELAY_TIME: None, ATTR_PLANNED_TIME: None, diff --git a/homeassistant/components/trafikverket_weatherstation/config_flow.py b/homeassistant/components/trafikverket_weatherstation/config_flow.py index 345d625c7c1..f8f86298045 100644 --- a/homeassistant/components/trafikverket_weatherstation/config_flow.py +++ b/homeassistant/components/trafikverket_weatherstation/config_flow.py @@ -1,6 +1,11 @@ """Adds config flow for Trafikverket Weather integration.""" from __future__ import annotations +from pytrafikverket.exceptions import ( + InvalidAuthentication, + MultipleWeatherStationsFound, + NoWeatherStationFound, +) from pytrafikverket.trafikverket_weather import TrafikverketWeather import voluptuous as vol @@ -20,15 +25,11 @@ class TVWeatherConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): entry: config_entries.ConfigEntry - async def validate_input(self, sensor_api: str, station: str) -> str: + async def validate_input(self, sensor_api: str, station: str) -> None: """Validate input from user input.""" web_session = async_get_clientsession(self.hass) weather_api = TrafikverketWeather(web_session, sensor_api) - try: - await weather_api.async_get_weather(station) - except ValueError as err: - return str(err) - return "connected" + await weather_api.async_get_weather(station) async def async_step_user( self, user_input: dict[str, str] | None = None @@ -41,8 +42,17 @@ class TVWeatherConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): api_key = user_input[CONF_API_KEY] station = user_input[CONF_STATION] - validate = await self.validate_input(api_key, station) - if validate == "connected": + try: + await self.validate_input(api_key, station) + except InvalidAuthentication: + errors["base"] = "invalid_auth" + except NoWeatherStationFound: + errors["base"] = "invalid_station" + except MultipleWeatherStationsFound: + errors["base"] = "more_stations" + except Exception: # pylint: disable=broad-exception-caught + errors["base"] = "cannot_connect" + else: return self.async_create_entry( title=name, data={ @@ -50,14 +60,6 @@ class TVWeatherConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): CONF_STATION: station, }, ) - if validate == "Source: Security, message: Invalid authentication": - errors["base"] = "invalid_auth" - elif validate == "Could not find a weather station with the specified name": - errors["base"] = "invalid_station" - elif validate == "Found multiple weather stations with the specified name": - errors["base"] = "more_stations" - else: - errors["base"] = "cannot_connect" return self.async_show_form( step_id="user", diff --git a/homeassistant/components/trafikverket_weatherstation/coordinator.py b/homeassistant/components/trafikverket_weatherstation/coordinator.py index 990dcc0bc0b..40c551089d2 100644 --- a/homeassistant/components/trafikverket_weatherstation/coordinator.py +++ b/homeassistant/components/trafikverket_weatherstation/coordinator.py @@ -4,11 +4,17 @@ from __future__ import annotations from datetime import timedelta import logging +from pytrafikverket.exceptions import ( + InvalidAuthentication, + MultipleWeatherStationsFound, + NoWeatherStationFound, +) from pytrafikverket.trafikverket_weather import TrafikverketWeather, WeatherStationInfo from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_API_KEY from homeassistant.core import HomeAssistant +from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -38,6 +44,8 @@ class TVDataUpdateCoordinator(DataUpdateCoordinator[WeatherStationInfo]): """Fetch data from Trafikverket.""" try: weatherdata = await self._weather_api.async_get_weather(self._station) - except ValueError as error: + except InvalidAuthentication as error: + raise ConfigEntryAuthFailed from error + except (NoWeatherStationFound, MultipleWeatherStationsFound) as error: raise UpdateFailed from error return weatherdata diff --git a/homeassistant/components/trafikverket_weatherstation/manifest.json b/homeassistant/components/trafikverket_weatherstation/manifest.json index 9b7dad395f9..3d584e80998 100644 --- a/homeassistant/components/trafikverket_weatherstation/manifest.json +++ b/homeassistant/components/trafikverket_weatherstation/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/trafikverket_weatherstation", "iot_class": "cloud_polling", "loggers": ["pytrafikverket"], - "requirements": ["pytrafikverket==0.2.3"] + "requirements": ["pytrafikverket==0.3.1"] } diff --git a/homeassistant/components/trafikverket_weatherstation/sensor.py b/homeassistant/components/trafikverket_weatherstation/sensor.py index c8eed559f7c..6dfd6a5e7c4 100644 --- a/homeassistant/components/trafikverket_weatherstation/sensor.py +++ b/homeassistant/components/trafikverket_weatherstation/sensor.py @@ -3,6 +3,7 @@ from __future__ import annotations from dataclasses import dataclass from datetime import datetime +from typing import TYPE_CHECKING from homeassistant.components.sensor import ( SensorDeviceClass, @@ -190,7 +191,9 @@ class TrafikverketWeatherStation( def native_value(self) -> StateType | datetime: """Return state of sensor.""" if self.entity_description.api_key == "measure_time": - return _to_datetime(self.coordinator.data.measure_time) + if TYPE_CHECKING: + assert self.coordinator.data.measure_time + return self.coordinator.data.measure_time state: StateType = getattr( self.coordinator.data, self.entity_description.api_key @@ -204,4 +207,6 @@ class TrafikverketWeatherStation( @property def available(self) -> bool: """Return if entity is available.""" + if TYPE_CHECKING: + assert self.coordinator.data.active return self.coordinator.data.active and super().available diff --git a/requirements_all.txt b/requirements_all.txt index 8022752c697..95504b93ea5 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2146,7 +2146,7 @@ pytradfri[async]==9.0.1 # homeassistant.components.trafikverket_ferry # homeassistant.components.trafikverket_train # homeassistant.components.trafikverket_weatherstation -pytrafikverket==0.2.3 +pytrafikverket==0.3.1 # homeassistant.components.usb pyudev==0.23.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 65a97d8ebec..9364c3e66fd 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1551,7 +1551,7 @@ pytradfri[async]==9.0.1 # homeassistant.components.trafikverket_ferry # homeassistant.components.trafikverket_train # homeassistant.components.trafikverket_weatherstation -pytrafikverket==0.2.3 +pytrafikverket==0.3.1 # homeassistant.components.usb pyudev==0.23.2 diff --git a/tests/components/trafikverket_ferry/test_config_flow.py b/tests/components/trafikverket_ferry/test_config_flow.py index 7bfb175220e..dbbd1fb09ac 100644 --- a/tests/components/trafikverket_ferry/test_config_flow.py +++ b/tests/components/trafikverket_ferry/test_config_flow.py @@ -4,6 +4,7 @@ from __future__ import annotations from unittest.mock import patch import pytest +from pytrafikverket.exceptions import InvalidAuthentication, NoFerryFound from homeassistant import config_entries from homeassistant.components.trafikverket_ferry.const import ( @@ -63,24 +64,24 @@ async def test_form(hass: HomeAssistant) -> None: @pytest.mark.parametrize( - ("error_message", "base_error"), + ("side_effect", "base_error"), [ ( - "Source: Security, message: Invalid authentication", + InvalidAuthentication, "invalid_auth", ), ( - "No FerryAnnouncement found", + NoFerryFound, "invalid_route", ), ( - "Unknown", + Exception, "cannot_connect", ), ], ) async def test_flow_fails( - hass: HomeAssistant, error_message: str, base_error: str + hass: HomeAssistant, side_effect: str, base_error: str ) -> None: """Test config flow errors.""" result4 = await hass.config_entries.flow.async_init( @@ -92,7 +93,7 @@ async def test_flow_fails( with patch( "homeassistant.components.trafikverket_ferry.config_flow.TrafikverketFerry.async_get_next_ferry_stop", - side_effect=ValueError(error_message), + side_effect=side_effect(), ): result4 = await hass.config_entries.flow.async_configure( result4["flow_id"], @@ -161,24 +162,24 @@ async def test_reauth_flow(hass: HomeAssistant) -> None: @pytest.mark.parametrize( - ("sideeffect", "p_error"), + ("side_effect", "p_error"), [ ( - ValueError("Source: Security, message: Invalid authentication"), + InvalidAuthentication, "invalid_auth", ), ( - ValueError("No FerryAnnouncement found"), + NoFerryFound, "invalid_route", ), ( - ValueError("Unknown"), + Exception, "cannot_connect", ), ], ) async def test_reauth_flow_error( - hass: HomeAssistant, sideeffect: Exception, p_error: str + hass: HomeAssistant, side_effect: Exception, p_error: str ) -> None: """Test a reauthentication flow with error.""" entry = MockConfigEntry( @@ -207,7 +208,7 @@ async def test_reauth_flow_error( with patch( "homeassistant.components.trafikverket_ferry.config_flow.TrafikverketFerry.async_get_next_ferry_stop", - side_effect=sideeffect, + side_effect=side_effect(), ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], diff --git a/tests/components/trafikverket_ferry/test_coordinator.py b/tests/components/trafikverket_ferry/test_coordinator.py index 7714e0c38f6..61c72b82a3f 100644 --- a/tests/components/trafikverket_ferry/test_coordinator.py +++ b/tests/components/trafikverket_ferry/test_coordinator.py @@ -2,10 +2,11 @@ from __future__ import annotations from datetime import date, datetime, timedelta -from unittest.mock import AsyncMock, patch +from unittest.mock import patch from freezegun.api import FrozenDateTimeFactory import pytest +from pytrafikverket.exceptions import InvalidAuthentication, NoFerryFound from pytrafikverket.trafikverket_ferry import FerryStop from homeassistant.components.trafikverket_ferry.const import DOMAIN @@ -22,7 +23,7 @@ from tests.common import MockConfigEntry, async_fire_time_changed async def test_coordinator( hass: HomeAssistant, - entity_registry_enabled_by_default: AsyncMock, + entity_registry_enabled_by_default: None, monkeypatch: pytest.MonkeyPatch, get_ferries: list[FerryStop], ) -> None: @@ -69,7 +70,7 @@ async def test_coordinator( assert state3.state == str(dt.now().year + 2) + "-05-01T12:00:00+00:00" mock_data.reset_mock() - mock_data.side_effect = ValueError("info") + mock_data.side_effect = NoFerryFound() async_fire_time_changed(hass, dt.utcnow() + timedelta(minutes=6)) await hass.async_block_till_done() mock_data.assert_called_once() @@ -81,11 +82,19 @@ async def test_coordinator( mock_data.side_effect = None async_fire_time_changed(hass, dt.utcnow() + timedelta(minutes=6)) await hass.async_block_till_done() - mock_data.assert_called_once() + # mock_data.assert_called_once() state1 = hass.states.get("sensor.harbor1_departure_from") assert state1.state == "Harbor 1" mock_data.reset_mock() + mock_data.side_effect = InvalidAuthentication() + async_fire_time_changed(hass, dt.utcnow() + timedelta(minutes=6)) + await hass.async_block_till_done() + mock_data.assert_called_once() + state1 = hass.states.get("sensor.harbor1_departure_from") + assert state1.state == STATE_UNAVAILABLE + mock_data.reset_mock() + async def test_coordinator_next_departuredate(freezer: FrozenDateTimeFactory) -> None: """Test the Trafikverket Ferry next_departuredate calculation.""" diff --git a/tests/components/trafikverket_train/test_config_flow.py b/tests/components/trafikverket_train/test_config_flow.py index 0169332609a..424e1d74162 100644 --- a/tests/components/trafikverket_train/test_config_flow.py +++ b/tests/components/trafikverket_train/test_config_flow.py @@ -4,6 +4,11 @@ from __future__ import annotations from unittest.mock import patch import pytest +from pytrafikverket.exceptions import ( + InvalidAuthentication, + MultipleTrainStationsFound, + NoTrainStationFound, +) from homeassistant import config_entries from homeassistant.components.trafikverket_train.const import ( @@ -108,28 +113,28 @@ async def test_form_entry_already_exist(hass: HomeAssistant) -> None: @pytest.mark.parametrize( - ("error_message", "base_error"), + ("side_effect", "base_error"), [ ( - "Source: Security, message: Invalid authentication", + InvalidAuthentication, "invalid_auth", ), ( - "Could not find a station with the specified name", + NoTrainStationFound, "invalid_station", ), ( - "Found multiple stations with the specified name", + MultipleTrainStationsFound, "more_stations", ), ( - "Unknown", + Exception, "cannot_connect", ), ], ) async def test_flow_fails( - hass: HomeAssistant, error_message: str, base_error: str + hass: HomeAssistant, side_effect: Exception, base_error: str ) -> None: """Test config flow errors.""" result4 = await hass.config_entries.flow.async_init( @@ -141,7 +146,7 @@ async def test_flow_fails( with patch( "homeassistant.components.trafikverket_train.config_flow.TrafikverketTrain.async_get_train_station", - side_effect=ValueError(error_message), + side_effect=side_effect(), ): result4 = await hass.config_entries.flow.async_configure( result4["flow_id"], @@ -234,28 +239,28 @@ async def test_reauth_flow(hass: HomeAssistant) -> None: @pytest.mark.parametrize( - ("sideeffect", "p_error"), + ("side_effect", "p_error"), [ ( - ValueError("Source: Security, message: Invalid authentication"), + InvalidAuthentication, "invalid_auth", ), ( - ValueError("Could not find a station with the specified name"), + NoTrainStationFound, "invalid_station", ), ( - ValueError("Found multiple stations with the specified name"), + MultipleTrainStationsFound, "more_stations", ), ( - ValueError("Unknown"), + Exception, "cannot_connect", ), ], ) async def test_reauth_flow_error( - hass: HomeAssistant, sideeffect: Exception, p_error: str + hass: HomeAssistant, side_effect: Exception, p_error: str ) -> None: """Test a reauthentication flow with error.""" entry = MockConfigEntry( @@ -284,7 +289,7 @@ async def test_reauth_flow_error( with patch( "homeassistant.components.trafikverket_train.config_flow.TrafikverketTrain.async_get_train_station", - side_effect=sideeffect, + side_effect=side_effect(), ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], diff --git a/tests/components/trafikverket_weatherstation/test_config_flow.py b/tests/components/trafikverket_weatherstation/test_config_flow.py index ed0ff9bb119..36c30b33b53 100644 --- a/tests/components/trafikverket_weatherstation/test_config_flow.py +++ b/tests/components/trafikverket_weatherstation/test_config_flow.py @@ -4,6 +4,11 @@ from __future__ import annotations from unittest.mock import patch import pytest +from pytrafikverket.exceptions import ( + InvalidAuthentication, + MultipleWeatherStationsFound, + NoWeatherStationFound, +) from homeassistant import config_entries from homeassistant.const import CONF_API_KEY @@ -48,28 +53,28 @@ async def test_form(hass: HomeAssistant) -> None: @pytest.mark.parametrize( - ("error_message", "base_error"), + ("side_effect", "base_error"), [ ( - "Source: Security, message: Invalid authentication", + InvalidAuthentication, "invalid_auth", ), ( - "Could not find a weather station with the specified name", + NoWeatherStationFound, "invalid_station", ), ( - "Found multiple weather stations with the specified name", + MultipleWeatherStationsFound, "more_stations", ), ( - "Unknown", + Exception, "cannot_connect", ), ], ) async def test_flow_fails( - hass: HomeAssistant, error_message: str, base_error: str + hass: HomeAssistant, side_effect: Exception, base_error: str ) -> None: """Test config flow errors.""" result4 = await hass.config_entries.flow.async_init( @@ -81,7 +86,7 @@ async def test_flow_fails( with patch( "homeassistant.components.trafikverket_weatherstation.config_flow.TrafikverketWeather.async_get_weather", - side_effect=ValueError(error_message), + side_effect=side_effect(), ): result4 = await hass.config_entries.flow.async_configure( result4["flow_id"],