Convert history tests to use async API (#116447)

* Convert history tests to use async API

* Add new fixture to help patch recorder

* Modify

* Modify

* Update tests/conftest.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Rename fixture

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Erik Montnemery 2024-05-03 08:14:46 +02:00 committed by GitHub
parent 897794f53b
commit 27fcf72275
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 209 additions and 163 deletions

View file

@ -3,15 +3,24 @@
import pytest import pytest
from homeassistant.components import history from homeassistant.components import history
from homeassistant.components.recorder import Recorder
from homeassistant.const import CONF_DOMAINS, CONF_ENTITIES, CONF_EXCLUDE, CONF_INCLUDE from homeassistant.const import CONF_DOMAINS, CONF_ENTITIES, CONF_EXCLUDE, CONF_INCLUDE
from homeassistant.setup import setup_component from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from tests.typing import RecorderInstanceGenerator
@pytest.fixture @pytest.fixture
def hass_history(hass_recorder): async def mock_recorder_before_hass(
"""Home Assistant fixture with history.""" async_setup_recorder_instance: RecorderInstanceGenerator,
hass = hass_recorder() ) -> None:
"""Set up recorder."""
@pytest.fixture
async def hass_history(hass: HomeAssistant, recorder_mock: Recorder) -> None:
"""Home Assistant fixture with history."""
config = history.CONFIG_SCHEMA( config = history.CONFIG_SCHEMA(
{ {
history.DOMAIN: { history.DOMAIN: {
@ -26,6 +35,4 @@ def hass_history(hass_recorder):
} }
} }
) )
assert setup_component(hass, history.DOMAIN, config) assert await async_setup_component(hass, history.DOMAIN, config)
return hass

View file

@ -24,7 +24,6 @@ from tests.components.recorder.common import (
assert_multiple_states_equal_without_context_and_last_changed, assert_multiple_states_equal_without_context_and_last_changed,
assert_states_equal_without_context, assert_states_equal_without_context,
async_wait_recording_done, async_wait_recording_done,
wait_recording_done,
) )
from tests.typing import ClientSessionGenerator from tests.typing import ClientSessionGenerator
@ -39,25 +38,26 @@ def listeners_without_writes(listeners: dict[str, int]) -> dict[str, int]:
@pytest.mark.usefixtures("hass_history") @pytest.mark.usefixtures("hass_history")
def test_setup() -> None: async def test_setup() -> None:
"""Test setup method of history.""" """Test setup method of history."""
# Verification occurs in the fixture # Verification occurs in the fixture
def test_get_significant_states(hass_history) -> None: async def test_get_significant_states(hass: HomeAssistant, hass_history) -> None:
"""Test that only significant states are returned. """Test that only significant states are returned.
We should get back every thermostat change that We should get back every thermostat change that
includes an attribute change, but only the state updates for includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned). media player (attribute changes are not significant and not returned).
""" """
hass = hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
hist = get_significant_states(hass, zero, four, entity_ids=list(states)) hist = get_significant_states(hass, zero, four, entity_ids=list(states))
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_minimal_response(hass_history) -> None: async def test_get_significant_states_minimal_response(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned. """Test that only significant states are returned.
When minimal responses is set only the first and When minimal responses is set only the first and
@ -67,8 +67,7 @@ def test_get_significant_states_minimal_response(hass_history) -> None:
includes an attribute change, but only the state updates for includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned). media player (attribute changes are not significant and not returned).
""" """
hass = hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
hist = get_significant_states( hist = get_significant_states(
hass, zero, four, minimal_response=True, entity_ids=list(states) hass, zero, four, minimal_response=True, entity_ids=list(states)
) )
@ -122,15 +121,16 @@ def test_get_significant_states_minimal_response(hass_history) -> None:
) )
def test_get_significant_states_with_initial(hass_history) -> None: async def test_get_significant_states_with_initial(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned. """Test that only significant states are returned.
We should get back every thermostat change that We should get back every thermostat change that
includes an attribute change, but only the state updates for includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned). media player (attribute changes are not significant and not returned).
""" """
hass = hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
one_and_half = zero + timedelta(seconds=1.5) one_and_half = zero + timedelta(seconds=1.5)
for entity_id in states: for entity_id in states:
if entity_id == "media_player.test": if entity_id == "media_player.test":
@ -149,15 +149,16 @@ def test_get_significant_states_with_initial(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_without_initial(hass_history) -> None: async def test_get_significant_states_without_initial(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned. """Test that only significant states are returned.
We should get back every thermostat change that We should get back every thermostat change that
includes an attribute change, but only the state updates for includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned). media player (attribute changes are not significant and not returned).
""" """
hass = hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
one = zero + timedelta(seconds=1) one = zero + timedelta(seconds=1)
one_with_microsecond = zero + timedelta(seconds=1, microseconds=1) one_with_microsecond = zero + timedelta(seconds=1, microseconds=1)
one_and_half = zero + timedelta(seconds=1.5) one_and_half = zero + timedelta(seconds=1.5)
@ -179,10 +180,11 @@ def test_get_significant_states_without_initial(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_entity_id(hass_history) -> None: async def test_get_significant_states_entity_id(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned for one entity.""" """Test that only significant states are returned for one entity."""
hass = hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
del states["media_player.test2"] del states["media_player.test2"]
del states["media_player.test3"] del states["media_player.test3"]
del states["thermostat.test"] del states["thermostat.test"]
@ -193,10 +195,11 @@ def test_get_significant_states_entity_id(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_multiple_entity_ids(hass_history) -> None: async def test_get_significant_states_multiple_entity_ids(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned for one entity.""" """Test that only significant states are returned for one entity."""
hass = hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
del states["media_player.test2"] del states["media_player.test2"]
del states["media_player.test3"] del states["media_player.test3"]
del states["thermostat.test2"] del states["thermostat.test2"]
@ -211,14 +214,15 @@ def test_get_significant_states_multiple_entity_ids(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_are_ordered(hass_history) -> None: async def test_get_significant_states_are_ordered(
hass: HomeAssistant, hass_history
) -> None:
"""Test order of results from get_significant_states. """Test order of results from get_significant_states.
When entity ids are given, the results should be returned with the data When entity ids are given, the results should be returned with the data
in the same order. in the same order.
""" """
hass = hass_history zero, four, _states = await async_record_states(hass)
zero, four, _states = record_states(hass)
entity_ids = ["media_player.test", "media_player.test2"] entity_ids = ["media_player.test", "media_player.test2"]
hist = get_significant_states(hass, zero, four, entity_ids) hist = get_significant_states(hass, zero, four, entity_ids)
assert list(hist.keys()) == entity_ids assert list(hist.keys()) == entity_ids
@ -227,15 +231,14 @@ def test_get_significant_states_are_ordered(hass_history) -> None:
assert list(hist.keys()) == entity_ids assert list(hist.keys()) == entity_ids
def test_get_significant_states_only(hass_history) -> None: async def test_get_significant_states_only(hass: HomeAssistant, hass_history) -> None:
"""Test significant states when significant_states_only is set.""" """Test significant states when significant_states_only is set."""
hass = hass_history
entity_id = "sensor.test" entity_id = "sensor.test"
def set_state(state, **kwargs): async def set_state(state, **kwargs):
"""Set the state.""" """Set the state."""
hass.states.set(entity_id, state, **kwargs) hass.states.async_set(entity_id, state, **kwargs)
wait_recording_done(hass) await async_wait_recording_done(hass)
return hass.states.get(entity_id) return hass.states.get(entity_id)
start = dt_util.utcnow() - timedelta(minutes=4) start = dt_util.utcnow() - timedelta(minutes=4)
@ -243,19 +246,19 @@ def test_get_significant_states_only(hass_history) -> None:
states = [] states = []
with freeze_time(start) as freezer: with freeze_time(start) as freezer:
set_state("123", attributes={"attribute": 10.64}) await set_state("123", attributes={"attribute": 10.64})
freezer.move_to(points[0]) freezer.move_to(points[0])
# Attributes are different, state not # Attributes are different, state not
states.append(set_state("123", attributes={"attribute": 21.42})) states.append(await set_state("123", attributes={"attribute": 21.42}))
freezer.move_to(points[1]) freezer.move_to(points[1])
# state is different, attributes not # state is different, attributes not
states.append(set_state("32", attributes={"attribute": 21.42})) states.append(await set_state("32", attributes={"attribute": 21.42}))
freezer.move_to(points[2]) freezer.move_to(points[2])
# everything is different # everything is different
states.append(set_state("412", attributes={"attribute": 54.23})) states.append(await set_state("412", attributes={"attribute": 54.23}))
hist = get_significant_states( hist = get_significant_states(
hass, hass,
@ -288,13 +291,13 @@ def test_get_significant_states_only(hass_history) -> None:
) )
def check_significant_states(hass, zero, four, states, config): async def check_significant_states(hass, zero, four, states, config):
"""Check if significant states are retrieved.""" """Check if significant states are retrieved."""
hist = get_significant_states(hass, zero, four) hist = get_significant_states(hass, zero, four)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def record_states(hass): async def async_record_states(hass):
"""Record some test states. """Record some test states.
We inject a bunch of state updates from media player, zone and We inject a bunch of state updates from media player, zone and
@ -308,10 +311,10 @@ def record_states(hass):
zone = "zone.home" zone = "zone.home"
script_c = "script.can_cancel_this_one" script_c = "script.can_cancel_this_one"
def set_state(entity_id, state, **kwargs): async def set_state(entity_id, state, **kwargs):
"""Set the state.""" """Set the state."""
hass.states.set(entity_id, state, **kwargs) hass.states.async_set(entity_id, state, **kwargs)
wait_recording_done(hass) await async_wait_recording_done(hass)
return hass.states.get(entity_id) return hass.states.get(entity_id)
zero = dt_util.utcnow() zero = dt_util.utcnow()
@ -323,55 +326,63 @@ def record_states(hass):
states = {therm: [], therm2: [], mp: [], mp2: [], mp3: [], script_c: []} states = {therm: [], therm2: [], mp: [], mp2: [], mp3: [], script_c: []}
with freeze_time(one) as freezer: with freeze_time(one) as freezer:
states[mp].append( states[mp].append(
set_state(mp, "idle", attributes={"media_title": str(sentinel.mt1)}) await set_state(mp, "idle", attributes={"media_title": str(sentinel.mt1)})
) )
states[mp2].append( states[mp2].append(
set_state(mp2, "YouTube", attributes={"media_title": str(sentinel.mt2)}) await set_state(
mp2, "YouTube", attributes={"media_title": str(sentinel.mt2)}
)
) )
states[mp3].append( states[mp3].append(
set_state(mp3, "idle", attributes={"media_title": str(sentinel.mt1)}) await set_state(mp3, "idle", attributes={"media_title": str(sentinel.mt1)})
) )
states[therm].append( states[therm].append(
set_state(therm, 20, attributes={"current_temperature": 19.5}) await set_state(therm, 20, attributes={"current_temperature": 19.5})
) )
freezer.move_to(one + timedelta(microseconds=1)) freezer.move_to(one + timedelta(microseconds=1))
states[mp].append( states[mp].append(
set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt2)}) await set_state(
mp, "YouTube", attributes={"media_title": str(sentinel.mt2)}
)
) )
freezer.move_to(two) freezer.move_to(two)
# This state will be skipped only different in time # This state will be skipped only different in time
set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt3)}) await set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt3)})
# This state will be skipped because domain is excluded # This state will be skipped because domain is excluded
set_state(zone, "zoning") await set_state(zone, "zoning")
states[script_c].append( states[script_c].append(
set_state(script_c, "off", attributes={"can_cancel": True}) await set_state(script_c, "off", attributes={"can_cancel": True})
) )
states[therm].append( states[therm].append(
set_state(therm, 21, attributes={"current_temperature": 19.8}) await set_state(therm, 21, attributes={"current_temperature": 19.8})
) )
states[therm2].append( states[therm2].append(
set_state(therm2, 20, attributes={"current_temperature": 19}) await set_state(therm2, 20, attributes={"current_temperature": 19})
) )
freezer.move_to(three) freezer.move_to(three)
states[mp].append( states[mp].append(
set_state(mp, "Netflix", attributes={"media_title": str(sentinel.mt4)}) await set_state(
mp, "Netflix", attributes={"media_title": str(sentinel.mt4)}
)
) )
states[mp3].append( states[mp3].append(
set_state(mp3, "Netflix", attributes={"media_title": str(sentinel.mt3)}) await set_state(
mp3, "Netflix", attributes={"media_title": str(sentinel.mt3)}
)
) )
# Attributes changed even though state is the same # Attributes changed even though state is the same
states[therm].append( states[therm].append(
set_state(therm, 21, attributes={"current_temperature": 20}) await set_state(therm, 21, attributes={"current_temperature": 20})
) )
return zero, four, states return zero, four, states
async def test_fetch_period_api( async def test_fetch_period_api(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history.""" """Test the fetch period view for history."""
await async_setup_component(hass, "history", {}) await async_setup_component(hass, "history", {})
@ -383,8 +394,8 @@ async def test_fetch_period_api(
async def test_fetch_period_api_with_use_include_order( async def test_fetch_period_api_with_use_include_order(
recorder_mock: Recorder,
hass: HomeAssistant, hass: HomeAssistant,
recorder_mock: Recorder,
hass_client: ClientSessionGenerator, hass_client: ClientSessionGenerator,
caplog: pytest.LogCaptureFixture, caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
@ -402,7 +413,7 @@ async def test_fetch_period_api_with_use_include_order(
async def test_fetch_period_api_with_minimal_response( async def test_fetch_period_api_with_minimal_response(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history with minimal_response.""" """Test the fetch period view for history with minimal_response."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -444,7 +455,7 @@ async def test_fetch_period_api_with_minimal_response(
async def test_fetch_period_api_with_no_timestamp( async def test_fetch_period_api_with_no_timestamp(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history with no timestamp.""" """Test the fetch period view for history with no timestamp."""
await async_setup_component(hass, "history", {}) await async_setup_component(hass, "history", {})
@ -454,8 +465,8 @@ async def test_fetch_period_api_with_no_timestamp(
async def test_fetch_period_api_with_include_order( async def test_fetch_period_api_with_include_order(
recorder_mock: Recorder,
hass: HomeAssistant, hass: HomeAssistant,
recorder_mock: Recorder,
hass_client: ClientSessionGenerator, hass_client: ClientSessionGenerator,
caplog: pytest.LogCaptureFixture, caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
@ -482,7 +493,7 @@ async def test_fetch_period_api_with_include_order(
async def test_entity_ids_limit_via_api( async def test_entity_ids_limit_via_api(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test limiting history to entity_ids.""" """Test limiting history to entity_ids."""
await async_setup_component( await async_setup_component(
@ -508,7 +519,7 @@ async def test_entity_ids_limit_via_api(
async def test_entity_ids_limit_via_api_with_skip_initial_state( async def test_entity_ids_limit_via_api_with_skip_initial_state(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test limiting history to entity_ids with skip_initial_state.""" """Test limiting history to entity_ids with skip_initial_state."""
await async_setup_component( await async_setup_component(
@ -542,7 +553,7 @@ async def test_entity_ids_limit_via_api_with_skip_initial_state(
async def test_fetch_period_api_before_history_started( async def test_fetch_period_api_before_history_started(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history for the far past.""" """Test the fetch period view for history for the far past."""
await async_setup_component( await async_setup_component(
@ -563,7 +574,7 @@ async def test_fetch_period_api_before_history_started(
async def test_fetch_period_api_far_future( async def test_fetch_period_api_far_future(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history for the far future.""" """Test the fetch period view for history for the far future."""
await async_setup_component( await async_setup_component(
@ -584,7 +595,7 @@ async def test_fetch_period_api_far_future(
async def test_fetch_period_api_with_invalid_datetime( async def test_fetch_period_api_with_invalid_datetime(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history with an invalid date time.""" """Test the fetch period view for history with an invalid date time."""
await async_setup_component( await async_setup_component(
@ -603,7 +614,7 @@ async def test_fetch_period_api_with_invalid_datetime(
async def test_fetch_period_api_invalid_end_time( async def test_fetch_period_api_invalid_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history with an invalid end time.""" """Test the fetch period view for history with an invalid end time."""
await async_setup_component( await async_setup_component(
@ -625,7 +636,7 @@ async def test_fetch_period_api_invalid_end_time(
async def test_entity_ids_limit_via_api_with_end_time( async def test_entity_ids_limit_via_api_with_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test limiting history to entity_ids with end_time.""" """Test limiting history to entity_ids with end_time."""
await async_setup_component( await async_setup_component(
@ -671,7 +682,7 @@ async def test_entity_ids_limit_via_api_with_end_time(
async def test_fetch_period_api_with_no_entity_ids( async def test_fetch_period_api_with_no_entity_ids(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history with minimal_response.""" """Test the fetch period view for history with minimal_response."""
await async_setup_component(hass, "history", {}) await async_setup_component(hass, "history", {})
@ -724,13 +735,13 @@ async def test_fetch_period_api_with_no_entity_ids(
], ],
) )
async def test_history_with_invalid_entity_ids( async def test_history_with_invalid_entity_ids(
hass: HomeAssistant,
recorder_mock: Recorder,
hass_client: ClientSessionGenerator,
filter_entity_id, filter_entity_id,
status_code, status_code,
response_contains1, response_contains1,
response_contains2, response_contains2,
recorder_mock: Recorder,
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
) -> None: ) -> None:
"""Test sending valid and invalid entity_ids to the API.""" """Test sending valid and invalid entity_ids to the API."""
await async_setup_component( await async_setup_component(

View file

@ -27,7 +27,6 @@ from tests.components.recorder.common import (
async_recorder_block_till_done, async_recorder_block_till_done,
async_wait_recording_done, async_wait_recording_done,
old_db_schema, old_db_schema,
wait_recording_done,
) )
from tests.typing import ClientSessionGenerator, WebSocketGenerator from tests.typing import ClientSessionGenerator, WebSocketGenerator
@ -40,33 +39,34 @@ def db_schema_30():
@pytest.fixture @pytest.fixture
def legacy_hass_history(hass_history): def legacy_hass_history(hass: HomeAssistant, hass_history):
"""Home Assistant fixture to use legacy history recording.""" """Home Assistant fixture to use legacy history recording."""
instance = recorder.get_instance(hass_history) instance = recorder.get_instance(hass)
with patch.object(instance.states_meta_manager, "active", False): with patch.object(instance.states_meta_manager, "active", False):
yield hass_history yield
@pytest.mark.usefixtures("legacy_hass_history") @pytest.mark.usefixtures("legacy_hass_history")
def test_setup() -> None: async def test_setup() -> None:
"""Test setup method of history.""" """Test setup method of history."""
# Verification occurs in the fixture # Verification occurs in the fixture
def test_get_significant_states(legacy_hass_history) -> None: async def test_get_significant_states(hass: HomeAssistant, legacy_hass_history) -> None:
"""Test that only significant states are returned. """Test that only significant states are returned.
We should get back every thermostat change that We should get back every thermostat change that
includes an attribute change, but only the state updates for includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned). media player (attribute changes are not significant and not returned).
""" """
hass = legacy_hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
hist = get_significant_states(hass, zero, four, entity_ids=list(states)) hist = get_significant_states(hass, zero, four, entity_ids=list(states))
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_minimal_response(legacy_hass_history) -> None: async def test_get_significant_states_minimal_response(
hass: HomeAssistant, legacy_hass_history
) -> None:
"""Test that only significant states are returned. """Test that only significant states are returned.
When minimal responses is set only the first and When minimal responses is set only the first and
@ -76,8 +76,7 @@ def test_get_significant_states_minimal_response(legacy_hass_history) -> None:
includes an attribute change, but only the state updates for includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned). media player (attribute changes are not significant and not returned).
""" """
hass = legacy_hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
hist = get_significant_states( hist = get_significant_states(
hass, zero, four, minimal_response=True, entity_ids=list(states) hass, zero, four, minimal_response=True, entity_ids=list(states)
) )
@ -132,15 +131,16 @@ def test_get_significant_states_minimal_response(legacy_hass_history) -> None:
) )
def test_get_significant_states_with_initial(legacy_hass_history) -> None: async def test_get_significant_states_with_initial(
hass: HomeAssistant, legacy_hass_history
) -> None:
"""Test that only significant states are returned. """Test that only significant states are returned.
We should get back every thermostat change that We should get back every thermostat change that
includes an attribute change, but only the state updates for includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned). media player (attribute changes are not significant and not returned).
""" """
hass = legacy_hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
one = zero + timedelta(seconds=1) one = zero + timedelta(seconds=1)
one_with_microsecond = zero + timedelta(seconds=1, microseconds=1) one_with_microsecond = zero + timedelta(seconds=1, microseconds=1)
one_and_half = zero + timedelta(seconds=1.5) one_and_half = zero + timedelta(seconds=1.5)
@ -162,15 +162,16 @@ def test_get_significant_states_with_initial(legacy_hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_without_initial(legacy_hass_history) -> None: async def test_get_significant_states_without_initial(
hass: HomeAssistant, legacy_hass_history
) -> None:
"""Test that only significant states are returned. """Test that only significant states are returned.
We should get back every thermostat change that We should get back every thermostat change that
includes an attribute change, but only the state updates for includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned). media player (attribute changes are not significant and not returned).
""" """
hass = legacy_hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
one = zero + timedelta(seconds=1) one = zero + timedelta(seconds=1)
one_with_microsecond = zero + timedelta(seconds=1, microseconds=1) one_with_microsecond = zero + timedelta(seconds=1, microseconds=1)
one_and_half = zero + timedelta(seconds=1.5) one_and_half = zero + timedelta(seconds=1.5)
@ -193,13 +194,13 @@ def test_get_significant_states_without_initial(legacy_hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_entity_id(hass_history) -> None: async def test_get_significant_states_entity_id(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned for one entity.""" """Test that only significant states are returned for one entity."""
hass = hass_history
instance = recorder.get_instance(hass) instance = recorder.get_instance(hass)
with patch.object(instance.states_meta_manager, "active", False): with patch.object(instance.states_meta_manager, "active", False):
zero, four, states = record_states(hass) zero, four, states = await async_record_states(hass)
del states["media_player.test2"] del states["media_player.test2"]
del states["media_player.test3"] del states["media_player.test3"]
del states["thermostat.test"] del states["thermostat.test"]
@ -210,10 +211,11 @@ def test_get_significant_states_entity_id(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_multiple_entity_ids(legacy_hass_history) -> None: async def test_get_significant_states_multiple_entity_ids(
hass: HomeAssistant, legacy_hass_history
) -> None:
"""Test that only significant states are returned for one entity.""" """Test that only significant states are returned for one entity."""
hass = legacy_hass_history zero, four, states = await async_record_states(hass)
zero, four, states = record_states(hass)
del states["media_player.test2"] del states["media_player.test2"]
del states["media_player.test3"] del states["media_player.test3"]
del states["thermostat.test2"] del states["thermostat.test2"]
@ -228,14 +230,15 @@ def test_get_significant_states_multiple_entity_ids(legacy_hass_history) -> None
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_are_ordered(legacy_hass_history) -> None: async def test_get_significant_states_are_ordered(
hass: HomeAssistant, legacy_hass_history
) -> None:
"""Test order of results from get_significant_states. """Test order of results from get_significant_states.
When entity ids are given, the results should be returned with the data When entity ids are given, the results should be returned with the data
in the same order. in the same order.
""" """
hass = legacy_hass_history zero, four, _states = await async_record_states(hass)
zero, four, _states = record_states(hass)
entity_ids = ["media_player.test", "media_player.test2"] entity_ids = ["media_player.test", "media_player.test2"]
hist = get_significant_states(hass, zero, four, entity_ids) hist = get_significant_states(hass, zero, four, entity_ids)
assert list(hist.keys()) == entity_ids assert list(hist.keys()) == entity_ids
@ -244,15 +247,16 @@ def test_get_significant_states_are_ordered(legacy_hass_history) -> None:
assert list(hist.keys()) == entity_ids assert list(hist.keys()) == entity_ids
def test_get_significant_states_only(legacy_hass_history) -> None: async def test_get_significant_states_only(
hass: HomeAssistant, legacy_hass_history
) -> None:
"""Test significant states when significant_states_only is set.""" """Test significant states when significant_states_only is set."""
hass = legacy_hass_history
entity_id = "sensor.test" entity_id = "sensor.test"
def set_state(state, **kwargs): async def set_state(state, **kwargs):
"""Set the state.""" """Set the state."""
hass.states.set(entity_id, state, **kwargs) hass.states.async_set(entity_id, state, **kwargs)
wait_recording_done(hass) await async_wait_recording_done(hass)
return hass.states.get(entity_id) return hass.states.get(entity_id)
start = dt_util.utcnow() - timedelta(minutes=4) start = dt_util.utcnow() - timedelta(minutes=4)
@ -260,19 +264,19 @@ def test_get_significant_states_only(legacy_hass_history) -> None:
states = [] states = []
with freeze_time(start) as freezer: with freeze_time(start) as freezer:
set_state("123", attributes={"attribute": 10.64}) await set_state("123", attributes={"attribute": 10.64})
freezer.move_to(points[0]) freezer.move_to(points[0])
# Attributes are different, state not # Attributes are different, state not
states.append(set_state("123", attributes={"attribute": 21.42})) states.append(await set_state("123", attributes={"attribute": 21.42}))
freezer.move_to(points[1]) freezer.move_to(points[1])
# state is different, attributes not # state is different, attributes not
states.append(set_state("32", attributes={"attribute": 21.42})) states.append(await set_state("32", attributes={"attribute": 21.42}))
freezer.move_to(points[2]) freezer.move_to(points[2])
# everything is different # everything is different
states.append(set_state("412", attributes={"attribute": 54.23})) states.append(await set_state("412", attributes={"attribute": 54.23}))
hist = get_significant_states( hist = get_significant_states(
hass, hass,
@ -311,7 +315,7 @@ def check_significant_states(hass, zero, four, states, config):
assert_dict_of_states_equal_without_context_and_last_changed(states, hist) assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def record_states(hass): async def async_record_states(hass):
"""Record some test states. """Record some test states.
We inject a bunch of state updates from media player, zone and We inject a bunch of state updates from media player, zone and
@ -325,10 +329,10 @@ def record_states(hass):
zone = "zone.home" zone = "zone.home"
script_c = "script.can_cancel_this_one" script_c = "script.can_cancel_this_one"
def set_state(entity_id, state, **kwargs): async def async_set_state(entity_id, state, **kwargs):
"""Set the state.""" """Set the state."""
hass.states.set(entity_id, state, **kwargs) hass.states.async_set(entity_id, state, **kwargs)
wait_recording_done(hass) await async_wait_recording_done(hass)
return hass.states.get(entity_id) return hass.states.get(entity_id)
zero = dt_util.utcnow() zero = dt_util.utcnow()
@ -340,55 +344,69 @@ def record_states(hass):
states = {therm: [], therm2: [], mp: [], mp2: [], mp3: [], script_c: []} states = {therm: [], therm2: [], mp: [], mp2: [], mp3: [], script_c: []}
with freeze_time(one) as freezer: with freeze_time(one) as freezer:
states[mp].append( states[mp].append(
set_state(mp, "idle", attributes={"media_title": str(sentinel.mt1)}) await async_set_state(
mp, "idle", attributes={"media_title": str(sentinel.mt1)}
)
) )
states[mp2].append( states[mp2].append(
set_state(mp2, "YouTube", attributes={"media_title": str(sentinel.mt2)}) await async_set_state(
mp2, "YouTube", attributes={"media_title": str(sentinel.mt2)}
)
) )
states[mp3].append( states[mp3].append(
set_state(mp3, "idle", attributes={"media_title": str(sentinel.mt1)}) await async_set_state(
mp3, "idle", attributes={"media_title": str(sentinel.mt1)}
)
) )
states[therm].append( states[therm].append(
set_state(therm, 20, attributes={"current_temperature": 19.5}) await async_set_state(therm, 20, attributes={"current_temperature": 19.5})
) )
freezer.move_to(one + timedelta(microseconds=1)) freezer.move_to(one + timedelta(microseconds=1))
states[mp].append( states[mp].append(
set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt2)}) await async_set_state(
mp, "YouTube", attributes={"media_title": str(sentinel.mt2)}
)
) )
freezer.move_to(two) freezer.move_to(two)
# This state will be skipped only different in time # This state will be skipped only different in time
set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt3)}) await async_set_state(
mp, "YouTube", attributes={"media_title": str(sentinel.mt3)}
)
# This state will be skipped because domain is excluded # This state will be skipped because domain is excluded
set_state(zone, "zoning") await async_set_state(zone, "zoning")
states[script_c].append( states[script_c].append(
set_state(script_c, "off", attributes={"can_cancel": True}) await async_set_state(script_c, "off", attributes={"can_cancel": True})
) )
states[therm].append( states[therm].append(
set_state(therm, 21, attributes={"current_temperature": 19.8}) await async_set_state(therm, 21, attributes={"current_temperature": 19.8})
) )
states[therm2].append( states[therm2].append(
set_state(therm2, 20, attributes={"current_temperature": 19}) await async_set_state(therm2, 20, attributes={"current_temperature": 19})
) )
freezer.move_to(three) freezer.move_to(three)
states[mp].append( states[mp].append(
set_state(mp, "Netflix", attributes={"media_title": str(sentinel.mt4)}) await async_set_state(
mp, "Netflix", attributes={"media_title": str(sentinel.mt4)}
)
) )
states[mp3].append( states[mp3].append(
set_state(mp3, "Netflix", attributes={"media_title": str(sentinel.mt3)}) await async_set_state(
mp3, "Netflix", attributes={"media_title": str(sentinel.mt3)}
)
) )
# Attributes changed even though state is the same # Attributes changed even though state is the same
states[therm].append( states[therm].append(
set_state(therm, 21, attributes={"current_temperature": 20}) await async_set_state(therm, 21, attributes={"current_temperature": 20})
) )
return zero, four, states return zero, four, states
async def test_fetch_period_api( async def test_fetch_period_api(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history.""" """Test the fetch period view for history."""
await async_setup_component(hass, "history", {}) await async_setup_component(hass, "history", {})
@ -402,7 +420,7 @@ async def test_fetch_period_api(
async def test_fetch_period_api_with_minimal_response( async def test_fetch_period_api_with_minimal_response(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history with minimal_response.""" """Test the fetch period view for history with minimal_response."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -445,7 +463,7 @@ async def test_fetch_period_api_with_minimal_response(
async def test_fetch_period_api_with_no_timestamp( async def test_fetch_period_api_with_no_timestamp(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history with no timestamp.""" """Test the fetch period view for history with no timestamp."""
await async_setup_component(hass, "history", {}) await async_setup_component(hass, "history", {})
@ -457,7 +475,7 @@ async def test_fetch_period_api_with_no_timestamp(
async def test_fetch_period_api_with_include_order( async def test_fetch_period_api_with_include_order(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test the fetch period view for history.""" """Test the fetch period view for history."""
await async_setup_component( await async_setup_component(
@ -481,7 +499,7 @@ async def test_fetch_period_api_with_include_order(
async def test_entity_ids_limit_via_api( async def test_entity_ids_limit_via_api(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test limiting history to entity_ids.""" """Test limiting history to entity_ids."""
await async_setup_component( await async_setup_component(
@ -509,7 +527,7 @@ async def test_entity_ids_limit_via_api(
async def test_entity_ids_limit_via_api_with_skip_initial_state( async def test_entity_ids_limit_via_api_with_skip_initial_state(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None: ) -> None:
"""Test limiting history to entity_ids with skip_initial_state.""" """Test limiting history to entity_ids with skip_initial_state."""
await async_setup_component( await async_setup_component(
@ -545,7 +563,7 @@ async def test_entity_ids_limit_via_api_with_skip_initial_state(
async def test_history_during_period( async def test_history_during_period(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period.""" """Test history_during_period."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -693,7 +711,7 @@ async def test_history_during_period(
async def test_history_during_period_impossible_conditions( async def test_history_during_period_impossible_conditions(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period returns when condition cannot be true.""" """Test history_during_period returns when condition cannot be true."""
await async_setup_component(hass, "history", {}) await async_setup_component(hass, "history", {})
@ -757,10 +775,10 @@ async def test_history_during_period_impossible_conditions(
"time_zone", ["UTC", "Europe/Berlin", "America/Chicago", "US/Hawaii"] "time_zone", ["UTC", "Europe/Berlin", "America/Chicago", "US/Hawaii"]
) )
async def test_history_during_period_significant_domain( async def test_history_during_period_significant_domain(
time_zone,
recorder_mock: Recorder,
hass: HomeAssistant, hass: HomeAssistant,
recorder_mock: Recorder,
hass_ws_client: WebSocketGenerator, hass_ws_client: WebSocketGenerator,
time_zone,
) -> None: ) -> None:
"""Test history_during_period with climate domain.""" """Test history_during_period with climate domain."""
hass.config.set_time_zone(time_zone) hass.config.set_time_zone(time_zone)
@ -941,7 +959,7 @@ async def test_history_during_period_significant_domain(
async def test_history_during_period_bad_start_time( async def test_history_during_period_bad_start_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period bad state time.""" """Test history_during_period bad state time."""
await async_setup_component( await async_setup_component(
@ -966,7 +984,7 @@ async def test_history_during_period_bad_start_time(
async def test_history_during_period_bad_end_time( async def test_history_during_period_bad_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period bad end time.""" """Test history_during_period bad end time."""
now = dt_util.utcnow() now = dt_util.utcnow()

View file

@ -39,7 +39,7 @@ def test_setup() -> None:
async def test_history_during_period( async def test_history_during_period(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period.""" """Test history_during_period."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -173,7 +173,7 @@ async def test_history_during_period(
async def test_history_during_period_impossible_conditions( async def test_history_during_period_impossible_conditions(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period returns when condition cannot be true.""" """Test history_during_period returns when condition cannot be true."""
await async_setup_component(hass, "history", {}) await async_setup_component(hass, "history", {})
@ -235,10 +235,10 @@ async def test_history_during_period_impossible_conditions(
"time_zone", ["UTC", "Europe/Berlin", "America/Chicago", "US/Hawaii"] "time_zone", ["UTC", "Europe/Berlin", "America/Chicago", "US/Hawaii"]
) )
async def test_history_during_period_significant_domain( async def test_history_during_period_significant_domain(
time_zone,
recorder_mock: Recorder,
hass: HomeAssistant, hass: HomeAssistant,
recorder_mock: Recorder,
hass_ws_client: WebSocketGenerator, hass_ws_client: WebSocketGenerator,
time_zone,
) -> None: ) -> None:
"""Test history_during_period with climate domain.""" """Test history_during_period with climate domain."""
hass.config.set_time_zone(time_zone) hass.config.set_time_zone(time_zone)
@ -403,7 +403,7 @@ async def test_history_during_period_significant_domain(
async def test_history_during_period_bad_start_time( async def test_history_during_period_bad_start_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period bad state time.""" """Test history_during_period bad state time."""
await async_setup_component( await async_setup_component(
@ -427,7 +427,7 @@ async def test_history_during_period_bad_start_time(
async def test_history_during_period_bad_end_time( async def test_history_during_period_bad_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period bad end time.""" """Test history_during_period bad end time."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -454,7 +454,7 @@ async def test_history_during_period_bad_end_time(
async def test_history_stream_historical_only( async def test_history_stream_historical_only(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream.""" """Test history stream."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -525,7 +525,7 @@ async def test_history_stream_historical_only(
async def test_history_stream_significant_domain_historical_only( async def test_history_stream_significant_domain_historical_only(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test the stream with climate domain with historical states only.""" """Test the stream with climate domain with historical states only."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -726,7 +726,7 @@ async def test_history_stream_significant_domain_historical_only(
async def test_history_stream_bad_start_time( async def test_history_stream_bad_start_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream bad state time.""" """Test history stream bad state time."""
await async_setup_component( await async_setup_component(
@ -750,7 +750,7 @@ async def test_history_stream_bad_start_time(
async def test_history_stream_end_time_before_start_time( async def test_history_stream_end_time_before_start_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream with an end_time before the start_time.""" """Test history stream with an end_time before the start_time."""
end_time = dt_util.utcnow() - timedelta(seconds=2) end_time = dt_util.utcnow() - timedelta(seconds=2)
@ -778,7 +778,7 @@ async def test_history_stream_end_time_before_start_time(
async def test_history_stream_bad_end_time( async def test_history_stream_bad_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream bad end time.""" """Test history stream bad end time."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -805,7 +805,7 @@ async def test_history_stream_bad_end_time(
async def test_history_stream_live_no_attributes_minimal_response( async def test_history_stream_live_no_attributes_minimal_response(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream with history and live data and no_attributes and minimal_response.""" """Test history stream with history and live data and no_attributes and minimal_response."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -882,7 +882,7 @@ async def test_history_stream_live_no_attributes_minimal_response(
async def test_history_stream_live( async def test_history_stream_live(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream with history and live data.""" """Test history stream with history and live data."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -985,7 +985,7 @@ async def test_history_stream_live(
async def test_history_stream_live_minimal_response( async def test_history_stream_live_minimal_response(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream with history and live data and minimal_response.""" """Test history stream with history and live data and minimal_response."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -1082,7 +1082,7 @@ async def test_history_stream_live_minimal_response(
async def test_history_stream_live_no_attributes( async def test_history_stream_live_no_attributes(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream with history and live data and no_attributes.""" """Test history stream with history and live data and no_attributes."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -1163,7 +1163,7 @@ async def test_history_stream_live_no_attributes(
async def test_history_stream_live_no_attributes_minimal_response_specific_entities( async def test_history_stream_live_no_attributes_minimal_response_specific_entities(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream with history and live data and no_attributes and minimal_response with specific entities.""" """Test history stream with history and live data and no_attributes and minimal_response with specific entities."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -1241,7 +1241,7 @@ async def test_history_stream_live_no_attributes_minimal_response_specific_entit
async def test_history_stream_live_with_future_end_time( async def test_history_stream_live_with_future_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream with history and live data with future end time.""" """Test history stream with history and live data with future end time."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -1334,8 +1334,8 @@ async def test_history_stream_live_with_future_end_time(
@pytest.mark.parametrize("include_start_time_state", [True, False]) @pytest.mark.parametrize("include_start_time_state", [True, False])
async def test_history_stream_before_history_starts( async def test_history_stream_before_history_starts(
recorder_mock: Recorder,
hass: HomeAssistant, hass: HomeAssistant,
recorder_mock: Recorder,
hass_ws_client: WebSocketGenerator, hass_ws_client: WebSocketGenerator,
include_start_time_state, include_start_time_state,
) -> None: ) -> None:
@ -1385,7 +1385,7 @@ async def test_history_stream_before_history_starts(
async def test_history_stream_for_entity_with_no_possible_changes( async def test_history_stream_for_entity_with_no_possible_changes(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream for future with no possible changes where end time is less than or equal to now.""" """Test history stream for future with no possible changes where end time is less than or equal to now."""
await async_setup_component( await async_setup_component(
@ -1436,7 +1436,7 @@ async def test_history_stream_for_entity_with_no_possible_changes(
async def test_overflow_queue( async def test_overflow_queue(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test overflowing the history stream queue.""" """Test overflowing the history stream queue."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -1513,7 +1513,7 @@ async def test_overflow_queue(
async def test_history_during_period_for_invalid_entity_ids( async def test_history_during_period_for_invalid_entity_ids(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period for valid and invalid entity ids.""" """Test history_during_period for valid and invalid entity ids."""
now = dt_util.utcnow() now = dt_util.utcnow()
@ -1656,7 +1656,7 @@ async def test_history_during_period_for_invalid_entity_ids(
async def test_history_stream_for_invalid_entity_ids( async def test_history_stream_for_invalid_entity_ids(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream for invalid and valid entity ids.""" """Test history stream for invalid and valid entity ids."""
@ -1824,7 +1824,7 @@ async def test_history_stream_for_invalid_entity_ids(
async def test_history_stream_historical_only_with_start_time_state_past( async def test_history_stream_historical_only_with_start_time_state_past(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history stream.""" """Test history stream."""
await async_setup_component( await async_setup_component(

View file

@ -24,7 +24,7 @@ def db_schema_32():
async def test_history_during_period( async def test_history_during_period(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None: ) -> None:
"""Test history_during_period.""" """Test history_during_period."""
now = dt_util.utcnow() now = dt_util.utcnow()

View file

@ -198,7 +198,7 @@ async def test_shutdown_closes_connections(
hass.set_state(CoreState.not_running) hass.set_state(CoreState.not_running)
instance = get_instance(hass) instance = recorder.get_instance(hass)
await instance.async_db_ready await instance.async_db_ready
await hass.async_block_till_done() await hass.async_block_till_done()
pool = instance.engine.pool pool = instance.engine.pool

View file

@ -526,6 +526,7 @@ async def hass(
load_registries: bool, load_registries: bool,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
request: pytest.FixtureRequest, request: pytest.FixtureRequest,
mock_recorder_before_hass: None,
) -> AsyncGenerator[HomeAssistant, None]: ) -> AsyncGenerator[HomeAssistant, None]:
"""Create a test instance of Home Assistant.""" """Create a test instance of Home Assistant."""
@ -1577,6 +1578,15 @@ async def recorder_mock(
return await async_setup_recorder_instance(hass, recorder_config) return await async_setup_recorder_instance(hass, recorder_config)
@pytest.fixture
def mock_recorder_before_hass() -> None:
"""Mock the recorder.
Override or parametrize this fixture with a fixture that mocks the recorder,
in the tests that need to test the recorder.
"""
@pytest.fixture(name="enable_bluetooth") @pytest.fixture(name="enable_bluetooth")
async def mock_enable_bluetooth( async def mock_enable_bluetooth(
hass: HomeAssistant, hass: HomeAssistant,