From 0ae0331c5c8626bc6a14bd6109d046a860a47dab Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke <jan-philipp@bnck.me> Date: Thu, 21 Dec 2023 12:23:01 +0100 Subject: [PATCH] Migrate google related tests to use freezegun (#105552) * Migrate google related tests to use freezegun * retrigger CI * Fix google tests * Add timezone to config_entry_token_expiry * Separate config_entry_token_expiry from token_expiry * Also test token refresh for offset-naive tokens * retrigger CI * Apply code review suggestion Co-authored-by: Allen Porter <allen.porter@gmail.com> * Run ruff-format --------- Co-authored-by: Allen Porter <allen.porter@gmail.com> --- tests/components/google/conftest.py | 5 +-- tests/components/google/test_calendar.py | 31 +++++++++---------- tests/components/google/test_config_flow.py | 3 +- tests/components/google/test_init.py | 6 +++- .../components/google_assistant/test_trait.py | 23 ++++++++------ tests/components/nest/test_camera.py | 3 +- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/tests/components/google/conftest.py b/tests/components/google/conftest.py index 4196604b5d4..97d918c2e01 100644 --- a/tests/components/google/conftest.py +++ b/tests/components/google/conftest.py @@ -4,6 +4,7 @@ from __future__ import annotations from collections.abc import Awaitable, Callable, Generator import datetime import http +import time from typing import Any, TypeVar from unittest.mock import Mock, mock_open, patch @@ -189,9 +190,9 @@ def creds( @pytest.fixture -def config_entry_token_expiry(token_expiry: datetime.datetime) -> float: +def config_entry_token_expiry() -> float: """Fixture for token expiration value stored in the config entry.""" - return token_expiry.timestamp() + return time.time() + 86400 @pytest.fixture diff --git a/tests/components/google/test_calendar.py b/tests/components/google/test_calendar.py index 8466f5ad4eb..d1cc41e166a 100644 --- a/tests/components/google/test_calendar.py +++ b/tests/components/google/test_calendar.py @@ -9,6 +9,7 @@ from unittest.mock import patch import urllib from aiohttp.client_exceptions import ClientError +from freezegun.api import FrozenDateTimeFactory from gcal_sync.auth import API_BASE_URL import pytest @@ -578,11 +579,13 @@ async def test_scan_calendar_error( async def test_future_event_update_behavior( - hass: HomeAssistant, mock_events_list_items, component_setup + hass: HomeAssistant, + freezer: FrozenDateTimeFactory, + mock_events_list_items, + component_setup, ) -> None: """Test an future event that becomes active.""" now = dt_util.now() - now_utc = dt_util.utcnow() one_hour_from_now = now + datetime.timedelta(minutes=60) end_event = one_hour_from_now + datetime.timedelta(minutes=90) event = { @@ -600,12 +603,9 @@ async def test_future_event_update_behavior( # Advance time until event has started now += datetime.timedelta(minutes=60) - now_utc += datetime.timedelta(minutes=60) - with patch("homeassistant.util.dt.utcnow", return_value=now_utc), patch( - "homeassistant.util.dt.now", return_value=now - ): - async_fire_time_changed(hass, now) - await hass.async_block_till_done() + freezer.move_to(now) + async_fire_time_changed(hass, now) + await hass.async_block_till_done() # Event has started state = hass.states.get(TEST_ENTITY) @@ -613,11 +613,13 @@ async def test_future_event_update_behavior( async def test_future_event_offset_update_behavior( - hass: HomeAssistant, mock_events_list_items, component_setup + hass: HomeAssistant, + freezer: FrozenDateTimeFactory, + mock_events_list_items, + component_setup, ) -> None: """Test an future event that becomes active.""" now = dt_util.now() - now_utc = dt_util.utcnow() one_hour_from_now = now + datetime.timedelta(minutes=60) end_event = one_hour_from_now + datetime.timedelta(minutes=90) event_summary = "Test Event in Progress" @@ -638,12 +640,9 @@ async def test_future_event_offset_update_behavior( # Advance time until event has started now += datetime.timedelta(minutes=45) - now_utc += datetime.timedelta(minutes=45) - with patch("homeassistant.util.dt.utcnow", return_value=now_utc), patch( - "homeassistant.util.dt.now", return_value=now - ): - async_fire_time_changed(hass, now) - await hass.async_block_till_done() + freezer.move_to(now) + async_fire_time_changed(hass, now) + await hass.async_block_till_done() # Event has not started, but the offset was reached state = hass.states.get(TEST_ENTITY) diff --git a/tests/components/google/test_config_flow.py b/tests/components/google/test_config_flow.py index f534f624bf6..b2c472757b6 100644 --- a/tests/components/google/test_config_flow.py +++ b/tests/components/google/test_config_flow.py @@ -9,6 +9,7 @@ from typing import Any from unittest.mock import Mock, patch from aiohttp.client_exceptions import ClientError +from freezegun import freeze_time from oauth2client.client import ( DeviceFlowInfo, FlowExchangeError, @@ -130,7 +131,7 @@ async def primary_calendar( async def fire_alarm(hass, point_in_time): """Fire an alarm and wait for callbacks to run.""" - with patch("homeassistant.util.dt.utcnow", return_value=point_in_time): + with freeze_time(point_in_time): async_fire_time_changed(hass, point_in_time) await hass.async_block_till_done() diff --git a/tests/components/google/test_init.py b/tests/components/google/test_init.py index 9ede0573922..26a5cb2e192 100644 --- a/tests/components/google/test_init.py +++ b/tests/components/google/test_init.py @@ -699,7 +699,11 @@ async def test_add_event_location( @pytest.mark.parametrize( "config_entry_token_expiry", - [datetime.datetime.max.replace(tzinfo=UTC).timestamp() + 1], + [ + (datetime.datetime.max.replace(tzinfo=UTC).timestamp() + 1), + (utcnow().replace(tzinfo=None).timestamp()), + ], + ids=["max_timestamp", "timestamp_naive"], ) async def test_invalid_token_expiry_in_config_entry( hass: HomeAssistant, diff --git a/tests/components/google_assistant/test_trait.py b/tests/components/google_assistant/test_trait.py index 293b16e637a..30a83e7e0c3 100644 --- a/tests/components/google_assistant/test_trait.py +++ b/tests/components/google_assistant/test_trait.py @@ -2,6 +2,7 @@ from datetime import datetime, timedelta from unittest.mock import ANY, patch +from freezegun.api import FrozenDateTimeFactory import pytest from homeassistant.components import ( @@ -76,7 +77,7 @@ from homeassistant.core import ( HomeAssistant, State, ) -from homeassistant.util import color +from homeassistant.util import color, dt as dt_util from homeassistant.util.unit_conversion import TemperatureConverter from . import BASIC_CONFIG, MockConfig @@ -3389,7 +3390,9 @@ async def test_humidity_setting_sensor_data( assert err.value.code == const.ERR_NOT_SUPPORTED -async def test_transport_control(hass: HomeAssistant) -> None: +async def test_transport_control( + hass: HomeAssistant, freezer: FrozenDateTimeFactory +) -> None: """Test the TransportControlTrait.""" assert helpers.get_google_type(media_player.DOMAIN, None) is not None @@ -3398,7 +3401,7 @@ async def test_transport_control(hass: HomeAssistant) -> None: media_player.DOMAIN, feature, None, None ) - now = datetime(2020, 1, 1) + now = datetime(2020, 1, 1, tzinfo=dt_util.UTC) trt = trait.TransportControlTrait( hass, @@ -3429,13 +3432,13 @@ async def test_transport_control(hass: HomeAssistant) -> None: ) # Patch to avoid time ticking over during the command failing the test - with patch("homeassistant.util.dt.utcnow", return_value=now): - await trt.execute( - trait.COMMAND_MEDIA_SEEK_RELATIVE, - BASIC_DATA, - {"relativePositionMs": 10000}, - {}, - ) + freezer.move_to(now) + await trt.execute( + trait.COMMAND_MEDIA_SEEK_RELATIVE, + BASIC_DATA, + {"relativePositionMs": 10000}, + {}, + ) assert len(calls) == 1 assert calls[0].data == { ATTR_ENTITY_ID: "media_player.bla", diff --git a/tests/components/nest/test_camera.py b/tests/components/nest/test_camera.py index 56c5bedaf0d..647a3419501 100644 --- a/tests/components/nest/test_camera.py +++ b/tests/components/nest/test_camera.py @@ -8,6 +8,7 @@ from http import HTTPStatus from unittest.mock import AsyncMock, Mock, patch import aiohttp +from freezegun import freeze_time from google_nest_sdm.event import EventMessage import pytest @@ -173,7 +174,7 @@ async def async_get_image(hass, width=None, height=None): async def fire_alarm(hass, point_in_time): """Fire an alarm and wait for callbacks to run.""" - with patch("homeassistant.util.dt.utcnow", return_value=point_in_time): + with freeze_time(point_in_time): async_fire_time_changed(hass, point_in_time) await hass.async_block_till_done() -- GitLab