Increase test coverage for google calendar (#62648)
* Increase test coverage for google calendar Update tests to exercise the API responses, getting test coverage to 97% for calendar.py ----------- coverage: platform linux, python 3.9.6-final-0 ----------- Name Stmts Miss Cover Missing --------------------------------------------------------------------------- homeassistant/components/google/__init__.py 193 84 56% 92, 163-228, 238, 244-247, 254-262, 274, 298-299, 305-347, 387-392, 416-430, 435-437 homeassistant/components/google/calendar.py 122 4 97% 41, 45, 51, 135 --------------------------------------------------------------------------- TOTAL 315 88 72% * Revert conftest changes * Update typing errors found on CI * Update python3.8 typing imports * Remove commented out code
This commit is contained in:
parent
6ef7539a31
commit
23277181ca
3 changed files with 170 additions and 9 deletions
|
@ -399,7 +399,7 @@ omit =
|
||||||
homeassistant/components/glances/sensor.py
|
homeassistant/components/glances/sensor.py
|
||||||
homeassistant/components/gntp/notify.py
|
homeassistant/components/gntp/notify.py
|
||||||
homeassistant/components/goalfeed/*
|
homeassistant/components/goalfeed/*
|
||||||
homeassistant/components/google/*
|
homeassistant/components/google/__init__.py
|
||||||
homeassistant/components/google_cloud/tts.py
|
homeassistant/components/google_cloud/tts.py
|
||||||
homeassistant/components/google_maps/device_tracker.py
|
homeassistant/components/google_maps/device_tracker.py
|
||||||
homeassistant/components/google_pubsub/__init__.py
|
homeassistant/components/google_pubsub/__init__.py
|
||||||
|
|
|
@ -121,8 +121,8 @@ class GoogleCalendarData:
|
||||||
def _prepare_query(self):
|
def _prepare_query(self):
|
||||||
try:
|
try:
|
||||||
service = self.calendar_service.get()
|
service = self.calendar_service.get()
|
||||||
except ServerNotFoundError:
|
except ServerNotFoundError as err:
|
||||||
_LOGGER.error("Unable to connect to Google")
|
_LOGGER.error("Unable to connect to Google: %s", err)
|
||||||
return None, None
|
return None, None
|
||||||
params = dict(DEFAULT_GOOGLE_SEARCH_PARAMS)
|
params = dict(DEFAULT_GOOGLE_SEARCH_PARAMS)
|
||||||
params["calendarId"] = self.calendar_id
|
params["calendarId"] = self.calendar_id
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
"""The tests for the google calendar platform."""
|
"""The tests for the google calendar platform."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any, Callable
|
||||||
from unittest.mock import Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
import httplib2
|
import httplib2
|
||||||
|
@ -11,10 +16,12 @@ from homeassistant.components.google import (
|
||||||
CONF_CLIENT_SECRET,
|
CONF_CLIENT_SECRET,
|
||||||
CONF_DEVICE_ID,
|
CONF_DEVICE_ID,
|
||||||
CONF_ENTITIES,
|
CONF_ENTITIES,
|
||||||
|
CONF_IGNORE_AVAILABILITY,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_TRACK,
|
CONF_TRACK,
|
||||||
DEVICE_SCHEMA,
|
DEVICE_SCHEMA,
|
||||||
SERVICE_SCAN_CALENDARS,
|
SERVICE_SCAN_CALENDARS,
|
||||||
|
GoogleCalendarService,
|
||||||
do_setup,
|
do_setup,
|
||||||
)
|
)
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON
|
from homeassistant.const import STATE_OFF, STATE_ON
|
||||||
|
@ -23,6 +30,8 @@ from homeassistant.setup import async_setup_component
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
from .conftest import TEST_CALENDAR
|
||||||
|
|
||||||
from tests.common import async_mock_service
|
from tests.common import async_mock_service
|
||||||
|
|
||||||
GOOGLE_CONFIG = {CONF_CLIENT_ID: "client_id", CONF_CLIENT_SECRET: "client_secret"}
|
GOOGLE_CONFIG = {CONF_CLIENT_ID: "client_id", CONF_CLIENT_SECRET: "client_secret"}
|
||||||
|
@ -69,6 +78,7 @@ def get_calendar_info(calendar):
|
||||||
CONF_TRACK: calendar["track"],
|
CONF_TRACK: calendar["track"],
|
||||||
CONF_NAME: calendar["summary"],
|
CONF_NAME: calendar["summary"],
|
||||||
CONF_DEVICE_ID: slugify(calendar["summary"]),
|
CONF_DEVICE_ID: slugify(calendar["summary"]),
|
||||||
|
CONF_IGNORE_AVAILABILITY: calendar.get("ignore_availability", True),
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@ -95,12 +105,6 @@ def mock_google_setup(hass, test_calendar):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
|
||||||
def mock_http(hass):
|
|
||||||
"""Mock the http component."""
|
|
||||||
hass.http = Mock()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def set_time_zone():
|
def set_time_zone():
|
||||||
"""Set the time zone for the tests."""
|
"""Set the time zone for the tests."""
|
||||||
|
@ -314,3 +318,160 @@ async def test_update_error(hass, google_service):
|
||||||
state = hass.states.get(TEST_ENTITY)
|
state = hass.states.get(TEST_ENTITY)
|
||||||
assert state.name == TEST_ENTITY_NAME
|
assert state.name == TEST_ENTITY_NAME
|
||||||
assert state.state == "off"
|
assert state.state == "off"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_calendars_api(hass, hass_client, google_service):
|
||||||
|
"""Test the Rest API returns the calendar."""
|
||||||
|
assert await async_setup_component(hass, "google", {"google": GOOGLE_CONFIG})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
client = await hass_client()
|
||||||
|
response = await client.get("/api/calendars")
|
||||||
|
assert response.status == HTTPStatus.OK
|
||||||
|
data = await response.json()
|
||||||
|
assert data == [
|
||||||
|
{
|
||||||
|
"entity_id": TEST_ENTITY,
|
||||||
|
"name": TEST_ENTITY_NAME,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
async def test_http_event_api_failure(hass, hass_client, google_service):
|
||||||
|
"""Test the Rest API response during a calendar failure."""
|
||||||
|
google_service.return_value.get = Mock(
|
||||||
|
side_effect=httplib2.ServerNotFoundError("unit test")
|
||||||
|
)
|
||||||
|
|
||||||
|
assert await async_setup_component(hass, "google", {"google": GOOGLE_CONFIG})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
start = dt_util.now().isoformat()
|
||||||
|
end = (dt_util.now() + dt_util.dt.timedelta(minutes=60)).isoformat()
|
||||||
|
|
||||||
|
client = await hass_client()
|
||||||
|
response = await client.get(f"/api/calendars/{TEST_ENTITY}?start={start}&end={end}")
|
||||||
|
assert response.status == HTTPStatus.OK
|
||||||
|
# A failure to talk to the server results in an empty list of events
|
||||||
|
events = await response.json()
|
||||||
|
assert events == []
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_events_list(
|
||||||
|
google_service: GoogleCalendarService,
|
||||||
|
) -> Callable[[dict[str, Any]], None]:
|
||||||
|
"""Fixture to construct a fake event list API response."""
|
||||||
|
|
||||||
|
def _put_result(response: dict[str, Any]) -> None:
|
||||||
|
google_service.return_value.get.return_value.events.return_value.list.return_value.execute.return_value = (
|
||||||
|
response
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
return _put_result
|
||||||
|
|
||||||
|
|
||||||
|
async def test_http_api_event(hass, hass_client, google_service, mock_events_list):
|
||||||
|
"""Test querying the API and fetching events from the server."""
|
||||||
|
now = dt_util.now()
|
||||||
|
|
||||||
|
mock_events_list(
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"summary": "Event title",
|
||||||
|
"start": {"dateTime": now.isoformat()},
|
||||||
|
"end": {
|
||||||
|
"dateTime": (now + dt_util.dt.timedelta(minutes=5)).isoformat()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert await async_setup_component(hass, "google", {"google": GOOGLE_CONFIG})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
start = (now - dt_util.dt.timedelta(minutes=60)).isoformat()
|
||||||
|
end = (now + dt_util.dt.timedelta(minutes=60)).isoformat()
|
||||||
|
|
||||||
|
client = await hass_client()
|
||||||
|
response = await client.get(f"/api/calendars/{TEST_ENTITY}?start={start}&end={end}")
|
||||||
|
assert response.status == HTTPStatus.OK
|
||||||
|
events = await response.json()
|
||||||
|
assert len(events) == 1
|
||||||
|
assert "summary" in events[0]
|
||||||
|
assert events[0]["summary"] == "Event title"
|
||||||
|
|
||||||
|
|
||||||
|
def create_ignore_avail_calendar() -> dict[str, Any]:
|
||||||
|
"""Create a calendar with ignore_availability set."""
|
||||||
|
calendar = TEST_CALENDAR.copy()
|
||||||
|
calendar["ignore_availability"] = False
|
||||||
|
return calendar
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("test_calendar", [create_ignore_avail_calendar()])
|
||||||
|
async def test_opaque_event(hass, hass_client, google_service, mock_events_list):
|
||||||
|
"""Test querying the API and fetching events from the server."""
|
||||||
|
now = dt_util.now()
|
||||||
|
|
||||||
|
mock_events_list(
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"summary": "Event title",
|
||||||
|
"transparency": "opaque",
|
||||||
|
"start": {"dateTime": now.isoformat()},
|
||||||
|
"end": {
|
||||||
|
"dateTime": (now + dt_util.dt.timedelta(minutes=5)).isoformat()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert await async_setup_component(hass, "google", {"google": GOOGLE_CONFIG})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
start = (now - dt_util.dt.timedelta(minutes=60)).isoformat()
|
||||||
|
end = (now + dt_util.dt.timedelta(minutes=60)).isoformat()
|
||||||
|
|
||||||
|
client = await hass_client()
|
||||||
|
response = await client.get(f"/api/calendars/{TEST_ENTITY}?start={start}&end={end}")
|
||||||
|
assert response.status == HTTPStatus.OK
|
||||||
|
events = await response.json()
|
||||||
|
assert len(events) == 1
|
||||||
|
assert "summary" in events[0]
|
||||||
|
assert events[0]["summary"] == "Event title"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("test_calendar", [create_ignore_avail_calendar()])
|
||||||
|
async def test_transparent_event(hass, hass_client, google_service, mock_events_list):
|
||||||
|
"""Test querying the API and fetching events from the server."""
|
||||||
|
now = dt_util.now()
|
||||||
|
|
||||||
|
mock_events_list(
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"summary": "Event title",
|
||||||
|
"transparency": "transparent",
|
||||||
|
"start": {"dateTime": now.isoformat()},
|
||||||
|
"end": {
|
||||||
|
"dateTime": (now + dt_util.dt.timedelta(minutes=5)).isoformat()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert await async_setup_component(hass, "google", {"google": GOOGLE_CONFIG})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
start = (now - dt_util.dt.timedelta(minutes=60)).isoformat()
|
||||||
|
end = (now + dt_util.dt.timedelta(minutes=60)).isoformat()
|
||||||
|
|
||||||
|
client = await hass_client()
|
||||||
|
response = await client.get(f"/api/calendars/{TEST_ENTITY}?start={start}&end={end}")
|
||||||
|
assert response.status == HTTPStatus.OK
|
||||||
|
events = await response.json()
|
||||||
|
assert events == []
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue