"""Validate actual HA form schemas, options and entry migration.""" from homeassistant.config_entries import SOURCE_USER from homeassistant.data_entry_flow import FlowResultType from pytest_homeassistant_custom_component.common import MockConfigEntry from custom_components.heating_mpc.const import DOMAIN from custom_components.heating_mpc.weather_sources import sources_for async def test_config_flow(hass, inputs): result = await hass.config_entries.flow.async_init(DOMAIN, context={"source": SOURCE_USER}) assert result["type"] is FlowResultType.FORM main = {"climate_entity": "climate.reference", "heater_entity": "switch.boiler", "room_entities": ["sensor.room"]} validated = result["data_schema"](main) assert validated["room_max_age_minutes"] == 30 assert validated["weather_max_age_minutes"] == 120 assert validated["room_stale_use_last_value"] is False result = await hass.config_entries.flow.async_configure(result["flow_id"], validated) assert result["step_id"] == "weather" result = await hass.config_entries.flow.async_configure( result["flow_id"], result["data_schema"]({"outside_temperature_sources": ["sensor.outside"]})) assert result["step_id"] == "weather_extra" result = await hass.config_entries.flow.async_configure(result["flow_id"], result["data_schema"]({})) assert result["step_id"] == "weights" result = await hass.config_entries.flow.async_configure(result["flow_id"], {"weight__sensor.room": 2}) assert result["type"] is FlowResultType.CREATE_ENTRY assert result["data"]["weights"] == {"sensor.room": 2} await hass.async_block_till_done() async def test_options_flow_keeps_settings(hass, entry, inputs): entry.add_to_hass(hass) assert 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) main = result["data_schema"]({"climate_entity": "climate.reference", "heater_entity": "switch.boiler", "room_entities": ["sensor.room"], "room_max_age_minutes": 45, "room_stale_use_last_value": True}) result = await hass.config_entries.options.async_configure(result["flow_id"], main) result = await hass.config_entries.options.async_configure( result["flow_id"], result["data_schema"]({"outside_temperature_sources": ["sensor.outside"]})) result = await hass.config_entries.options.async_configure(result["flow_id"], result["data_schema"]({})) result = await hass.config_entries.options.async_configure(result["flow_id"], {"weight__sensor.room": 3}) assert result["type"] is FlowResultType.CREATE_ENTRY await hass.async_block_till_done() assert entry.options["room_max_age_minutes"] == 45 coordinator = hass.data[DOMAIN][entry.entry_id] assert coordinator.config["room_max_age_minutes"] == 45 assert coordinator.config["room_stale_use_last_value"] is True # The next options form shows the saved choice. result = await hass.config_entries.options.async_init(entry.entry_id) assert result["data_schema"]({"climate_entity": "climate.reference", "heater_entity": "switch.boiler", "room_entities": ["sensor.room"]})["room_stale_use_last_value"] is True hass.config_entries.options.async_abort(result["flow_id"]) async def test_v1_entry_migrates_on_setup(hass, inputs): entry = MockConfigEntry(domain=DOMAIN, version=1, data={ "climate_entity": "climate.reference", "heater_entity": "switch.boiler", "room_entities": ["sensor.room"], "outside_entity": "sensor.outside"}) entry.add_to_hass(hass) assert await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() assert entry.version == 2 assert entry.data["outside_temperature_sources"] == ["sensor.outside"] assert "outside_entity" not in entry.data async def test_options_flow_clears_optional_weather_sources(hass, inputs): """Swapping providers in the UI must allow removing an optional source list.""" entry = MockConfigEntry(domain=DOMAIN, version=2, unique_id="home_heating", data={ "climate_entity": "climate.reference", "heater_entity": "switch.boiler", "room_entities": ["sensor.room"], "outside_temperature_sources": ["sensor.outside"], "outside_wind_sources": ["sensor.wind"], "outside_pressure_sources": ["sensor.pressure"], "weights": {"sensor.room": 1.0}}) entry.add_to_hass(hass) assert await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() flow = hass.config_entries.options result = await flow.async_init(entry.entry_id) result = await flow.async_configure(result["flow_id"], result["data_schema"]({ "climate_entity": "climate.reference", "heater_entity": "switch.boiler", "room_entities": ["sensor.room"]})) markers = {str(key): key for key in result["data_schema"].schema} assert markers["outside_wind_sources"].description == {"suggested_value": ["sensor.wind"]} # The user removes the wind provider; a cleared field may be omitted on submit. result = await flow.async_configure(result["flow_id"], result["data_schema"]( {"outside_temperature_sources": ["sensor.outside"]})) result = await flow.async_configure(result["flow_id"], result["data_schema"]( {"outside_pressure_sources": ["sensor.pressure"]})) result = await flow.async_configure(result["flow_id"], {"weight__sensor.room": 1}) assert result["type"] is FlowResultType.CREATE_ENTRY await hass.async_block_till_done() assert entry.options["outside_wind_sources"] == [] assert entry.options["outside_pressure_sources"] == ["sensor.pressure"] config = hass.data[DOMAIN][entry.entry_id].config assert sources_for(config, "wind") == [] assert sources_for(config, "pressure") == ["sensor.pressure"]