core/tests/components/notify/test_apns.py

321 lines
11 KiB
Python

"""The tests for the APNS component."""
import os
import unittest
from unittest.mock import patch
from unittest.mock import Mock
from apns2.errors import Unregistered
import homeassistant.components.notify as notify
from homeassistant.bootstrap import setup_component
from homeassistant.components.notify.apns import ApnsNotificationService
from homeassistant.config import load_yaml_config_file
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."""
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):
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]
def test_register_new_device(self):
"""Test registering a new device with a name."""
devices_path = self.hass.config.path('test_app_apns.yaml')
with open(devices_path, 'w+') as out:
out.write('5678: {name: test device 2}\n')
self._setup_notify()
self.assertTrue(self.hass.services.call(notify.DOMAIN,
'apns_test_app',
{'push_id': '1234',
'name': 'test device'},
blocking=True))
devices = {str(key): value for (key, value) in
load_yaml_config_file(devices_path).items()}
test_device_1 = devices.get('1234')
test_device_2 = devices.get('5678')
self.assertIsNotNone(test_device_1)
self.assertIsNotNone(test_device_2)
self.assertEqual('test device', test_device_1.get('name'))
os.remove(devices_path)
def test_register_device_without_name(self):
"""Test registering a without a name."""
devices_path = self.hass.config.path('test_app_apns.yaml')
with open(devices_path, 'w+') as out:
out.write('5678: {name: test device 2}\n')
self._setup_notify()
self.assertTrue(self.hass.services.call(notify.DOMAIN, 'apns_test_app',
{'push_id': '1234'},
blocking=True))
devices = {str(key): value for (key, value) in
load_yaml_config_file(devices_path).items()}
test_device = devices.get('1234')
self.assertIsNotNone(test_device)
self.assertIsNone(test_device.get('name'))
os.remove(devices_path)
def test_update_existing_device(self):
"""Test updating an existing device."""
devices_path = self.hass.config.path('test_app_apns.yaml')
with open(devices_path, 'w+') as out:
out.write('1234: {name: test device 1}\n')
out.write('5678: {name: test device 2}\n')
self._setup_notify()
self.assertTrue(self.hass.services.call(notify.DOMAIN,
'apns_test_app',
{'push_id': '1234',
'name': 'updated device 1'},
blocking=True))
devices = {str(key): value for (key, value) in
load_yaml_config_file(devices_path).items()}
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.get('name'))
os.remove(devices_path)
def test_update_existing_device_with_tracking_id(self):
"""Test updating an existing device that has a tracking id."""
devices_path = self.hass.config.path('test_app_apns.yaml')
with open(devices_path, 'w+') as out:
out.write('1234: {name: test device 1, '
'tracking_device_id: tracking123}\n')
out.write('5678: {name: test device 2, '
'tracking_device_id: tracking456}\n')
self._setup_notify()
self.assertTrue(self.hass.services.call(notify.DOMAIN,
'apns_test_app',
{'push_id': '1234',
'name': 'updated device 1'},
blocking=True))
devices = {str(key): value for (key, value) in
load_yaml_config_file(devices_path).items()}
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.get('tracking_device_id'))
self.assertEqual('tracking456',
test_device_2.get('tracking_device_id'))
os.remove(devices_path)
@patch('apns2.client.APNsClient')
def test_send(self, mock_client):
"""Test updating an existing device."""
send = mock_client.return_value.send_notification
devices_path = self.hass.config.path('test_app_apns.yaml')
with open(devices_path, 'w+') as out:
out.write('1234: {name: test device 1}\n')
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
devices_path = self.hass.config.path('test_app_apns.yaml')
with open(devices_path, 'w+') as out:
out.write('1234: {name: test device 1, disabled: True}\n')
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
devices_path = self.hass.config.path('test_app_apns.yaml')
with open(devices_path, 'w+') as out:
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 = ApnsNotificationService(
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'))
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')
def test_disable_when_unregistered(self, mock_client):
"""Test disabling a device when it is unregistered."""
send = mock_client.return_value.send_notification
send.side_effect = Unregistered()
devices_path = self.hass.config.path('test_app_apns.yaml')
with open(devices_path, 'w+') as out:
out.write('1234: {name: test device 1}\n')
self._setup_notify()
self.assertTrue(self.hass.services.call('notify', 'test_app',
{'message': 'Hello'},
blocking=True))
devices = {str(key): value for (key, value) in
load_yaml_config_file(devices_path).items()}
test_device_1 = devices.get('1234')
self.assertIsNotNone(test_device_1)
self.assertEqual(True, test_device_1.get('disabled'))
os.remove(devices_path)