|
1 | 1 | """Test the Derivative config flow.""" |
2 | 2 |
|
| 3 | +from datetime import timedelta |
3 | 4 | from unittest.mock import patch |
4 | 5 |
|
| 6 | +from freezegun import freeze_time |
5 | 7 | import pytest |
6 | 8 |
|
7 | 9 | from homeassistant import config_entries |
8 | 10 | from homeassistant.components.derivative.const import DOMAIN |
| 11 | +from homeassistant.const import STATE_UNAVAILABLE |
9 | 12 | from homeassistant.core import HomeAssistant |
10 | 13 | from homeassistant.data_entry_flow import FlowResultType |
11 | 14 | from homeassistant.helpers import selector |
| 15 | +from homeassistant.util import dt as dt_util |
12 | 16 |
|
13 | 17 | from tests.common import MockConfigEntry, get_schema_suggested_value |
14 | 18 |
|
@@ -154,3 +158,86 @@ async def test_options( |
154 | 158 | await hass.async_block_till_done() |
155 | 159 | state = hass.states.get(f"{platform}.my_derivative") |
156 | 160 | assert state.attributes["unit_of_measurement"] == "cat/h" |
| 161 | + |
| 162 | + |
| 163 | +async def test_update_unit(hass: HomeAssistant) -> None: |
| 164 | + """Test behavior of changing the unit_time option.""" |
| 165 | + # Setup the config entry |
| 166 | + source_id = "sensor.source" |
| 167 | + config_entry = MockConfigEntry( |
| 168 | + data={}, |
| 169 | + domain=DOMAIN, |
| 170 | + options={ |
| 171 | + "name": "My derivative", |
| 172 | + "round": 1.0, |
| 173 | + "source": source_id, |
| 174 | + "unit_time": "min", |
| 175 | + "time_window": {"seconds": 0.0}, |
| 176 | + }, |
| 177 | + title="My derivative", |
| 178 | + ) |
| 179 | + derivative_id = "sensor.my_derivative" |
| 180 | + config_entry.add_to_hass(hass) |
| 181 | + assert await hass.config_entries.async_setup(config_entry.entry_id) |
| 182 | + await hass.async_block_till_done() |
| 183 | + |
| 184 | + state = hass.states.get(derivative_id) |
| 185 | + assert state.state == STATE_UNAVAILABLE |
| 186 | + assert state.attributes.get("unit_of_measurement") is None |
| 187 | + |
| 188 | + time = dt_util.utcnow() |
| 189 | + with freeze_time(time) as freezer: |
| 190 | + # First state update of the source. |
| 191 | + # Derivative does not learn the unit yet. |
| 192 | + hass.states.async_set(source_id, 5, {"unit_of_measurement": "dogs"}) |
| 193 | + await hass.async_block_till_done() |
| 194 | + state = hass.states.get(derivative_id) |
| 195 | + assert state.state == "0.0" |
| 196 | + assert state.attributes.get("unit_of_measurement") is None |
| 197 | + |
| 198 | + # Second state update of the source. |
| 199 | + time += timedelta(minutes=1) |
| 200 | + freezer.move_to(time) |
| 201 | + hass.states.async_set(source_id, "7", {"unit_of_measurement": "dogs"}) |
| 202 | + await hass.async_block_till_done() |
| 203 | + state = hass.states.get(derivative_id) |
| 204 | + assert state.state == "2.0" |
| 205 | + assert state.attributes.get("unit_of_measurement") == "dogs/min" |
| 206 | + |
| 207 | + # Update the unit_time from minutes to seconds. |
| 208 | + result = await hass.config_entries.options.async_init(config_entry.entry_id) |
| 209 | + result = await hass.config_entries.options.async_configure( |
| 210 | + result["flow_id"], |
| 211 | + user_input={ |
| 212 | + "source": source_id, |
| 213 | + "round": 1.0, |
| 214 | + "unit_time": "s", |
| 215 | + "time_window": {"seconds": 0.0}, |
| 216 | + }, |
| 217 | + ) |
| 218 | + await hass.async_block_till_done() |
| 219 | + |
| 220 | + # Check the state after reconfigure. Neither unit or state has changed. |
| 221 | + state = hass.states.get(derivative_id) |
| 222 | + assert state.state == "2.0" |
| 223 | + assert state.attributes.get("unit_of_measurement") == "dogs/min" |
| 224 | + |
| 225 | + # Third state update of the source. |
| 226 | + time += timedelta(seconds=1) |
| 227 | + freezer.move_to(time) |
| 228 | + hass.states.async_set(source_id, "10", {"unit_of_measurement": "dogs"}) |
| 229 | + await hass.async_block_till_done() |
| 230 | + state = hass.states.get(derivative_id) |
| 231 | + assert state.state == "3.0" |
| 232 | + # While the state is correctly reporting a state of 3 dogs per second, it incorrectly keeps |
| 233 | + # the unit as dogs/min |
| 234 | + assert state.attributes.get("unit_of_measurement") == "dogs/min" |
| 235 | + |
| 236 | + # Fourth state update of the source. |
| 237 | + time += timedelta(seconds=1) |
| 238 | + freezer.move_to(time) |
| 239 | + hass.states.async_set(source_id, "20", {"unit_of_measurement": "dogs"}) |
| 240 | + await hass.async_block_till_done() |
| 241 | + state = hass.states.get(derivative_id) |
| 242 | + assert state.state == "10.0" |
| 243 | + assert state.attributes.get("unit_of_measurement") == "dogs/min" |
0 commit comments