core/tests/components/notify/test_apns.py

407 lines
13 KiB
Python
Raw Normal View History

"""The tests for the APNS component."""
import io
import unittest
from unittest.mock import Mock, patch
from apns2.errors import Unregistered
import yaml
import homeassistant.components.notify as notify
from homeassistant.bootstrap import setup_component
from homeassistant.components.notify import apns
from homeassistant.core import State
from tests.common import assert_setup_component, get_test_home_assistant
CONFIG = {
notify.DOMAIN: {
'platform': 'apns',
'name': 'test_app',
'topic': 'testapp.appname',
'cert_file': 'test_app.pem'
}
}
class TestApns(unittest.TestCase):
"""Test the APNS component."""
2017-01-07 00:47:25 +00:00
def setUp(self): # pylint: disable=invalid-name
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
def tearDown(self): # pylint: disable=invalid-name
"""Stop everything that was started."""
self.hass.stop()
@patch('os.path.isfile', Mock(return_value=True))
@patch('os.access', Mock(return_value=True))
def _setup_notify(self):
assert isinstance(apns.load_yaml_config_file, Mock), \
'Found unmocked load_yaml'
with assert_setup_component(1) as handle_config:
assert setup_component(self.hass, notify.DOMAIN, CONFIG)
assert handle_config[notify.DOMAIN]
@patch('os.path.isfile', return_value=True)
@patch('os.access', return_value=True)
def test_apns_setup_full(self, mock_access, mock_isfile):
"""Test setup with all data."""
config = {
'notify': {
'platform': 'apns',
'name': 'test_app',
'sandbox': 'True',
'topic': 'testapp.appname',
'cert_file': 'test_app.pem'
}
}
with assert_setup_component(1) as handle_config:
assert setup_component(self.hass, notify.DOMAIN, config)
assert handle_config[notify.DOMAIN]
def test_apns_setup_missing_name(self):
"""Test setup with missing name."""
config = {
'notify': {
'platform': 'apns',
'topic': 'testapp.appname',
'cert_file': 'test_app.pem',
}
}
with assert_setup_component(0) as handle_config:
assert setup_component(self.hass, notify.DOMAIN, config)
assert not handle_config[notify.DOMAIN]
def test_apns_setup_missing_certificate(self):
"""Test setup with missing certificate."""
config = {
'notify': {
'platform': 'apns',
'name': 'test_app',
'topic': 'testapp.appname',
}
}
with assert_setup_component(0) as handle_config:
assert setup_component(self.hass, notify.DOMAIN, config)
assert not handle_config[notify.DOMAIN]
def test_apns_setup_missing_topic(self):
"""Test setup with missing topic."""
config = {
'notify': {
'platform': 'apns',
'name': 'test_app',
'cert_file': 'test_app.pem',
}
}
with assert_setup_component(0) as handle_config:
assert setup_component(self.hass, notify.DOMAIN, config)
assert not handle_config[notify.DOMAIN]
@patch('homeassistant.components.notify.apns._write_device')
def test_register_new_device(self, mock_write):
"""Test registering a new device with a name."""
yaml_file = {5678: {'name': 'test device 2'}}
written_devices = []
def fake_write(_out, device):
"""Fake write_device."""
written_devices.append(device)
mock_write.side_effect = fake_write
with patch(
'homeassistant.components.notify.apns.load_yaml_config_file',
Mock(return_value=yaml_file)):
self._setup_notify()
self.assertTrue(self.hass.services.call(notify.DOMAIN,
'apns_test_app',
2017-01-07 00:47:25 +00:00
{'push_id': '1234',
'name': 'test device'},
blocking=True))
assert len(written_devices) == 1
assert written_devices[0].name == 'test device'
@patch('homeassistant.components.notify.apns._write_device')
def test_register_device_without_name(self, mock_write):
"""Test registering a without a name."""
yaml_file = {
1234: {
'name': 'test device 1',
'tracking_device_id': 'tracking123',
},
5678: {
'name': 'test device 2',
'tracking_device_id': 'tracking456',
},
}
written_devices = []
def fake_write(_out, device):
"""Fake write_device."""
written_devices.append(device)
mock_write.side_effect = fake_write
with patch(
'homeassistant.components.notify.apns.load_yaml_config_file',
Mock(return_value=yaml_file)):
self._setup_notify()
self.assertTrue(self.hass.services.call(notify.DOMAIN, 'apns_test_app',
2017-01-07 00:47:25 +00:00
{'push_id': '1234'},
blocking=True))
devices = {dev.push_id: dev for dev in written_devices}
test_device = devices.get('1234')
self.assertIsNotNone(test_device)
self.assertIsNone(test_device.name)
@patch('homeassistant.components.notify.apns._write_device')
def test_update_existing_device(self, mock_write):
"""Test updating an existing device."""
yaml_file = {
1234: {
'name': 'test device 1',
},
5678: {
'name': 'test device 2',
},
}
written_devices = []
def fake_write(_out, device):
"""Fake write_device."""
written_devices.append(device)
mock_write.side_effect = fake_write
with patch(
'homeassistant.components.notify.apns.load_yaml_config_file',
Mock(return_value=yaml_file)):
self._setup_notify()
self.assertTrue(self.hass.services.call(notify.DOMAIN,
'apns_test_app',
2017-01-07 00:47:25 +00:00
{'push_id': '1234',
'name': 'updated device 1'},
blocking=True))
devices = {dev.push_id: dev for dev in written_devices}
test_device_1 = devices.get('1234')
test_device_2 = devices.get('5678')
self.assertIsNotNone(test_device_1)
self.assertIsNotNone(test_device_2)
self.assertEqual('updated device 1', test_device_1.name)
@patch('homeassistant.components.notify.apns._write_device')
def test_update_existing_device_with_tracking_id(self, mock_write):
"""Test updating an existing device that has a tracking id."""
yaml_file = {
1234: {
'name': 'test device 1',
'tracking_device_id': 'tracking123',
},
5678: {
'name': 'test device 2',
'tracking_device_id': 'tracking456',
},
}
written_devices = []
def fake_write(_out, device):
"""Fake write_device."""
written_devices.append(device)
mock_write.side_effect = fake_write
with patch(
'homeassistant.components.notify.apns.load_yaml_config_file',
Mock(return_value=yaml_file)):
self._setup_notify()
self.assertTrue(self.hass.services.call(notify.DOMAIN,
'apns_test_app',
2017-01-07 00:47:25 +00:00
{'push_id': '1234',
'name': 'updated device 1'},
blocking=True))
devices = {dev.push_id: dev for dev in written_devices}
test_device_1 = devices.get('1234')
test_device_2 = devices.get('5678')
self.assertIsNotNone(test_device_1)
self.assertIsNotNone(test_device_2)
self.assertEqual('tracking123',
test_device_1.tracking_device_id)
self.assertEqual('tracking456',
test_device_2.tracking_device_id)
@patch('apns2.client.APNsClient')
def test_send(self, mock_client):
"""Test updating an existing device."""
send = mock_client.return_value.send_notification
yaml_file = {1234: {'name': 'test device 1'}}
with patch(
'homeassistant.components.notify.apns.load_yaml_config_file',
Mock(return_value=yaml_file)):
self._setup_notify()
self.assertTrue(self.hass.services.call(
'notify', 'test_app',
{'message': 'Hello', 'data': {
'badge': 1,
'sound': 'test.mp3',
'category': 'testing'}},
blocking=True))
self.assertTrue(send.called)
self.assertEqual(1, len(send.mock_calls))
target = send.mock_calls[0][1][0]
payload = send.mock_calls[0][1][1]
self.assertEqual('1234', target)
self.assertEqual('Hello', payload.alert)
self.assertEqual(1, payload.badge)
self.assertEqual('test.mp3', payload.sound)
self.assertEqual('testing', payload.category)
@patch('apns2.client.APNsClient')
def test_send_when_disabled(self, mock_client):
"""Test updating an existing device."""
send = mock_client.return_value.send_notification
yaml_file = {1234: {
'name': 'test device 1',
'disabled': True,
}}
with patch(
'homeassistant.components.notify.apns.load_yaml_config_file',
Mock(return_value=yaml_file)):
self._setup_notify()
self.assertTrue(self.hass.services.call(
'notify', 'test_app',
{'message': 'Hello', 'data': {
'badge': 1,
'sound': 'test.mp3',
'category': 'testing'}},
blocking=True))
self.assertFalse(send.called)
@patch('apns2.client.APNsClient')
def test_send_with_state(self, mock_client):
"""Test updating an existing device."""
send = mock_client.return_value.send_notification
2017-01-07 00:47:25 +00:00
devices_path = self.hass.config.path('test_app_apns.yaml')
with open(devices_path, 'w+') as out:
2016-11-19 05:47:59 +00:00
out.write('1234: {name: test device 1, '
'tracking_device_id: tracking123}\n')
out.write('5678: {name: test device 2, '
'tracking_device_id: tracking456}\n')
notify_service = apns.ApnsNotificationService(
2017-01-07 00:47:25 +00:00
self.hass,
'test_app',
'testapp.appname',
False,
'test_app.pem'
)
notify_service.device_state_changed_listener(
'device_tracker.tracking456',
State('device_tracker.tracking456', None),
State('device_tracker.tracking456', 'home'))
2017-01-07 00:47:25 +00:00
self.hass.block_till_done()
notify_service.send_message(message='Hello', target='home')
self.assertTrue(send.called)
self.assertEqual(1, len(send.mock_calls))
target = send.mock_calls[0][1][0]
payload = send.mock_calls[0][1][1]
self.assertEqual('5678', target)
self.assertEqual('Hello', payload.alert)
@patch('apns2.client.APNsClient')
@patch('homeassistant.components.notify.apns._write_device')
def test_disable_when_unregistered(self, mock_write, mock_client):
"""Test disabling a device when it is unregistered."""
send = mock_client.return_value.send_notification
send.side_effect = Unregistered()
yaml_file = {
1234: {
'name': 'test device 1',
'tracking_device_id': 'tracking123',
},
5678: {
'name': 'test device 2',
'tracking_device_id': 'tracking456',
},
}
written_devices = []
def fake_write(_out, device):
"""Fake write_device."""
written_devices.append(device)
mock_write.side_effect = fake_write
with patch(
'homeassistant.components.notify.apns.load_yaml_config_file',
Mock(return_value=yaml_file)):
self._setup_notify()
2017-01-07 00:47:25 +00:00
self.assertTrue(self.hass.services.call('notify', 'test_app',
{'message': 'Hello'},
blocking=True))
devices = {dev.push_id: dev for dev in written_devices}
test_device_1 = devices.get('1234')
self.assertIsNotNone(test_device_1)
self.assertEqual(True, test_device_1.disabled)
def test_write_device():
"""Test writing device."""
out = io.StringIO()
device = apns.ApnsDevice('123', 'name', 'track_id', True)
apns._write_device(out, device)
data = yaml.load(out.getvalue())
assert data == {
123: {
'name': 'name',
'tracking_device_id': 'track_id',
'disabled': True
},
}