From 77feaecbfa9e4f22fa4d5753690413a2805545b1 Mon Sep 17 00:00:00 2001 From: Eugenio Panadero Date: Thu, 12 Jan 2023 01:07:11 +0100 Subject: [PATCH] Remove unreachable config entry migration in pvpc hourly pricing (#85700) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🔥 Remove old config entry migration logic introduced for a breaking change in 2021-06, now unreachable after completely disabling the YAML config for the integration * ✅ Remove test for old config entry migration logic and adjust existent one for config-flow to do not lose coverage --- .../pvpc_hourly_pricing/__init__.py | 54 +--------- .../pvpc_hourly_pricing/test_config_flow.py | 16 ++- .../pvpc_hourly_pricing/test_sensor.py | 98 ------------------- 3 files changed, 14 insertions(+), 154 deletions(-) delete mode 100644 tests/components/pvpc_hourly_pricing/test_sensor.py diff --git a/homeassistant/components/pvpc_hourly_pricing/__init__.py b/homeassistant/components/pvpc_hourly_pricing/__init__.py index d83c0e82521..a482b175ab0 100644 --- a/homeassistant/components/pvpc_hourly_pricing/__init__.py +++ b/homeassistant/components/pvpc_hourly_pricing/__init__.py @@ -7,14 +7,9 @@ import voluptuous as vol from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession -from homeassistant.helpers.entity_registry import ( - EntityRegistry, - async_get, - async_migrate_entries, -) from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util import dt as dt_util @@ -44,53 +39,6 @@ CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False) async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up pvpc hourly pricing from a config entry.""" - if len(entry.data) == 2: - defaults = { - ATTR_TARIFF: _DEFAULT_TARIFF, - ATTR_POWER: DEFAULT_POWER_KW, - ATTR_POWER_P3: DEFAULT_POWER_KW, - } - data = {**entry.data, **defaults} - hass.config_entries.async_update_entry( - entry, unique_id=_DEFAULT_TARIFF, data=data, options=defaults - ) - - @callback - def update_unique_id(reg_entry): - """Change unique id for sensor entity, pointing to new tariff.""" - return {"new_unique_id": _DEFAULT_TARIFF} - - try: - await async_migrate_entries(hass, entry.entry_id, update_unique_id) - _LOGGER.warning( - ( - "Migrating PVPC sensor from old tariff '%s' to new '%s'. " - "Configure the integration to set your contracted power, " - "and select prices for Ceuta/Melilla, " - "if that is your case" - ), - entry.data[ATTR_TARIFF], - _DEFAULT_TARIFF, - ) - except ValueError: - # there were multiple sensors (with different old tariffs, up to 3), - # so we leave just one and remove the others - ent_reg: EntityRegistry = async_get(hass) - for entity_id, reg_entry in ent_reg.entities.items(): - if reg_entry.config_entry_id == entry.entry_id: - ent_reg.async_remove(entity_id) - _LOGGER.warning( - ( - "Old PVPC Sensor %s is removed " - "(another one already exists, using the same tariff)" - ), - entity_id, - ) - break - - await hass.config_entries.async_remove(entry.entry_id) - return False - coordinator = ElecPricesDataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() diff --git a/tests/components/pvpc_hourly_pricing/test_config_flow.py b/tests/components/pvpc_hourly_pricing/test_config_flow.py index b0ee2c9585a..94d9898aa58 100644 --- a/tests/components/pvpc_hourly_pricing/test_config_flow.py +++ b/tests/components/pvpc_hourly_pricing/test_config_flow.py @@ -1,5 +1,5 @@ """Tests for the pvpc_hourly_pricing config_flow.""" -from datetime import datetime +from datetime import datetime, timedelta from freezegun import freeze_time @@ -16,7 +16,7 @@ from homeassistant.helpers import entity_registry as er from .conftest import check_valid_state -from tests.common import date_util +from tests.common import async_fire_time_changed, date_util from tests.test_util.aiohttp import AiohttpClientMocker _MOCK_TIME_VALID_RESPONSES = datetime(2023, 1, 6, 12, 0, tzinfo=date_util.UTC) @@ -40,7 +40,7 @@ async def test_config_flow(hass, pvpc_aioclient_mock: AiohttpClientMocker): ATTR_POWER_P3: 5.75, } - with freeze_time(_MOCK_TIME_VALID_RESPONSES): + with freeze_time(_MOCK_TIME_VALID_RESPONSES) as mock_time: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) @@ -111,3 +111,13 @@ async def test_config_flow(hass, pvpc_aioclient_mock: AiohttpClientMocker): assert state.attributes["period"] == "P3" assert state.attributes["next_period"] == "P2" assert state.attributes["available_power"] == 4600 + + # check update failed + ts_future = _MOCK_TIME_VALID_RESPONSES + timedelta(days=1) + mock_time.move_to(ts_future) + async_fire_time_changed(hass, ts_future) + await hass.async_block_till_done() + state = hass.states.get("sensor.test") + check_valid_state(state, tariff=TARIFFS[0], value="unavailable") + assert "period" not in state.attributes + assert pvpc_aioclient_mock.call_count == 4 diff --git a/tests/components/pvpc_hourly_pricing/test_sensor.py b/tests/components/pvpc_hourly_pricing/test_sensor.py deleted file mode 100644 index eb5b35b38d4..00000000000 --- a/tests/components/pvpc_hourly_pricing/test_sensor.py +++ /dev/null @@ -1,98 +0,0 @@ -"""Tests for the pvpc_hourly_pricing sensor component.""" -from datetime import datetime, timedelta -import logging - -from freezegun import freeze_time - -from homeassistant.components.pvpc_hourly_pricing import ( - ATTR_POWER, - ATTR_POWER_P3, - ATTR_TARIFF, - DOMAIN, - TARIFFS, -) -from homeassistant.const import CONF_NAME - -from .conftest import check_valid_state - -from tests.common import ( - MockConfigEntry, - async_fire_time_changed, - date_util, - mock_registry, -) -from tests.test_util.aiohttp import AiohttpClientMocker - - -async def test_multi_sensor_migration( - hass, caplog, pvpc_aioclient_mock: AiohttpClientMocker -): - """Test tariff migration when there are >1 old sensors.""" - entity_reg = mock_registry(hass) - hass.config.set_time_zone("Europe/Madrid") - uid_1 = "discrimination" - uid_2 = "normal" - old_conf_1 = {CONF_NAME: "test_pvpc_1", ATTR_TARIFF: uid_1} - old_conf_2 = {CONF_NAME: "test_pvpc_2", ATTR_TARIFF: uid_2} - - config_entry_1 = MockConfigEntry(domain=DOMAIN, data=old_conf_1, unique_id=uid_1) - config_entry_1.add_to_hass(hass) - entity1 = entity_reg.async_get_or_create( - domain="sensor", - platform=DOMAIN, - unique_id=uid_1, - config_entry=config_entry_1, - suggested_object_id="test_pvpc_1", - ) - - config_entry_2 = MockConfigEntry(domain=DOMAIN, data=old_conf_2, unique_id=uid_2) - config_entry_2.add_to_hass(hass) - entity2 = entity_reg.async_get_or_create( - domain="sensor", - platform=DOMAIN, - unique_id=uid_2, - config_entry=config_entry_2, - suggested_object_id="test_pvpc_2", - ) - - assert len(hass.config_entries.async_entries(DOMAIN)) == 2 - assert len(entity_reg.entities) == 2 - - mock_data = {"return_time": datetime(2023, 1, 6, 21, tzinfo=date_util.UTC)} - - caplog.clear() - with caplog.at_level(logging.WARNING): - with freeze_time(mock_data["return_time"]): - assert await hass.config_entries.async_setup(config_entry_1.entry_id) - assert any("Migrating PVPC" in message for message in caplog.messages) - assert any( - "Old PVPC Sensor sensor.test_pvpc_2 is removed" in message - for message in caplog.messages - ) - - # check migration with removal of extra sensors - assert len(entity_reg.entities) == 1 - assert entity1.entity_id in entity_reg.entities - assert entity2.entity_id not in entity_reg.entities - - current_entries = hass.config_entries.async_entries(DOMAIN) - assert len(current_entries) == 1 - migrated_entry = current_entries[0] - assert migrated_entry.version == 1 - assert migrated_entry.data[ATTR_POWER] == migrated_entry.data[ATTR_POWER_P3] - assert migrated_entry.data[ATTR_TARIFF] == TARIFFS[0] - - await hass.async_block_till_done() - assert pvpc_aioclient_mock.call_count == 2 - - # check state and availability - state = hass.states.get("sensor.test_pvpc_1") - check_valid_state(state, tariff=TARIFFS[0], value=0.13937) - - with freeze_time(mock_data["return_time"] + timedelta(hours=2)): - async_fire_time_changed(hass, mock_data["return_time"]) - await list(hass.data[DOMAIN].values())[0].async_refresh() - await hass.async_block_till_done() - state = hass.states.get("sensor.test_pvpc_1") - check_valid_state(state, tariff=TARIFFS[0], value="unavailable") - assert pvpc_aioclient_mock.call_count == 3