hass-core/tests/components/notify/test_apns.py
Martin Hjelmare 9db1aa7629 Add discovery notify support and mysensors notify (#5219)
* Add mysensors notify platform

* Make add_devices optional in platform callback function.
* Use new argument structure for all existing mysensors platforms.
* Add notify platform.
* Update mysensors gateway.

* Refactor notify setup

* Enable discovery of notify platforms.
* Update and add tests for notify component and some platforms.
* Continue setup of notify platforms if a platform fails setup.
* Remove notify tests that check platform config. These tests are not
  needed when config validation is used.
* Add config validation to APNS notify platform.
* Use discovery to set up mysensors notify platform.

* Add discovery_info to get_service and update tests

* Add discovery_info as keyword argument to the get_service function
  signature and update all notify platforms.
* Update existing notify tests to check config validation using test
  helper.
* Add removed tests back in that checked config in apns, command_line
  and file platforms, but use config validation test helper to verify
  config.
* Add a test for notify file to increase coverage.
* Fix some PEP issues.

* Fix comments and use more constants

* Move apns notify service under notify domain
2017-01-15 03:53:14 +01:00

316 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]
def test_apns_setup_full(self):
"""Test setup with all data."""
config = {
'notify': {
'platform': 'apns',
'name': 'test_app',
'sandbox': 'True',
'topic': 'testapp.appname',
'cert_file': 'test_app.pem'
}
}
self.assertTrue(notify.setup(self.hass, config))
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)