diff --git a/tests/components/weather/__init__.py b/tests/components/weather/__init__.py index 91097dfae14..35a818735d0 100644 --- a/tests/components/weather/__init__.py +++ b/tests/components/weather/__init__.py @@ -1,14 +1,71 @@ """The tests for Weather platforms.""" -from homeassistant.components.weather import ATTR_CONDITION_SUNNY -from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component +from typing import Any +from homeassistant.components.weather import ( + ATTR_CONDITION_SUNNY, + ATTR_FORECAST_CLOUD_COVERAGE, + ATTR_FORECAST_HUMIDITY, + ATTR_FORECAST_NATIVE_APPARENT_TEMP, + ATTR_FORECAST_NATIVE_DEW_POINT, + ATTR_FORECAST_NATIVE_PRECIPITATION, + ATTR_FORECAST_NATIVE_PRESSURE, + ATTR_FORECAST_NATIVE_TEMP, + ATTR_FORECAST_NATIVE_TEMP_LOW, + ATTR_FORECAST_NATIVE_WIND_GUST_SPEED, + ATTR_FORECAST_NATIVE_WIND_SPEED, + ATTR_FORECAST_UV_INDEX, + ATTR_FORECAST_WIND_BEARING, + DOMAIN, + Forecast, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from tests.common import ( + MockConfigEntry, + MockModule, + MockPlatform, + mock_integration, + mock_platform, +) from tests.testing_config.custom_components.test import weather as WeatherPlatform -async def create_entity(hass: HomeAssistant, **kwargs): +class MockWeatherTest(WeatherPlatform.MockWeather): + """Mock weather class.""" + + def __init__(self, **values: Any) -> None: + """Initialize.""" + super().__init__(**values) + self.forecast_list: list[Forecast] | None = [ + { + ATTR_FORECAST_NATIVE_TEMP: self.native_temperature, + ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature, + ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature, + ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point, + ATTR_FORECAST_CLOUD_COVERAGE: self.cloud_coverage, + ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure, + ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: self.native_wind_gust_speed, + ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed, + ATTR_FORECAST_WIND_BEARING: self.wind_bearing, + ATTR_FORECAST_UV_INDEX: self.uv_index, + ATTR_FORECAST_NATIVE_PRECIPITATION: self._values.get( + "native_precipitation" + ), + ATTR_FORECAST_HUMIDITY: self.humidity, + } + ] + + +async def create_entity( + hass: HomeAssistant, + mock_weather: WeatherPlatform.MockWeather, + manifest_extra: dict[str, Any] | None, + **kwargs, +) -> WeatherPlatform.MockWeather: """Create the weather entity to run tests on.""" kwargs = { "native_temperature": None, @@ -16,17 +73,47 @@ async def create_entity(hass: HomeAssistant, **kwargs): "is_daytime": True, **kwargs, } - platform: WeatherPlatform = getattr(hass.components, "test.weather") - platform.init(empty=True) - platform.ENTITIES.append( - platform.MockWeatherMockForecast( - name="Test", condition=ATTR_CONDITION_SUNNY, **kwargs - ) + + weather_entity = mock_weather( + name="Testing", + entity_id="weather.testing", + condition=ATTR_CONDITION_SUNNY, + **kwargs, ) - entity0 = platform.ENTITIES[0] - assert await async_setup_component( - hass, "weather", {"weather": {"platform": "test"}} + async def async_setup_entry_init( + hass: HomeAssistant, config_entry: ConfigEntry + ) -> bool: + """Set up test config entry.""" + await hass.config_entries.async_forward_entry_setups(config_entry, [DOMAIN]) + return True + + async def async_setup_entry_weather_platform( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, + ) -> None: + """Set up test weather platform via config entry.""" + async_add_entities([weather_entity]) + + mock_integration( + hass, + MockModule( + "test", + async_setup_entry=async_setup_entry_init, + partial_manifest=manifest_extra, + ), + built_in=False, ) + mock_platform( + hass, + "test.weather", + MockPlatform(async_setup_entry=async_setup_entry_weather_platform), + ) + + config_entry = MockConfigEntry(domain="test") + config_entry.add_to_hass(hass) + assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - return entity0 + + return weather_entity diff --git a/tests/components/weather/conftest.py b/tests/components/weather/conftest.py new file mode 100644 index 00000000000..a85b5e85d4b --- /dev/null +++ b/tests/components/weather/conftest.py @@ -0,0 +1,22 @@ +"""Fixtures for Weather platform tests.""" +from collections.abc import Generator + +import pytest + +from homeassistant.config_entries import ConfigFlow +from homeassistant.core import HomeAssistant + +from tests.common import mock_config_flow, mock_platform + + +class MockFlow(ConfigFlow): + """Test flow.""" + + +@pytest.fixture +def config_flow_fixture(hass: HomeAssistant) -> Generator[None, None, None]: + """Mock config flow.""" + mock_platform(hass, "test.config_flow") + + with mock_config_flow("test", MockFlow): + yield diff --git a/tests/components/weather/test_init.py b/tests/components/weather/test_init.py index f17edb16f07..f62bed295da 100644 --- a/tests/components/weather/test_init.py +++ b/tests/components/weather/test_init.py @@ -1,7 +1,5 @@ """The test for weather entity.""" -from collections.abc import Generator from datetime import datetime -from typing import Any import pytest from syrupy.assertion import SnapshotAssertion @@ -10,23 +8,13 @@ from homeassistant.components.weather import ( ATTR_CONDITION_SUNNY, ATTR_FORECAST, ATTR_FORECAST_APPARENT_TEMP, - ATTR_FORECAST_CLOUD_COVERAGE, ATTR_FORECAST_DEW_POINT, ATTR_FORECAST_HUMIDITY, - ATTR_FORECAST_NATIVE_APPARENT_TEMP, - ATTR_FORECAST_NATIVE_DEW_POINT, - ATTR_FORECAST_NATIVE_PRECIPITATION, - ATTR_FORECAST_NATIVE_PRESSURE, - ATTR_FORECAST_NATIVE_TEMP, - ATTR_FORECAST_NATIVE_TEMP_LOW, - ATTR_FORECAST_NATIVE_WIND_GUST_SPEED, - ATTR_FORECAST_NATIVE_WIND_SPEED, ATTR_FORECAST_PRECIPITATION, ATTR_FORECAST_PRESSURE, ATTR_FORECAST_TEMP, ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_UV_INDEX, - ATTR_FORECAST_WIND_BEARING, ATTR_FORECAST_WIND_GUST_SPEED, ATTR_FORECAST_WIND_SPEED, ATTR_WEATHER_APPARENT_TEMPERATURE, @@ -56,7 +44,6 @@ from homeassistant.components.weather.const import ( ATTR_WEATHER_DEW_POINT, ATTR_WEATHER_HUMIDITY, ) -from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.const import ( PRECISION_HALVES, PRECISION_TENTHS, @@ -69,9 +56,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback import homeassistant.helpers.issue_registry as ir -from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util from homeassistant.util.unit_conversion import ( DistanceConverter, @@ -81,20 +66,8 @@ from homeassistant.util.unit_conversion import ( ) from homeassistant.util.unit_system import METRIC_SYSTEM, US_CUSTOMARY_SYSTEM -from . import create_entity +from . import MockWeatherTest, create_entity -from tests.common import ( - MockConfigEntry, - MockModule, - MockPlatform, - mock_config_flow, - mock_integration, - mock_platform, -) -from tests.testing_config.custom_components.test import weather as WeatherPlatform -from tests.testing_config.custom_components.test_weather import ( - weather as NewWeatherPlatform, -) from tests.typing import WebSocketGenerator @@ -134,20 +107,6 @@ class MockWeatherEntity(WeatherEntity): ] -class MockWeatherEntityPrecision(WeatherEntity): - """Mock a Weather Entity with precision.""" - - def __init__(self) -> None: - """Initiate Entity.""" - super().__init__() - self._attr_condition = ATTR_CONDITION_SUNNY - self._attr_native_temperature = 20.3 - self._attr_native_apparent_temperature = 25.3 - self._attr_native_dew_point = 2.3 - self._attr_native_temperature_unit = UnitOfTemperature.CELSIUS - self._attr_precision = PRECISION_HALVES - - @pytest.mark.parametrize( "native_unit", (UnitOfTemperature.FAHRENHEIT, UnitOfTemperature.CELSIUS) ) @@ -160,7 +119,7 @@ class MockWeatherEntityPrecision(WeatherEntity): ) async def test_temperature( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -179,13 +138,23 @@ async def test_temperature( dew_point_state_value = TemperatureConverter.convert( dew_point_native_value, native_unit, state_unit ) - entity0 = await create_entity( - hass, - native_temperature=native_value, - native_temperature_unit=native_unit, - native_apparent_temperature=apparent_native_value, - native_dew_point=dew_point_native_value, - ) + + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "native_temperature": native_value, + "native_temperature_unit": native_unit, + "native_apparent_temperature": apparent_native_value, + "native_dew_point": dew_point_native_value, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast_daily = state.attributes[ATTR_FORECAST][0] @@ -229,7 +198,7 @@ async def test_temperature( ) async def test_temperature_no_unit( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -243,13 +212,22 @@ async def test_temperature_no_unit( dew_point_state_value = dew_point_native_value apparent_temp_state_value = apparent_temp_native_value - entity0 = await create_entity( - hass, - native_temperature=native_value, - native_temperature_unit=native_unit, - native_dew_point=dew_point_native_value, - native_apparent_temperature=apparent_temp_native_value, - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "native_temperature": native_value, + "native_temperature_unit": native_unit, + "native_dew_point": dew_point_native_value, + "native_apparent_temperature": apparent_temp_native_value, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -284,7 +262,7 @@ async def test_temperature_no_unit( ) async def test_pressure( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -294,9 +272,18 @@ async def test_pressure( native_value = 30 state_value = PressureConverter.convert(native_value, native_unit, state_unit) - entity0 = await create_entity( - hass, native_pressure=native_value, native_pressure_unit=native_unit - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = {"native_pressure": native_value, "native_pressure_unit": native_unit} + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) + state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -314,7 +301,7 @@ async def test_pressure( ) async def test_pressure_no_unit( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -324,9 +311,18 @@ async def test_pressure_no_unit( native_value = 30 state_value = native_value - entity0 = await create_entity( - hass, native_pressure=native_value, native_pressure_unit=native_unit - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = {"native_pressure": native_value, "native_pressure_unit": native_unit} + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) + state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -354,7 +350,7 @@ async def test_pressure_no_unit( ) async def test_wind_speed( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -364,9 +360,17 @@ async def test_wind_speed( native_value = 10 state_value = SpeedConverter.convert(native_value, native_unit, state_unit) - entity0 = await create_entity( - hass, native_wind_speed=native_value, native_wind_speed_unit=native_unit - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = {"native_wind_speed": native_value, "native_wind_speed_unit": native_unit} + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -397,7 +401,7 @@ async def test_wind_speed( ) async def test_wind_gust_speed( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -407,9 +411,20 @@ async def test_wind_gust_speed( native_value = 10 state_value = SpeedConverter.convert(native_value, native_unit, state_unit) - entity0 = await create_entity( - hass, native_wind_gust_speed=native_value, native_wind_speed_unit=native_unit - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "native_wind_gust_speed": native_value, + "native_wind_speed_unit": native_unit, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -433,7 +448,7 @@ async def test_wind_gust_speed( ) async def test_wind_speed_no_unit( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -443,9 +458,17 @@ async def test_wind_speed_no_unit( native_value = 10 state_value = native_value - entity0 = await create_entity( - hass, native_wind_speed=native_value, native_wind_speed_unit=native_unit - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = {"native_wind_speed": native_value, "native_wind_speed_unit": native_unit} + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -469,7 +492,7 @@ async def test_wind_speed_no_unit( ) async def test_visibility( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -479,9 +502,17 @@ async def test_visibility( native_value = 10 state_value = DistanceConverter.convert(native_value, native_unit, state_unit) - entity0 = await create_entity( - hass, native_visibility=native_value, native_visibility_unit=native_unit - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = {"native_visibility": native_value, "native_visibility_unit": native_unit} + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) expected = state_value @@ -500,7 +531,7 @@ async def test_visibility( ) async def test_visibility_no_unit( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -510,9 +541,17 @@ async def test_visibility_no_unit( native_value = 10 state_value = native_value - entity0 = await create_entity( - hass, native_visibility=native_value, native_visibility_unit=native_unit - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = {"native_visibility": native_value, "native_visibility_unit": native_unit} + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) expected = state_value @@ -531,7 +570,7 @@ async def test_visibility_no_unit( ) async def test_precipitation( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -541,9 +580,20 @@ async def test_precipitation( native_value = 30 state_value = DistanceConverter.convert(native_value, native_unit, state_unit) - entity0 = await create_entity( - hass, native_precipitation=native_value, native_precipitation_unit=native_unit - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "native_precipitation": native_value, + "native_precipitation_unit": native_unit, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -564,7 +614,7 @@ async def test_precipitation( ) async def test_precipitation_no_unit( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, native_unit: str, state_unit: str, unit_system, @@ -574,9 +624,20 @@ async def test_precipitation_no_unit( native_value = 30 state_value = native_value - entity0 = await create_entity( - hass, native_precipitation=native_value, native_precipitation_unit=native_unit - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "native_precipitation": native_value, + "native_precipitation_unit": native_unit, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -589,7 +650,7 @@ async def test_precipitation_no_unit( async def test_wind_bearing_ozone_and_cloud_coverage_and_uv_index( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, ) -> None: """Test wind bearing, ozone and cloud coverage.""" wind_bearing_value = 180 @@ -597,13 +658,22 @@ async def test_wind_bearing_ozone_and_cloud_coverage_and_uv_index( cloud_coverage = 75 uv_index = 1.2 - entity0 = await create_entity( - hass, - wind_bearing=wind_bearing_value, - ozone=ozone_value, - cloud_coverage=cloud_coverage, - uv_index=uv_index, - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "wind_bearing": wind_bearing_value, + "ozone": ozone_value, + "cloud_coverage": cloud_coverage, + "uv_index": uv_index, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -616,12 +686,22 @@ async def test_wind_bearing_ozone_and_cloud_coverage_and_uv_index( async def test_humidity( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, ) -> None: """Test humidity.""" humidity_value = 80.2 - entity0 = await create_entity(hass, humidity=humidity_value) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = {"humidity": humidity_value} + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -631,18 +711,28 @@ async def test_humidity( async def test_none_forecast( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, ) -> None: """Test that conversion with None values succeeds.""" - entity0 = await create_entity( - hass, - native_pressure=None, - native_pressure_unit=UnitOfPressure.INHG, - native_wind_speed=None, - native_wind_speed_unit=UnitOfSpeed.METERS_PER_SECOND, - native_precipitation=None, - native_precipitation_unit=UnitOfLength.MILLIMETERS, - ) + + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "native_pressure": None, + "native_pressure_unit": UnitOfPressure.INHG, + "native_wind_speed": None, + "native_wind_speed_unit": UnitOfSpeed.METERS_PER_SECOND, + "native_precipitation": None, + "native_precipitation_unit": UnitOfLength.MILLIMETERS, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -652,9 +742,7 @@ async def test_none_forecast( assert forecast.get(ATTR_FORECAST_PRECIPITATION) is None -async def test_custom_units( - hass: HomeAssistant, enable_custom_integrations: None -) -> None: +async def test_custom_units(hass: HomeAssistant, config_flow_fixture: None) -> None: """Test custom unit.""" wind_speed_value = 5 wind_speed_unit = UnitOfSpeed.METERS_PER_SECOND @@ -681,32 +769,30 @@ async def test_custom_units( entity_registry.async_update_entity_options(entry.entity_id, "weather", set_options) await hass.async_block_till_done() - platform: WeatherPlatform = getattr(hass.components, "test.weather") - platform.init(empty=True) - platform.ENTITIES.append( - platform.MockWeatherMockForecast( - name="Test", - condition=ATTR_CONDITION_SUNNY, - native_temperature=temperature_value, - native_temperature_unit=temperature_unit, - native_wind_speed=wind_speed_value, - native_wind_speed_unit=wind_speed_unit, - native_pressure=pressure_value, - native_pressure_unit=pressure_unit, - native_visibility=visibility_value, - native_visibility_unit=visibility_unit, - native_precipitation=precipitation_value, - native_precipitation_unit=precipitation_unit, - is_daytime=True, - unique_id="very_unique", - ) - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" - entity0 = platform.ENTITIES[0] - assert await async_setup_component( - hass, "weather", {"weather": {"platform": "test"}} - ) - await hass.async_block_till_done() + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "native_temperature": temperature_value, + "native_temperature_unit": temperature_unit, + "native_wind_speed": wind_speed_value, + "native_wind_speed_unit": wind_speed_unit, + "native_pressure": pressure_value, + "native_pressure_unit": pressure_unit, + "native_visibility": visibility_value, + "native_visibility_unit": visibility_unit, + "native_precipitation": precipitation_value, + "native_precipitation_unit": precipitation_unit, + "is_daytime": True, + "unique_id": "very_unique", + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) state = hass.states.get(entity0.entity_id) forecast = state.attributes[ATTR_FORECAST][0] @@ -802,36 +888,55 @@ async def test_attr(hass: HomeAssistant) -> None: assert weather._wind_speed_unit == UnitOfSpeed.KILOMETERS_PER_HOUR -async def test_precision_for_temperature(hass: HomeAssistant) -> None: +async def test_precision_for_temperature( + hass: HomeAssistant, + config_flow_fixture: None, +) -> None: """Test the precision for temperature.""" - weather = MockWeatherEntityPrecision() - weather.hass = hass + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" - assert weather.condition == ATTR_CONDITION_SUNNY - assert weather.native_temperature == 20.3 - assert weather.native_dew_point == 2.3 - assert weather._temperature_unit == UnitOfTemperature.CELSIUS - assert weather.precision == PRECISION_HALVES + kwargs = { + "precision": PRECISION_HALVES, + "native_temperature": 23.3, + "native_temperature_unit": UnitOfTemperature.CELSIUS, + "native_dew_point": 2.7, + } - assert weather.state_attributes[ATTR_WEATHER_TEMPERATURE] == 20.5 - assert weather.state_attributes[ATTR_WEATHER_DEW_POINT] == 2.5 + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) + + state = hass.states.get(entity0.entity_id) + + assert state.state == ATTR_CONDITION_SUNNY + assert state.attributes[ATTR_WEATHER_TEMPERATURE] == 23.5 + assert state.attributes[ATTR_WEATHER_DEW_POINT] == 2.5 + assert state.attributes[ATTR_WEATHER_TEMPERATURE_UNIT] == UnitOfTemperature.CELSIUS async def test_forecast_twice_daily_missing_is_daytime( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, - enable_custom_integrations: None, + config_flow_fixture: None, ) -> None: """Test forecast_twice_daily missing mandatory attribute is_daytime.""" - entity0 = await create_entity( - hass, - native_temperature=38, - native_temperature_unit=UnitOfTemperature.CELSIUS, - is_daytime=None, - supported_features=WeatherEntityFeature.FORECAST_TWICE_DAILY, - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "native_temperature": 38, + "native_temperature_unit": UnitOfTemperature.CELSIUS, + "is_daytime": None, + "supported_features": WeatherEntityFeature.FORECAST_TWICE_DAILY, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) client = await hass_ws_client(hass) @@ -867,19 +972,37 @@ async def test_forecast_twice_daily_missing_is_daytime( ) async def test_get_forecast( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, forecast_type: str, supported_features: int, snapshot: SnapshotAssertion, ) -> None: """Test get forecast service.""" - entity0 = await create_entity( - hass, - native_temperature=38, - native_temperature_unit=UnitOfTemperature.CELSIUS, - supported_features=supported_features, - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + async def async_forecast_daily(self) -> list[Forecast] | None: + """Return the forecast_daily.""" + return self.forecast_list + + async def async_forecast_twice_daily(self) -> list[Forecast] | None: + """Return the forecast_twice_daily.""" + forecast = self.forecast_list[0] + forecast["is_daytime"] = True + return [forecast] + + async def async_forecast_hourly(self) -> list[Forecast] | None: + """Return the forecast_hourly.""" + return self.forecast_list + + kwargs = { + "native_temperature": 38, + "native_temperature_unit": UnitOfTemperature.CELSIUS, + "supported_features": supported_features, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) response = await hass.services.async_call( DOMAIN, @@ -896,18 +1019,25 @@ async def test_get_forecast( async def test_get_forecast_no_forecast( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, ) -> None: """Test get forecast service.""" - entity0 = await create_entity( - hass, - native_temperature=38, - native_temperature_unit=UnitOfTemperature.CELSIUS, - supported_features=WeatherEntityFeature.FORECAST_DAILY, - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + + async def async_forecast_daily(self) -> list[Forecast] | None: + """Return the forecast_daily.""" + return None + + kwargs = { + "native_temperature": 38, + "native_temperature_unit": UnitOfTemperature.CELSIUS, + "supported_features": WeatherEntityFeature.FORECAST_DAILY, + } + + entity0 = await create_entity(hass, MockWeatherMock, None, **kwargs) - entity0.forecast_list = None response = await hass.services.async_call( DOMAIN, SERVICE_GET_FORECAST, @@ -933,18 +1063,33 @@ async def test_get_forecast_no_forecast( ) async def test_get_forecast_unsupported( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, forecast_types: list[str], supported_features: int, ) -> None: """Test get forecast service.""" - entity0 = await create_entity( - hass, - native_temperature=38, - native_temperature_unit=UnitOfTemperature.CELSIUS, - supported_features=supported_features, - ) + class MockWeatherMockForecast(MockWeatherTest): + """Mock weather class with mocked legacy forecast.""" + + async def async_forecast_daily(self) -> list[Forecast] | None: + """Return the forecast_daily.""" + return self.forecast_list + + async def async_forecast_twice_daily(self) -> list[Forecast] | None: + """Return the forecast_twice_daily.""" + return self.forecast_list + + async def async_forecast_hourly(self) -> list[Forecast] | None: + """Return the forecast_hourly.""" + return self.forecast_list + + kwargs = { + "native_temperature": 38, + "native_temperature_unit": UnitOfTemperature.CELSIUS, + "supported_features": supported_features, + } + weather_entity = await create_entity(hass, MockWeatherMockForecast, None, **kwargs) for forecast_type in forecast_types: with pytest.raises(HomeAssistantError): @@ -952,7 +1097,7 @@ async def test_get_forecast_unsupported( DOMAIN, SERVICE_GET_FORECAST, { - "entity_id": entity0.entity_id, + "entity_id": weather_entity.entity_id, "type": forecast_type, }, blocking=True, @@ -960,19 +1105,6 @@ async def test_get_forecast_unsupported( ) -class MockFlow(ConfigFlow): - """Test flow.""" - - -@pytest.fixture -def config_flow_fixture(hass: HomeAssistant) -> Generator[None, None, None]: - """Mock config flow.""" - mock_platform(hass, "test.config_flow") - - with mock_config_flow("test", MockFlow): - yield - - ISSUE_TRACKER = "https://blablabla.com" @@ -1004,31 +1136,9 @@ async def test_issue_forecast_property_deprecated( ) -> None: """Test the issue is raised on deprecated forecast attributes.""" - class MockWeatherMockLegacyForecastOnly(WeatherPlatform.MockWeather): + class MockWeatherMockLegacyForecastOnly(MockWeatherTest): """Mock weather class with mocked legacy forecast.""" - def __init__(self, **values: Any) -> None: - """Initialize.""" - super().__init__(**values) - self.forecast_list: list[Forecast] | None = [ - { - ATTR_FORECAST_NATIVE_TEMP: self.native_temperature, - ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature, - ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature, - ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point, - ATTR_FORECAST_CLOUD_COVERAGE: self.cloud_coverage, - ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure, - ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: self.native_wind_gust_speed, - ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed, - ATTR_FORECAST_WIND_BEARING: self.wind_bearing, - ATTR_FORECAST_UV_INDEX: self.uv_index, - ATTR_FORECAST_NATIVE_PRECIPITATION: self._values.get( - "native_precipitation" - ), - ATTR_FORECAST_HUMIDITY: self.humidity, - } - ] - @property def forecast(self) -> list[Forecast] | None: """Return the forecast.""" @@ -1041,48 +1151,10 @@ async def test_issue_forecast_property_deprecated( "native_temperature": 38, "native_temperature_unit": UnitOfTemperature.CELSIUS, } - weather_entity = MockWeatherMockLegacyForecastOnly( - name="Testing", - entity_id="weather.testing", - condition=ATTR_CONDITION_SUNNY, - **kwargs, + weather_entity = await create_entity( + hass, MockWeatherMockLegacyForecastOnly, manifest_extra, **kwargs ) - async def async_setup_entry_init( - hass: HomeAssistant, config_entry: ConfigEntry - ) -> bool: - """Set up test config entry.""" - await hass.config_entries.async_forward_entry_setups(config_entry, [DOMAIN]) - return True - - async def async_setup_entry_weather_platform( - hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, - ) -> None: - """Set up test weather platform via config entry.""" - async_add_entities([weather_entity]) - - mock_integration( - hass, - MockModule( - "test", - async_setup_entry=async_setup_entry_init, - partial_manifest=manifest_extra, - ), - built_in=False, - ) - mock_platform( - hass, - "test.weather", - MockPlatform(async_setup_entry=async_setup_entry_weather_platform), - ) - - config_entry = MockConfigEntry(domain="test") - config_entry.add_to_hass(hass) - assert await hass.config_entries.async_setup(config_entry.entry_id) - await hass.async_block_till_done() - assert weather_entity.state == ATTR_CONDITION_SUNNY issues = ir.async_get(hass) @@ -1105,37 +1177,37 @@ async def test_issue_forecast_property_deprecated( async def test_issue_forecast_attr_deprecated( hass: HomeAssistant, - enable_custom_integrations: None, + issue_registry: ir.IssueRegistry, + config_flow_fixture: None, caplog: pytest.LogCaptureFixture, ) -> None: """Test the issue is raised on deprecated forecast attributes.""" + class MockWeatherMockLegacyForecast(MockWeatherTest): + """Mock weather class with legacy forecast.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + kwargs = { "native_temperature": 38, "native_temperature_unit": UnitOfTemperature.CELSIUS, } - platform: WeatherPlatform = getattr(hass.components, "test.weather") - caplog.clear() - platform.init(empty=True) - weather = platform.MockWeather( - name="Testing", - entity_id="weather.testing", - condition=ATTR_CONDITION_SUNNY, - **kwargs, + + # Fake that the class belongs to a custom integration + MockWeatherMockLegacyForecast.__module__ = "custom_components.test.weather" + + weather_entity = await create_entity( + hass, MockWeatherMockLegacyForecast, None, **kwargs ) - weather._attr_forecast = [] - platform.ENTITIES.append(weather) - entity0 = platform.ENTITIES[0] - assert await async_setup_component( - hass, "weather", {"weather": {"platform": "test", "name": "testing"}} + assert weather_entity.state == ATTR_CONDITION_SUNNY + + issue = issue_registry.async_get_issue( + "weather", "deprecated_weather_forecast_test" ) - await hass.async_block_till_done() - - assert entity0.state == ATTR_CONDITION_SUNNY - - issues = ir.async_get(hass) - issue = issues.async_get_issue("weather", "deprecated_weather_forecast_test") assert issue assert issue.issue_domain == "test" assert issue.issue_id == "deprecated_weather_forecast_test" @@ -1143,7 +1215,7 @@ async def test_issue_forecast_attr_deprecated( assert issue.translation_placeholders == {"platform": "test"} assert ( - "test::MockWeather implements the `forecast` property or " + "test::MockWeatherMockLegacyForecast implements the `forecast` property or " "sets `self._attr_forecast` in a subclass of WeatherEntity, this is deprecated " "and will be unsupported from Home Assistant 2024.3. Please report it to the " "author of the 'test' custom integration" @@ -1152,36 +1224,33 @@ async def test_issue_forecast_attr_deprecated( async def test_issue_forecast_deprecated_no_logging( hass: HomeAssistant, - enable_custom_integrations: None, + config_flow_fixture: None, caplog: pytest.LogCaptureFixture, ) -> None: """Test the no issue is raised on deprecated forecast attributes if new methods exist.""" + class MockWeatherMockForecast(MockWeatherTest): + """Mock weather class with mocked new method and legacy forecast.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + async def async_forecast_daily(self) -> list[Forecast] | None: + """Return the forecast_daily.""" + return self.forecast_list + kwargs = { "native_temperature": 38, "native_temperature_unit": UnitOfTemperature.CELSIUS, } - platform: NewWeatherPlatform = getattr(hass.components, "test_weather.weather") - caplog.clear() - platform.init(empty=True) - platform.ENTITIES.append( - platform.MockWeatherMockForecast( - name="Test", - entity_id="weather.test", - condition=ATTR_CONDITION_SUNNY, - **kwargs, - ) - ) - entity0 = platform.ENTITIES[0] - assert await async_setup_component( - hass, "weather", {"weather": {"platform": "test_weather", "name": "test"}} - ) - await hass.async_block_till_done() + weather_entity = await create_entity(hass, MockWeatherMockForecast, None, **kwargs) - assert entity0.state == ATTR_CONDITION_SUNNY + assert weather_entity.state == ATTR_CONDITION_SUNNY - assert "Setting up weather.test_weather" in caplog.text + assert "Setting up weather.test" in caplog.text assert ( "custom_components.test_weather.weather::weather.test is using a forecast attribute on an instance of WeatherEntity" not in caplog.text diff --git a/tests/components/weather/test_recorder.py b/tests/components/weather/test_recorder.py index 049a38cac1e..6b2ce4b633a 100644 --- a/tests/components/weather/test_recorder.py +++ b/tests/components/weather/test_recorder.py @@ -5,56 +5,43 @@ from datetime import timedelta from homeassistant.components.recorder import Recorder from homeassistant.components.recorder.history import get_significant_states -from homeassistant.components.weather import ATTR_CONDITION_SUNNY, ATTR_FORECAST +from homeassistant.components.weather import ATTR_FORECAST, Forecast from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util from homeassistant.util.unit_system import METRIC_SYSTEM +from . import MockWeatherTest, create_entity + from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done -from tests.testing_config.custom_components.test import weather as WeatherPlatform - - -async def create_entity(hass: HomeAssistant, **kwargs): - """Create the weather entity to run tests on.""" - kwargs = { - "native_temperature": None, - "native_temperature_unit": None, - "is_daytime": True, - **kwargs, - } - platform: WeatherPlatform = getattr(hass.components, "test.weather") - platform.init(empty=True) - platform.ENTITIES.append( - platform.MockWeatherMockForecast( - name="Test", condition=ATTR_CONDITION_SUNNY, **kwargs - ) - ) - - entity0 = platform.ENTITIES[0] - assert await async_setup_component( - hass, "weather", {"weather": {"platform": "test"}} - ) - await hass.async_block_till_done() - return entity0 async def test_exclude_attributes( - recorder_mock: Recorder, hass: HomeAssistant, enable_custom_integrations: None + recorder_mock: Recorder, + hass: HomeAssistant, + config_flow_fixture: None, ) -> None: """Test weather attributes to be excluded.""" now = dt_util.utcnow() - entity0 = await create_entity( - hass, - native_temperature=38, - native_temperature_unit=UnitOfTemperature.CELSIUS, - ) + + class MockWeatherMockForecast(MockWeatherTest): + """Mock weather class with mocked legacy forecast.""" + + @property + def forecast(self) -> list[Forecast] | None: + """Return the forecast.""" + return self.forecast_list + + kwargs = { + "native_temperature": 38, + "native_temperature_unit": UnitOfTemperature.CELSIUS, + } + weather_entity = await create_entity(hass, MockWeatherMockForecast, None, **kwargs) hass.config.units = METRIC_SYSTEM await hass.async_block_till_done() - state = hass.states.get(entity0.entity_id) + state = hass.states.get(weather_entity.entity_id) assert state.attributes[ATTR_FORECAST] await hass.async_block_till_done() diff --git a/tests/components/weather/test_websocket_api.py b/tests/components/weather/test_websocket_api.py index 4f5223c6f79..4a401d79849 100644 --- a/tests/components/weather/test_websocket_api.py +++ b/tests/components/weather/test_websocket_api.py @@ -1,11 +1,11 @@ """Test the weather websocket API.""" -from homeassistant.components.weather import WeatherEntityFeature +from homeassistant.components.weather import Forecast, WeatherEntityFeature from homeassistant.components.weather.const import DOMAIN from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component -from . import create_entity +from . import MockWeatherTest, create_entity from tests.typing import WebSocketGenerator @@ -40,16 +40,23 @@ async def test_device_class_units( async def test_subscribe_forecast( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, - enable_custom_integrations: None, + config_flow_fixture: None, ) -> None: """Test multiple forecast.""" - entity0 = await create_entity( - hass, - native_temperature=38, - native_temperature_unit=UnitOfTemperature.CELSIUS, - supported_features=WeatherEntityFeature.FORECAST_DAILY, - ) + class MockWeatherMockForecast(MockWeatherTest): + """Mock weather class.""" + + async def async_forecast_daily(self) -> list[Forecast] | None: + """Return the forecast_daily.""" + return self.forecast_list + + kwargs = { + "native_temperature": 38, + "native_temperature_unit": UnitOfTemperature.CELSIUS, + "supported_features": WeatherEntityFeature.FORECAST_DAILY, + } + weather_entity = await create_entity(hass, MockWeatherMockForecast, None, **kwargs) client = await hass_ws_client(hass) @@ -57,7 +64,7 @@ async def test_subscribe_forecast( { "type": "weather/subscribe_forecast", "forecast_type": "daily", - "entity_id": entity0.entity_id, + "entity_id": weather_entity.entity_id, } ) msg = await client.receive_json() @@ -82,16 +89,16 @@ async def test_subscribe_forecast( ], } - await entity0.async_update_listeners(None) + await weather_entity.async_update_listeners(None) msg = await client.receive_json() assert msg["event"] == forecast - await entity0.async_update_listeners(["daily"]) + await weather_entity.async_update_listeners(["daily"]) msg = await client.receive_json() assert msg["event"] == forecast - entity0.forecast_list = None - await entity0.async_update_listeners(None) + weather_entity.forecast_list = None + await weather_entity.async_update_listeners(None) msg = await client.receive_json() assert msg["event"] == {"type": "daily", "forecast": None} @@ -99,7 +106,6 @@ async def test_subscribe_forecast( async def test_subscribe_forecast_unknown_entity( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, - enable_custom_integrations: None, ) -> None: """Test multiple forecast.""" @@ -125,23 +131,25 @@ async def test_subscribe_forecast_unknown_entity( async def test_subscribe_forecast_unsupported( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, - enable_custom_integrations: None, + config_flow_fixture: None, ) -> None: """Test multiple forecast.""" - entity0 = await create_entity( - hass, - native_temperature=38, - native_temperature_unit=UnitOfTemperature.CELSIUS, - ) + class MockWeatherMock(MockWeatherTest): + """Mock weather class.""" + kwargs = { + "native_temperature": 38, + "native_temperature_unit": UnitOfTemperature.CELSIUS, + } + weather_entity = await create_entity(hass, MockWeatherMock, None, **kwargs) client = await hass_ws_client(hass) await client.send_json_auto_id( { "type": "weather/subscribe_forecast", "forecast_type": "daily", - "entity_id": entity0.entity_id, + "entity_id": weather_entity.entity_id, } ) msg = await client.receive_json() diff --git a/tests/testing_config/custom_components/test/weather.py b/tests/testing_config/custom_components/test/weather.py index 633a5e4c389..5afb6001b8a 100644 --- a/tests/testing_config/custom_components/test/weather.py +++ b/tests/testing_config/custom_components/test/weather.py @@ -23,6 +23,7 @@ from homeassistant.components.weather import ( Forecast, WeatherEntity, ) +from homeassistant.core import HomeAssistant from tests.common import MockEntity @@ -36,7 +37,7 @@ def init(empty=False): async def async_setup_platform( - hass, config, async_add_entities_callback, discovery_info=None + hass: HomeAssistant, config, async_add_entities_callback, discovery_info=None ): """Return mock entities.""" async_add_entities_callback(ENTITIES) @@ -135,79 +136,10 @@ class MockWeather(MockEntity, WeatherEntity): """Return the current condition.""" return self._handle("condition") - -class MockWeatherCompat(MockEntity, WeatherEntity): - """Mock weather class for backwards compatibility check.""" - @property - def temperature(self) -> float | None: - """Return the platform temperature.""" - return self._handle("temperature") - - @property - def temperature_unit(self) -> str | None: - """Return the unit of measurement for temperature.""" - return self._handle("temperature_unit") - - @property - def pressure(self) -> float | None: - """Return the pressure.""" - return self._handle("pressure") - - @property - def pressure_unit(self) -> str | None: - """Return the unit of measurement for pressure.""" - return self._handle("pressure_unit") - - @property - def humidity(self) -> float | None: - """Return the humidity.""" - return self._handle("humidity") - - @property - def wind_speed(self) -> float | None: - """Return the wind speed.""" - return self._handle("wind_speed") - - @property - def wind_speed_unit(self) -> str | None: - """Return the unit of measurement for wind speed.""" - return self._handle("wind_speed_unit") - - @property - def wind_bearing(self) -> float | str | None: - """Return the wind bearing.""" - return self._handle("wind_bearing") - - @property - def ozone(self) -> float | None: - """Return the ozone level.""" - return self._handle("ozone") - - @property - def visibility(self) -> float | None: - """Return the visibility.""" - return self._handle("visibility") - - @property - def visibility_unit(self) -> str | None: - """Return the unit of measurement for visibility.""" - return self._handle("visibility_unit") - - @property - def forecast(self) -> list[Forecast] | None: - """Return the forecast.""" - return self._handle("forecast") - - @property - def precipitation_unit(self) -> str | None: - """Return the unit of measurement for accumulated precipitation.""" - return self._handle("precipitation_unit") - - @property - def condition(self) -> str | None: - """Return the current condition.""" - return self._handle("condition") + def precision(self) -> float: + """Return the precision of the temperature.""" + return self._handle("precision") class MockWeatherMockForecast(MockWeather): diff --git a/tests/testing_config/custom_components/test_weather/__init__.py b/tests/testing_config/custom_components/test_weather/__init__.py deleted file mode 100644 index ddec081ed8b..00000000000 --- a/tests/testing_config/custom_components/test_weather/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""An integration with Weather platform.""" diff --git a/tests/testing_config/custom_components/test_weather/manifest.json b/tests/testing_config/custom_components/test_weather/manifest.json deleted file mode 100644 index d1238659b41..00000000000 --- a/tests/testing_config/custom_components/test_weather/manifest.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "domain": "test_weather", - "name": "Test Weather", - "documentation": "http://example.com", - "requirements": [], - "dependencies": [], - "codeowners": [], - "version": "1.2.3" -} diff --git a/tests/testing_config/custom_components/test_weather/weather.py b/tests/testing_config/custom_components/test_weather/weather.py deleted file mode 100644 index 68d9ccab712..00000000000 --- a/tests/testing_config/custom_components/test_weather/weather.py +++ /dev/null @@ -1,210 +0,0 @@ -"""Provide a mock weather platform. - -Call init before using it in your tests to ensure clean test data. -""" -from __future__ import annotations - -from typing import Any - -from homeassistant.components.weather import ( - ATTR_FORECAST_CLOUD_COVERAGE, - ATTR_FORECAST_HUMIDITY, - ATTR_FORECAST_IS_DAYTIME, - ATTR_FORECAST_NATIVE_APPARENT_TEMP, - ATTR_FORECAST_NATIVE_DEW_POINT, - ATTR_FORECAST_NATIVE_PRECIPITATION, - ATTR_FORECAST_NATIVE_PRESSURE, - ATTR_FORECAST_NATIVE_TEMP, - ATTR_FORECAST_NATIVE_TEMP_LOW, - ATTR_FORECAST_NATIVE_WIND_GUST_SPEED, - ATTR_FORECAST_NATIVE_WIND_SPEED, - ATTR_FORECAST_UV_INDEX, - ATTR_FORECAST_WIND_BEARING, - Forecast, - WeatherEntity, -) - -from tests.common import MockEntity - -ENTITIES = [] - - -def init(empty=False): - """Initialize the platform with entities.""" - global ENTITIES - ENTITIES = [] if empty else [MockWeatherMockForecast()] - - -async def async_setup_platform( - hass, config, async_add_entities_callback, discovery_info=None -): - """Return mock entities.""" - async_add_entities_callback(ENTITIES) - - -class MockWeatherMockForecast(MockEntity, WeatherEntity): - """Mock weather class.""" - - def __init__(self, **values: Any) -> None: - """Initialize.""" - super().__init__(**values) - self.forecast_list: list[Forecast] | None = [ - { - ATTR_FORECAST_NATIVE_TEMP: self.native_temperature, - ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature, - ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature, - ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point, - ATTR_FORECAST_CLOUD_COVERAGE: self.cloud_coverage, - ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure, - ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: self.native_wind_gust_speed, - ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed, - ATTR_FORECAST_WIND_BEARING: self.wind_bearing, - ATTR_FORECAST_UV_INDEX: self.uv_index, - ATTR_FORECAST_NATIVE_PRECIPITATION: self._values.get( - "native_precipitation" - ), - ATTR_FORECAST_HUMIDITY: self.humidity, - } - ] - - @property - def forecast(self) -> list[Forecast] | None: - """Return the forecast.""" - return self.forecast_list - - async def async_forecast_daily(self) -> list[Forecast] | None: - """Return the forecast_daily.""" - return self.forecast_list - - async def async_forecast_twice_daily(self) -> list[Forecast] | None: - """Return the forecast_twice_daily.""" - return [ - { - ATTR_FORECAST_NATIVE_TEMP: self.native_temperature, - ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature, - ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature, - ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point, - ATTR_FORECAST_CLOUD_COVERAGE: self.cloud_coverage, - ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure, - ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: self.native_wind_gust_speed, - ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed, - ATTR_FORECAST_WIND_BEARING: self.wind_bearing, - ATTR_FORECAST_UV_INDEX: self.uv_index, - ATTR_FORECAST_NATIVE_PRECIPITATION: self._values.get( - "native_precipitation" - ), - ATTR_FORECAST_HUMIDITY: self.humidity, - ATTR_FORECAST_IS_DAYTIME: self._values.get("is_daytime"), - } - ] - - async def async_forecast_hourly(self) -> list[Forecast] | None: - """Return the forecast_hourly.""" - return [ - { - ATTR_FORECAST_NATIVE_TEMP: self.native_temperature, - ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature, - ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature, - ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point, - ATTR_FORECAST_CLOUD_COVERAGE: self.cloud_coverage, - ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure, - ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: self.native_wind_gust_speed, - ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed, - ATTR_FORECAST_WIND_BEARING: self.wind_bearing, - ATTR_FORECAST_UV_INDEX: self.uv_index, - ATTR_FORECAST_NATIVE_PRECIPITATION: self._values.get( - "native_precipitation" - ), - ATTR_FORECAST_HUMIDITY: self.humidity, - } - ] - - @property - def native_temperature(self) -> float | None: - """Return the platform temperature.""" - return self._handle("native_temperature") - - @property - def native_apparent_temperature(self) -> float | None: - """Return the platform apparent temperature.""" - return self._handle("native_apparent_temperature") - - @property - def native_dew_point(self) -> float | None: - """Return the platform dewpoint temperature.""" - return self._handle("native_dew_point") - - @property - def native_temperature_unit(self) -> str | None: - """Return the unit of measurement for temperature.""" - return self._handle("native_temperature_unit") - - @property - def native_pressure(self) -> float | None: - """Return the pressure.""" - return self._handle("native_pressure") - - @property - def native_pressure_unit(self) -> str | None: - """Return the unit of measurement for pressure.""" - return self._handle("native_pressure_unit") - - @property - def humidity(self) -> float | None: - """Return the humidity.""" - return self._handle("humidity") - - @property - def native_wind_gust_speed(self) -> float | None: - """Return the wind speed.""" - return self._handle("native_wind_gust_speed") - - @property - def native_wind_speed(self) -> float | None: - """Return the wind speed.""" - return self._handle("native_wind_speed") - - @property - def native_wind_speed_unit(self) -> str | None: - """Return the unit of measurement for wind speed.""" - return self._handle("native_wind_speed_unit") - - @property - def wind_bearing(self) -> float | str | None: - """Return the wind bearing.""" - return self._handle("wind_bearing") - - @property - def ozone(self) -> float | None: - """Return the ozone level.""" - return self._handle("ozone") - - @property - def cloud_coverage(self) -> float | None: - """Return the cloud coverage in %.""" - return self._handle("cloud_coverage") - - @property - def uv_index(self) -> float | None: - """Return the UV index.""" - return self._handle("uv_index") - - @property - def native_visibility(self) -> float | None: - """Return the visibility.""" - return self._handle("native_visibility") - - @property - def native_visibility_unit(self) -> str | None: - """Return the unit of measurement for visibility.""" - return self._handle("native_visibility_unit") - - @property - def native_precipitation_unit(self) -> str | None: - """Return the native unit of measurement for accumulated precipitation.""" - return self._handle("native_precipitation_unit") - - @property - def condition(self) -> str | None: - """Return the current condition.""" - return self._handle("condition")