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