Clean caldav calendar tests (#23609)

This commit is contained in:
Martin Hjelmare 2019-05-02 09:46:12 +02:00 committed by Pascal Vizeli
parent daa1d103d4
commit 447440adc3

View File

@ -1,21 +1,16 @@
"""The tests for the webdav calendar component.""" """The tests for the webdav calendar component."""
# pylint: disable=protected-access
import datetime import datetime
import logging from unittest.mock import MagicMock, Mock
import unittest
from unittest.mock import (patch, Mock, MagicMock)
import homeassistant.components.calendar as calendar_base from asynctest import patch
import homeassistant.components.caldav.calendar as caldav
from caldav.objects import Event from caldav.objects import Event
from homeassistant.const import CONF_PLATFORM, STATE_OFF, STATE_ON import pytest
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.setup import async_setup_component
from homeassistant.util import dt from homeassistant.util import dt
from tests.common import get_test_home_assistant
TEST_PLATFORM = {calendar_base.DOMAIN: {CONF_PLATFORM: 'test'}}
_LOGGER = logging.getLogger(__name__)
# pylint: disable=redefined-outer-name
DEVICE_DATA = { DEVICE_DATA = {
"name": "Private Calendar", "name": "Private Calendar",
@ -123,18 +118,48 @@ END:VCALENDAR
] ]
CALDAV_CONFIG = {
"platform": "caldav",
"url": "http://test.local",
"custom_calendars": [],
}
@pytest.fixture(autouse=True)
def mock_http(hass):
"""Mock the http component."""
hass.http = Mock()
@pytest.fixture
def mock_dav_client():
"""Mock the dav client."""
patch_dav_client = patch(
'caldav.DAVClient', return_value=_mocked_dav_client('First', 'Second'))
with patch_dav_client as dav_client:
yield dav_client
@pytest.fixture(name='calendar')
def mock_private_cal():
"""Mock a private calendar."""
_calendar = _mock_calendar("Private")
calendars = [_calendar]
client = _mocked_dav_client(calendars=calendars)
patch_dav_client = patch('caldav.DAVClient', return_value=client)
with patch_dav_client:
yield _calendar
def _local_datetime(hours, minutes): def _local_datetime(hours, minutes):
"""Build a datetime object for testing in the correct timezone.""" """Build a datetime object for testing in the correct timezone."""
return dt.as_local(datetime.datetime(2017, 11, 27, hours, minutes, 0)) return dt.as_local(datetime.datetime(2017, 11, 27, hours, minutes, 0))
def _mocked_dav_client(*args, **kwargs): def _mocked_dav_client(*names, calendars=None):
"""Mock requests.get invocations.""" """Mock requests.get invocations."""
calendars = [ if calendars is None:
_mock_calendar("First"), calendars = [_mock_calendar(name) for name in names]
_mock_calendar("Second")
]
principal = Mock() principal = Mock()
principal.calendars = MagicMock(return_value=calendars) principal.calendars = MagicMock(return_value=calendars)
@ -154,247 +179,271 @@ def _mock_calendar(name):
return calendar return calendar
class TestComponentsWebDavCalendar(unittest.TestCase): async def test_setup_component(hass, mock_dav_client):
"""Test the WebDav calendar.""" """Test setup component with calendars."""
assert await async_setup_component(
hass, 'calendar', {'calendar': CALDAV_CONFIG})
await hass.async_block_till_done()
hass = None # HomeAssistant state = hass.states.get('calendar.first')
assert state.name == "First"
state = hass.states.get('calendar.second')
assert state.name == "Second"
# pylint: disable=invalid-name
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.hass.http = Mock()
self.calendar = _mock_calendar("Private")
# pylint: disable=invalid-name async def test_setup_component_with_no_calendar_matching(
def tearDown(self): hass, mock_dav_client):
"""Stop everything that was started.""" """Test setup component with wrong calendar."""
self.hass.stop() config = dict(CALDAV_CONFIG)
config['calendars'] = ['none']
@patch('caldav.DAVClient', side_effect=_mocked_dav_client) assert await async_setup_component(hass, 'calendar', {'calendar': config})
def test_setup_component(self, req_mock): await hass.async_block_till_done()
"""Test setup component with calendars."""
def _add_device(devices):
assert len(devices) == 2
assert devices[0].name == "First"
assert devices[0].dev_id == "First"
assert not devices[0].data.include_all_day
assert devices[1].name == "Second"
assert devices[1].dev_id == "Second"
assert not devices[1].data.include_all_day
caldav.setup_platform(self.hass, all_calendar_states = hass.states.async_entity_ids('calendar')
{ assert not all_calendar_states
"url": "http://test.local",
"custom_calendars": []
},
_add_device)
@patch('caldav.DAVClient', side_effect=_mocked_dav_client)
def test_setup_component_with_no_calendar_matching(self, req_mock):
"""Test setup component with wrong calendar."""
def _add_device(devices):
assert not devices
caldav.setup_platform(self.hass, async def test_setup_component_with_a_calendar_match(hass, mock_dav_client):
{ """Test setup component with right calendar."""
"url": "http://test.local", config = dict(CALDAV_CONFIG)
"calendars": ["none"], config['calendars'] = ['Second']
"custom_calendars": []
},
_add_device)
@patch('caldav.DAVClient', side_effect=_mocked_dav_client) assert await async_setup_component(hass, 'calendar', {'calendar': config})
def test_setup_component_with_a_calendar_match(self, req_mock): await hass.async_block_till_done()
"""Test setup component with right calendar."""
def _add_device(devices):
assert len(devices) == 1
assert devices[0].name == "Second"
caldav.setup_platform(self.hass, all_calendar_states = hass.states.async_entity_ids('calendar')
{ assert len(all_calendar_states) == 1
"url": "http://test.local", state = hass.states.get('calendar.second')
"calendars": ["Second"], assert state.name == 'Second'
"custom_calendars": []
},
_add_device)
@patch('caldav.DAVClient', side_effect=_mocked_dav_client)
def test_setup_component_with_one_custom_calendar(self, req_mock):
"""Test setup component with custom calendars."""
def _add_device(devices):
assert len(devices) == 1
assert devices[0].name == "HomeOffice"
assert devices[0].dev_id == "Second HomeOffice"
assert devices[0].data.include_all_day
caldav.setup_platform(self.hass, async def test_setup_component_with_one_custom_calendar(hass, mock_dav_client):
{ """Test setup component with custom calendars."""
"url": "http://test.local", config = dict(CALDAV_CONFIG)
"custom_calendars": [ config['custom_calendars'] = [{
{ 'name': 'HomeOffice',
"name": "HomeOffice", 'calendar': 'Second',
"calendar": "Second", 'search': 'HomeOffice',
"filter": "HomeOffice" }]
}]
},
_add_device)
@patch('homeassistant.util.dt.now', return_value=_local_datetime(17, 45)) assert await async_setup_component(hass, 'calendar', {'calendar': config})
def test_ongoing_event(self, mock_now): await hass.async_block_till_done()
"""Test that the ongoing event is returned."""
cal = caldav.WebDavCalendarEventDevice(self.hass,
DEVICE_DATA,
self.calendar)
assert cal.name == DEVICE_DATA["name"] all_calendar_states = hass.states.async_entity_ids('calendar')
assert cal.state == STATE_ON assert len(all_calendar_states) == 1
assert cal.device_state_attributes == { state = hass.states.get('calendar.second_homeoffice')
"message": "This is a normal event", assert state.name == 'HomeOffice'
"all_day": False,
"offset_reached": False,
"start_time": "2017-11-27 17:00:00",
"end_time": "2017-11-27 18:00:00",
"location": "Hamburg",
"description": "Surprisingly rainy",
}
@patch('homeassistant.util.dt.now', return_value=_local_datetime(17, 30))
def test_just_ended_event(self, mock_now):
"""Test that the next ongoing event is returned."""
cal = caldav.WebDavCalendarEventDevice(self.hass,
DEVICE_DATA,
self.calendar)
assert cal.name == DEVICE_DATA["name"] @patch('homeassistant.util.dt.now', return_value=_local_datetime(17, 45))
assert cal.state == STATE_ON async def test_ongoing_event(mock_now, hass, calendar):
assert cal.device_state_attributes == { """Test that the ongoing event is returned."""
"message": "This is a normal event", assert await async_setup_component(
"all_day": False, hass, 'calendar', {'calendar': CALDAV_CONFIG})
"offset_reached": False, await hass.async_block_till_done()
"start_time": "2017-11-27 17:00:00",
"end_time": "2017-11-27 18:00:00",
"location": "Hamburg",
"description": "Surprisingly rainy",
}
@patch('homeassistant.util.dt.now', return_value=_local_datetime(17, 00)) state = hass.states.get('calendar.private')
def test_ongoing_event_different_tz(self, mock_now): assert state.name == calendar.name
"""Test that the ongoing event with another timezone is returned.""" assert state.state == STATE_ON
cal = caldav.WebDavCalendarEventDevice(self.hass, assert dict(state.attributes) == {
DEVICE_DATA, "friendly_name": "Private",
self.calendar) "message": "This is a normal event",
"all_day": False,
'offset_reached': False,
"start_time": "2017-11-27 17:00:00",
"end_time": "2017-11-27 18:00:00",
"location": "Hamburg",
"description": "Surprisingly rainy",
}
assert cal.name == DEVICE_DATA["name"]
assert cal.state == STATE_ON
assert cal.device_state_attributes == {
"message": "Enjoy the sun",
"all_day": False,
"offset_reached": False,
"start_time": "2017-11-27 16:30:00",
"description": "Sunny day",
"end_time": "2017-11-27 17:30:00",
"location": "San Francisco",
}
@patch('homeassistant.util.dt.now', return_value=_local_datetime(8, 30)) @patch('homeassistant.util.dt.now', return_value=_local_datetime(17, 30))
def test_ongoing_event_with_offset(self, mock_now): async def test_just_ended_event(mock_now, hass, calendar):
"""Test that the offset is taken into account.""" """Test that the next ongoing event is returned."""
cal = caldav.WebDavCalendarEventDevice(self.hass, assert await async_setup_component(
DEVICE_DATA, hass, 'calendar', {'calendar': CALDAV_CONFIG})
self.calendar) await hass.async_block_till_done()
assert cal.state == STATE_OFF state = hass.states.get('calendar.private')
assert cal.device_state_attributes == { assert state.name == calendar.name
"message": "This is an offset event", assert state.state == STATE_ON
"all_day": False, assert dict(state.attributes) == {
"offset_reached": True, "friendly_name": "Private",
"start_time": "2017-11-27 10:00:00", "message": "This is a normal event",
"end_time": "2017-11-27 11:00:00", "all_day": False,
"location": "Hamburg", "offset_reached": False,
"description": "Surprisingly shiny", "start_time": "2017-11-27 17:00:00",
} "end_time": "2017-11-27 18:00:00",
"location": "Hamburg",
"description": "Surprisingly rainy",
}
@patch('homeassistant.util.dt.now', return_value=_local_datetime(12, 00))
def test_matching_filter(self, mock_now):
"""Test that the matching event is returned."""
cal = caldav.WebDavCalendarEventDevice(self.hass,
DEVICE_DATA,
self.calendar,
False,
"This is a normal event")
assert cal.state == STATE_OFF @patch('homeassistant.util.dt.now', return_value=_local_datetime(17, 00))
assert not cal.offset_reached() async def test_ongoing_event_different_tz(mock_now, hass, calendar):
assert cal.device_state_attributes == { """Test that the ongoing event with another timezone is returned."""
"message": "This is a normal event", assert await async_setup_component(
"all_day": False, hass, 'calendar', {'calendar': CALDAV_CONFIG})
"offset_reached": False, await hass.async_block_till_done()
"start_time": "2017-11-27 17:00:00",
"end_time": "2017-11-27 18:00:00",
"location": "Hamburg",
"description": "Surprisingly rainy",
}
@patch('homeassistant.util.dt.now', return_value=_local_datetime(12, 00)) state = hass.states.get('calendar.private')
def test_matching_filter_real_regexp(self, mock_now): assert state.name == calendar.name
"""Test that the event matching the regexp is returned.""" assert state.state == STATE_ON
cal = caldav.WebDavCalendarEventDevice(self.hass, assert dict(state.attributes) == {
DEVICE_DATA, "friendly_name": "Private",
self.calendar, "message": "Enjoy the sun",
False, "all_day": False,
"^This.*event") "offset_reached": False,
"start_time": "2017-11-27 16:30:00",
"description": "Sunny day",
"end_time": "2017-11-27 17:30:00",
"location": "San Francisco",
}
assert cal.state == STATE_OFF
assert not cal.offset_reached()
assert cal.device_state_attributes == {
"message": "This is a normal event",
"all_day": False,
"offset_reached": False,
"start_time": "2017-11-27 17:00:00",
"end_time": "2017-11-27 18:00:00",
"location": "Hamburg",
"description": "Surprisingly rainy",
}
@patch('homeassistant.util.dt.now', return_value=_local_datetime(20, 00)) @patch('homeassistant.util.dt.now', return_value=_local_datetime(8, 30))
def test_filter_matching_past_event(self, mock_now): async def test_ongoing_event_with_offset(mock_now, hass, calendar):
"""Test that the matching past event is not returned.""" """Test that the offset is taken into account."""
cal = caldav.WebDavCalendarEventDevice(self.hass, assert await async_setup_component(
DEVICE_DATA, hass, 'calendar', {'calendar': CALDAV_CONFIG})
self.calendar, await hass.async_block_till_done()
False,
"This is a normal event")
assert cal.data.event is None state = hass.states.get('calendar.private')
assert state.name == calendar.name
assert state.state == STATE_OFF
assert dict(state.attributes) == {
"friendly_name": "Private",
"message": "This is an offset event",
"all_day": False,
"offset_reached": True,
"start_time": "2017-11-27 10:00:00",
"end_time": "2017-11-27 11:00:00",
"location": "Hamburg",
"description": "Surprisingly shiny",
}
@patch('homeassistant.util.dt.now', return_value=_local_datetime(12, 00))
def test_no_result_with_filtering(self, mock_now):
"""Test that nothing is returned since nothing matches."""
cal = caldav.WebDavCalendarEventDevice(self.hass,
DEVICE_DATA,
self.calendar,
False,
"This is a non-existing event")
assert cal.data.event is None @patch('homeassistant.util.dt.now', return_value=_local_datetime(12, 00))
async def test_matching_filter(mock_now, hass, calendar):
"""Test that the matching event is returned."""
config = dict(CALDAV_CONFIG)
config['custom_calendars'] = [{
'name': 'Private',
'calendar': 'Private',
'search': 'This is a normal event',
}]
@patch('homeassistant.util.dt.now', return_value=_local_datetime(17, 30)) assert await async_setup_component(
def test_all_day_event_returned(self, mock_now): hass, 'calendar', {'calendar': config})
"""Test that the event lasting the whole day is returned.""" await hass.async_block_till_done()
cal = caldav.WebDavCalendarEventDevice(self.hass,
DEVICE_DATA,
self.calendar,
True)
assert cal.name == DEVICE_DATA["name"] state = hass.states.get('calendar.private_private')
assert cal.state == STATE_ON assert state.name == calendar.name
assert cal.device_state_attributes == { assert state.state == STATE_OFF
"message": "This is an all day event", assert dict(state.attributes) == {
"all_day": True, "friendly_name": "Private",
"offset_reached": False, "message": "This is a normal event",
"start_time": "2017-11-27 00:00:00", "all_day": False,
"end_time": "2017-11-28 00:00:00", "offset_reached": False,
"location": "Hamburg", "start_time": "2017-11-27 17:00:00",
"description": "What a beautiful day", "end_time": "2017-11-27 18:00:00",
} "location": "Hamburg",
"description": "Surprisingly rainy",
}
@patch('homeassistant.util.dt.now', return_value=_local_datetime(12, 00))
async def test_matching_filter_real_regexp(mock_now, hass, calendar):
"""Test that the event matching the regexp is returned."""
config = dict(CALDAV_CONFIG)
config['custom_calendars'] = [{
'name': 'Private',
'calendar': 'Private',
'search': r'.*rainy',
}]
assert await async_setup_component(
hass, 'calendar', {'calendar': config})
await hass.async_block_till_done()
state = hass.states.get('calendar.private_private')
assert state.name == calendar.name
assert state.state == STATE_OFF
assert dict(state.attributes) == {
"friendly_name": "Private",
"message": "This is a normal event",
"all_day": False,
"offset_reached": False,
"start_time": "2017-11-27 17:00:00",
"end_time": "2017-11-27 18:00:00",
"location": "Hamburg",
"description": "Surprisingly rainy",
}
@patch('homeassistant.util.dt.now', return_value=_local_datetime(20, 00))
async def test_filter_matching_past_event(mock_now, hass, calendar):
"""Test that the matching past event is not returned."""
config = dict(CALDAV_CONFIG)
config['custom_calendars'] = [{
'name': 'Private',
'calendar': 'Private',
'search': 'This is a normal event',
}]
assert await async_setup_component(
hass, 'calendar', {'calendar': config})
await hass.async_block_till_done()
state = hass.states.get('calendar.private_private')
assert state.name == calendar.name
assert state.state == 'off'
@patch('homeassistant.util.dt.now', return_value=_local_datetime(12, 00))
async def test_no_result_with_filtering(mock_now, hass, calendar):
"""Test that nothing is returned since nothing matches."""
config = dict(CALDAV_CONFIG)
config['custom_calendars'] = [{
'name': 'Private',
'calendar': 'Private',
'search': 'This is a non-existing event',
}]
assert await async_setup_component(
hass, 'calendar', {'calendar': config})
await hass.async_block_till_done()
state = hass.states.get('calendar.private_private')
assert state.name == calendar.name
assert state.state == 'off'
@patch('homeassistant.util.dt.now', return_value=_local_datetime(17, 30))
async def test_all_day_event_returned(mock_now, hass, calendar):
"""Test that the event lasting the whole day is returned."""
config = dict(CALDAV_CONFIG)
config['custom_calendars'] = [{
'name': 'Private',
'calendar': 'Private',
'search': '.*',
}]
assert await async_setup_component(
hass, 'calendar', {'calendar': config})
await hass.async_block_till_done()
state = hass.states.get('calendar.private_private')
assert state.name == calendar.name
assert state.state == STATE_ON
assert dict(state.attributes) == {
"friendly_name": "Private",
"message": "This is an all day event",
"all_day": True,
"offset_reached": False,
"start_time": "2017-11-27 00:00:00",
"end_time": "2017-11-28 00:00:00",
"location": "Hamburg",
"description": "What a beautiful day",
}