Stop updating google_calendars.yaml if it does not already exist (#72340)
* Stop updating google_calendars.yaml if it does not already exist * Add additional test coverage to make CI pass * Add test for no updates to google_calendar.yaml * Add parameter to test for expecting write calls * Missing call argument * Remove conditional and replace with inline assertpull/72485/head
parent
9591d5366e
commit
71bc650ac7
|
@ -300,6 +300,7 @@ async def async_setup_services(
|
|||
calendars = await hass.async_add_executor_job(
|
||||
load_config, hass.config.path(YAML_DEVICES)
|
||||
)
|
||||
calendars_file_lock = asyncio.Lock()
|
||||
|
||||
async def _found_calendar(calendar_item: Calendar) -> None:
|
||||
calendar = get_calendar_info(
|
||||
|
@ -307,15 +308,19 @@ async def async_setup_services(
|
|||
calendar_item.dict(exclude_unset=True),
|
||||
)
|
||||
calendar_id = calendar_item.id
|
||||
# Populate the yaml file with all discovered calendars
|
||||
if calendar_id not in calendars:
|
||||
calendars[calendar_id] = calendar
|
||||
await hass.async_add_executor_job(
|
||||
update_config, hass.config.path(YAML_DEVICES), calendar
|
||||
)
|
||||
else:
|
||||
# Prefer entity/name information from yaml, overriding api
|
||||
calendar = calendars[calendar_id]
|
||||
# If the google_calendars.yaml file already exists, populate it for
|
||||
# backwards compatibility, but otherwise do not create it if it does
|
||||
# not exist.
|
||||
if calendars:
|
||||
if calendar_id not in calendars:
|
||||
calendars[calendar_id] = calendar
|
||||
async with calendars_file_lock:
|
||||
await hass.async_add_executor_job(
|
||||
update_config, hass.config.path(YAML_DEVICES), calendar
|
||||
)
|
||||
else:
|
||||
# Prefer entity/name information from yaml, overriding api
|
||||
calendar = calendars[calendar_id]
|
||||
async_dispatcher_send(hass, DISCOVER_CALENDAR, calendar)
|
||||
|
||||
created_calendars = set()
|
||||
|
|
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||
from collections.abc import Awaitable, Callable
|
||||
import datetime
|
||||
from typing import Any, Generator, TypeVar
|
||||
from unittest.mock import mock_open, patch
|
||||
from unittest.mock import Mock, mock_open, patch
|
||||
|
||||
from aiohttp.client_exceptions import ClientError
|
||||
from gcal_sync.auth import API_BASE_URL
|
||||
|
@ -104,11 +104,11 @@ def calendars_config(calendars_config_entity: dict[str, Any]) -> list[dict[str,
|
|||
def mock_calendars_yaml(
|
||||
hass: HomeAssistant,
|
||||
calendars_config: list[dict[str, Any]],
|
||||
) -> None:
|
||||
) -> Generator[Mock, None, None]:
|
||||
"""Fixture that prepares the google_calendars.yaml mocks."""
|
||||
mocked_open_function = mock_open(read_data=yaml.dump(calendars_config))
|
||||
with patch("homeassistant.components.google.open", mocked_open_function):
|
||||
yield
|
||||
yield mocked_open_function
|
||||
|
||||
|
||||
class FakeStorage:
|
||||
|
@ -170,10 +170,17 @@ def config_entry_token_expiry(token_expiry: datetime.datetime) -> float:
|
|||
return token_expiry.timestamp()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config_entry_options() -> dict[str, Any] | None:
|
||||
"""Fixture to set initial config entry options."""
|
||||
return None
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config_entry(
|
||||
token_scopes: list[str],
|
||||
config_entry_token_expiry: float,
|
||||
config_entry_options: dict[str, Any] | None,
|
||||
) -> MockConfigEntry:
|
||||
"""Fixture to create a config entry for the integration."""
|
||||
return MockConfigEntry(
|
||||
|
@ -188,6 +195,7 @@ def config_entry(
|
|||
"expires_at": config_entry_token_expiry,
|
||||
},
|
||||
},
|
||||
options=config_entry_options,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -572,14 +572,16 @@ async def test_opaque_event(
|
|||
assert (len(events) > 0) == expect_visible_event
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mock_test_setup", [None])
|
||||
async def test_scan_calendar_error(
|
||||
hass,
|
||||
component_setup,
|
||||
test_api_calendar,
|
||||
mock_calendars_list,
|
||||
config_entry,
|
||||
):
|
||||
"""Test that the calendar update handles a server error."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
mock_calendars_list({}, exc=ClientError())
|
||||
assert await component_setup()
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import datetime
|
|||
import http
|
||||
import time
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -19,6 +19,7 @@ from homeassistant.components.google import (
|
|||
SERVICE_ADD_EVENT,
|
||||
SERVICE_SCAN_CALENDARS,
|
||||
)
|
||||
from homeassistant.components.google.const import CONF_CALENDAR_ACCESS
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import STATE_OFF
|
||||
from homeassistant.core import HomeAssistant, State
|
||||
|
@ -229,7 +230,10 @@ async def test_found_calendar_from_api(
|
|||
assert not hass.states.get(TEST_YAML_ENTITY)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("calendars_config,google_config", [([], {})])
|
||||
@pytest.mark.parametrize(
|
||||
"calendars_config,google_config,config_entry_options",
|
||||
[([], {}, {CONF_CALENDAR_ACCESS: "read_write"})],
|
||||
)
|
||||
async def test_load_application_credentials(
|
||||
hass: HomeAssistant,
|
||||
component_setup: ComponentSetup,
|
||||
|
@ -604,3 +608,48 @@ async def test_expired_token_requires_reauth(
|
|||
flows = hass.config_entries.flow.async_progress()
|
||||
assert len(flows) == 1
|
||||
assert flows[0]["step_id"] == "reauth_confirm"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"calendars_config,expect_write_calls",
|
||||
[
|
||||
(
|
||||
[
|
||||
{
|
||||
"cal_id": "ignored",
|
||||
"entities": {"device_id": "existing", "name": "existing"},
|
||||
}
|
||||
],
|
||||
True,
|
||||
),
|
||||
([], False),
|
||||
],
|
||||
ids=["has_yaml", "no_yaml"],
|
||||
)
|
||||
async def test_calendar_yaml_update(
|
||||
hass: HomeAssistant,
|
||||
component_setup: ComponentSetup,
|
||||
mock_calendars_yaml: Mock,
|
||||
mock_calendars_list: ApiResult,
|
||||
test_api_calendar: dict[str, Any],
|
||||
mock_events_list: ApiResult,
|
||||
setup_config_entry: MockConfigEntry,
|
||||
calendars_config: dict[str, Any],
|
||||
expect_write_calls: bool,
|
||||
) -> None:
|
||||
"""Test updating the yaml file with a new calendar."""
|
||||
|
||||
mock_calendars_list({"items": [test_api_calendar]})
|
||||
mock_events_list({})
|
||||
assert await component_setup()
|
||||
|
||||
mock_calendars_yaml().read.assert_called()
|
||||
mock_calendars_yaml().write.called is expect_write_calls
|
||||
|
||||
state = hass.states.get(TEST_API_ENTITY)
|
||||
assert state
|
||||
assert state.name == TEST_API_ENTITY_NAME
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
# No yaml config loaded that overwrites the entity name
|
||||
assert not hass.states.get(TEST_YAML_ENTITY)
|
||||
|
|
Loading…
Reference in New Issue