Rewrite APNS tests to use pytest (#41684)

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
Edward Knight 2020-10-16 12:43:02 +01:00 committed by GitHub
parent 11d2e0c671
commit b39d82c154
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,17 +1,17 @@
"""The tests for the APNS component.""" """The tests for the APNS component."""
import io import io
import unittest
from apns2.errors import Unregistered from apns2.errors import Unregistered
import pytest
import yaml import yaml
import homeassistant.components.apns.notify as apns import homeassistant.components.apns.notify as apns
import homeassistant.components.notify as notify import homeassistant.components.notify as notify
from homeassistant.core import State from homeassistant.core import State
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
from tests.async_mock import Mock, mock_open, patch from tests.async_mock import Mock, mock_open, patch
from tests.common import assert_setup_component, get_test_home_assistant from tests.common import assert_setup_component
CONFIG = { CONFIG = {
notify.DOMAIN: { notify.DOMAIN: {
@ -23,356 +23,367 @@ CONFIG = {
} }
@patch("homeassistant.components.apns.notify.open", mock_open(), create=True) @pytest.fixture(scope="module", autouse=True)
class TestApns(unittest.TestCase): def mock_apns_notify_open():
"""Test the APNS component.""" """Mock builtins.open for apns.notfiy."""
with patch("homeassistant.components.apns.notify.open", mock_open(), create=True):
yield
def setUp(self): # pylint: disable=invalid-name
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.addCleanup(self.tear_down_cleanup)
def tear_down_cleanup(self): @patch("os.path.isfile", Mock(return_value=True))
"""Stop everything that was started.""" @patch("os.access", Mock(return_value=True))
self.hass.stop() async def _setup_notify(hass_):
assert isinstance(apns.load_yaml_config_file, Mock), "Found unmocked load_yaml"
@patch("os.path.isfile", Mock(return_value=True)) with assert_setup_component(1) as handle_config:
@patch("os.access", Mock(return_value=True)) assert await async_setup_component(hass_, notify.DOMAIN, CONFIG)
def _setup_notify(self): assert handle_config[notify.DOMAIN]
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.path.isfile", return_value=True)
@patch("os.access", return_value=True) @patch("os.access", return_value=True)
def test_apns_setup_full(self, mock_access, mock_isfile): async def test_apns_setup_full(mock_access, mock_isfile, hass):
"""Test setup with all data.""" """Test setup with all data."""
config = { config = {
"notify": { "notify": {
"platform": "apns", "platform": "apns",
"name": "test_app", "name": "test_app",
"sandbox": "True", "sandbox": "True",
"topic": "testapp.appname", "topic": "testapp.appname",
"cert_file": "test_app.pem", "cert_file": "test_app.pem",
}
} }
}
with assert_setup_component(1) as handle_config: with assert_setup_component(1) as handle_config:
assert setup_component(self.hass, notify.DOMAIN, config) assert await async_setup_component(hass, notify.DOMAIN, config)
assert handle_config[notify.DOMAIN] assert handle_config[notify.DOMAIN]
def test_apns_setup_missing_name(self):
"""Test setup with missing name.""" async def test_apns_setup_missing_name(hass):
config = { """Test setup with missing name."""
"notify": { config = {
"platform": "apns", "notify": {
"topic": "testapp.appname", "platform": "apns",
"cert_file": "test_app.pem", "topic": "testapp.appname",
} "cert_file": "test_app.pem",
} }
with assert_setup_component(0) as handle_config: }
assert setup_component(self.hass, notify.DOMAIN, config) with assert_setup_component(0) as handle_config:
assert not handle_config[notify.DOMAIN] assert await async_setup_component(hass, notify.DOMAIN, config)
assert not handle_config[notify.DOMAIN]
def test_apns_setup_missing_certificate(self):
"""Test setup with missing certificate.""" async def test_apns_setup_missing_certificate(hass):
config = { """Test setup with missing certificate."""
"notify": { config = {
"platform": "apns", "notify": {
"name": "test_app", "platform": "apns",
"topic": "testapp.appname", "name": "test_app",
} "topic": "testapp.appname",
} }
with assert_setup_component(0) as handle_config: }
assert setup_component(self.hass, notify.DOMAIN, config) with assert_setup_component(0) as handle_config:
assert not handle_config[notify.DOMAIN] assert await async_setup_component(hass, notify.DOMAIN, config)
assert not handle_config[notify.DOMAIN]
def test_apns_setup_missing_topic(self):
"""Test setup with missing topic.""" async def test_apns_setup_missing_topic(hass):
config = { """Test setup with missing topic."""
"notify": { config = {
"platform": "apns", "notify": {
"name": "test_app", "platform": "apns",
"cert_file": "test_app.pem", "name": "test_app",
} "cert_file": "test_app.pem",
} }
with assert_setup_component(0) as handle_config: }
assert setup_component(self.hass, notify.DOMAIN, config) with assert_setup_component(0) as handle_config:
assert not handle_config[notify.DOMAIN] assert await async_setup_component(hass, notify.DOMAIN, config)
assert not handle_config[notify.DOMAIN]
@patch("homeassistant.components.apns.notify._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 = [] @patch("homeassistant.components.apns.notify._write_device")
async def test_register_new_device(mock_write, hass):
"""Test registering a new device with a name."""
yaml_file = {5678: {"name": "test device 2"}}
def fake_write(_out, device): written_devices = []
"""Fake write_device."""
written_devices.append(device)
mock_write.side_effect = fake_write def fake_write(_out, device):
"""Fake write_device."""
written_devices.append(device)
with patch( mock_write.side_effect = fake_write
"homeassistant.components.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
self._setup_notify()
assert self.hass.services.call( with patch(
apns.DOMAIN, "homeassistant.components.apns.notify.load_yaml_config_file",
"apns_test_app", Mock(return_value=yaml_file),
{"push_id": "1234", "name": "test device"}, ):
blocking=True, await _setup_notify(hass)
)
assert len(written_devices) == 1 assert await hass.services.async_call(
assert written_devices[0].name == "test device" apns.DOMAIN,
"apns_test_app",
{"push_id": "1234", "name": "test device"},
blocking=True,
)
@patch("homeassistant.components.apns.notify._write_device") assert len(written_devices) == 1
def test_register_device_without_name(self, mock_write): assert written_devices[0].name == "test device"
"""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): @patch("homeassistant.components.apns.notify._write_device")
"""Fake write_device.""" async def test_register_device_without_name(mock_write, hass):
written_devices.append(device) """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"},
}
mock_write.side_effect = fake_write written_devices = []
with patch( def fake_write(_out, device):
"homeassistant.components.apns.notify.load_yaml_config_file", """Fake write_device."""
Mock(return_value=yaml_file), written_devices.append(device)
):
self._setup_notify()
assert self.hass.services.call( mock_write.side_effect = fake_write
apns.DOMAIN, "apns_test_app", {"push_id": "1234"}, blocking=True
)
devices = {dev.push_id: dev for dev in written_devices} with patch(
"homeassistant.components.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
await _setup_notify(hass)
test_device = devices.get("1234") assert await hass.services.async_call(
apns.DOMAIN, "apns_test_app", {"push_id": "1234"}, blocking=True
)
assert test_device is not None devices = {dev.push_id: dev for dev in written_devices}
assert test_device.name is None
@patch("homeassistant.components.apns.notify._write_device") test_device = devices.get("1234")
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 = [] assert test_device is not None
assert test_device.name is None
def fake_write(_out, device):
"""Fake write_device."""
written_devices.append(device)
mock_write.side_effect = fake_write @patch("homeassistant.components.apns.notify._write_device")
async def test_update_existing_device(mock_write, hass):
"""Test updating an existing device."""
yaml_file = {1234: {"name": "test device 1"}, 5678: {"name": "test device 2"}}
with patch( written_devices = []
"homeassistant.components.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
self._setup_notify()
assert self.hass.services.call( def fake_write(_out, device):
apns.DOMAIN, """Fake write_device."""
"apns_test_app", written_devices.append(device)
{"push_id": "1234", "name": "updated device 1"},
blocking=True,
)
devices = {dev.push_id: dev for dev in written_devices} mock_write.side_effect = fake_write
test_device_1 = devices.get("1234") with patch(
test_device_2 = devices.get("5678") "homeassistant.components.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
await _setup_notify(hass)
assert test_device_1 is not None assert await hass.services.async_call(
assert test_device_2 is not None apns.DOMAIN,
"apns_test_app",
{"push_id": "1234", "name": "updated device 1"},
blocking=True,
)
assert "updated device 1" == test_device_1.name devices = {dev.push_id: dev for dev in written_devices}
@patch("homeassistant.components.apns.notify._write_device") test_device_1 = devices.get("1234")
def test_update_existing_device_with_tracking_id(self, mock_write): test_device_2 = devices.get("5678")
"""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 = [] assert test_device_1 is not None
assert test_device_2 is not None
def fake_write(_out, device): assert "updated device 1" == test_device_1.name
"""Fake write_device."""
written_devices.append(device)
mock_write.side_effect = fake_write
with patch( @patch("homeassistant.components.apns.notify._write_device")
"homeassistant.components.apns.notify.load_yaml_config_file", async def test_update_existing_device_with_tracking_id(mock_write, hass):
Mock(return_value=yaml_file), """Test updating an existing device that has a tracking id."""
): yaml_file = {
self._setup_notify() 1234: {"name": "test device 1", "tracking_device_id": "tracking123"},
5678: {"name": "test device 2", "tracking_device_id": "tracking456"},
}
assert self.hass.services.call( written_devices = []
apns.DOMAIN,
"apns_test_app",
{"push_id": "1234", "name": "updated device 1"},
blocking=True,
)
devices = {dev.push_id: dev for dev in written_devices} def fake_write(_out, device):
"""Fake write_device."""
written_devices.append(device)
test_device_1 = devices.get("1234") mock_write.side_effect = fake_write
test_device_2 = devices.get("5678")
assert test_device_1 is not None with patch(
assert test_device_2 is not None "homeassistant.components.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
await _setup_notify(hass)
assert "tracking123" == test_device_1.tracking_device_id assert await hass.services.async_call(
assert "tracking456" == test_device_2.tracking_device_id apns.DOMAIN,
"apns_test_app",
{"push_id": "1234", "name": "updated device 1"},
blocking=True,
)
@patch("homeassistant.components.apns.notify.APNsClient") devices = {dev.push_id: dev for dev in written_devices}
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"}} test_device_1 = devices.get("1234")
test_device_2 = devices.get("5678")
with patch( assert test_device_1 is not None
"homeassistant.components.apns.notify.load_yaml_config_file", assert test_device_2 is not None
Mock(return_value=yaml_file),
):
self._setup_notify()
assert self.hass.services.call( assert "tracking123" == test_device_1.tracking_device_id
"notify", assert "tracking456" == test_device_2.tracking_device_id
@patch("homeassistant.components.apns.notify.APNsClient")
async def test_send(mock_client, hass):
"""Test updating an existing device."""
send = mock_client.return_value.send_notification
yaml_file = {1234: {"name": "test device 1"}}
with patch(
"homeassistant.components.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
await _setup_notify(hass)
assert await hass.services.async_call(
"notify",
"test_app",
{
"message": "Hello",
"data": {"badge": 1, "sound": "test.mp3", "category": "testing"},
},
blocking=True,
)
assert send.called
assert 1 == len(send.mock_calls)
target = send.mock_calls[0][1][0]
payload = send.mock_calls[0][1][1]
assert "1234" == target
assert "Hello" == payload.alert
assert 1 == payload.badge
assert "test.mp3" == payload.sound
assert "testing" == payload.category
@patch("homeassistant.components.apns.notify.APNsClient")
async def test_send_when_disabled(mock_client, hass):
"""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.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
await _setup_notify(hass)
assert await hass.services.async_call(
"notify",
"test_app",
{
"message": "Hello",
"data": {"badge": 1, "sound": "test.mp3", "category": "testing"},
},
blocking=True,
)
assert not send.called
@patch("homeassistant.components.apns.notify.APNsClient")
async def test_send_with_state(mock_client, hass):
"""Test updating an existing device."""
send = mock_client.return_value.send_notification
yaml_file = {
1234: {"name": "test device 1", "tracking_device_id": "tracking123"},
5678: {"name": "test device 2", "tracking_device_id": "tracking456"},
}
with patch(
"homeassistant.components.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
), patch("os.path.isfile", Mock(return_value=True)):
notify_service = await hass.async_add_executor_job(
apns.ApnsNotificationService,
hass,
"test_app", "test_app",
{ "testapp.appname",
"message": "Hello", False,
"data": {"badge": 1, "sound": "test.mp3", "category": "testing"}, "test_app.pem",
},
blocking=True,
) )
assert send.called notify_service.device_state_changed_listener(
assert 1 == len(send.mock_calls) "device_tracker.tracking456",
State("device_tracker.tracking456", None),
State("device_tracker.tracking456", "home"),
)
target = send.mock_calls[0][1][0] notify_service.send_message(message="Hello", target="home")
payload = send.mock_calls[0][1][1]
assert "1234" == target assert send.called
assert "Hello" == payload.alert assert 1 == len(send.mock_calls)
assert 1 == payload.badge
assert "test.mp3" == payload.sound
assert "testing" == payload.category
@patch("homeassistant.components.apns.notify.APNsClient") target = send.mock_calls[0][1][0]
def test_send_when_disabled(self, mock_client): payload = send.mock_calls[0][1][1]
"""Test updating an existing device."""
send = mock_client.return_value.send_notification
yaml_file = {1234: {"name": "test device 1", "disabled": True}} assert "5678" == target
assert "Hello" == payload.alert
with patch(
"homeassistant.components.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
self._setup_notify()
assert self.hass.services.call(
"notify",
"test_app",
{
"message": "Hello",
"data": {"badge": 1, "sound": "test.mp3", "category": "testing"},
},
blocking=True,
)
assert not send.called
@patch("homeassistant.components.apns.notify.APNsClient")
def test_send_with_state(self, mock_client):
"""Test updating an existing device."""
send = mock_client.return_value.send_notification
yaml_file = {
1234: {"name": "test device 1", "tracking_device_id": "tracking123"},
5678: {"name": "test device 2", "tracking_device_id": "tracking456"},
}
with patch(
"homeassistant.components.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
), patch("os.path.isfile", Mock(return_value=True)):
notify_service = apns.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"),
)
notify_service.send_message(message="Hello", target="home")
assert send.called
assert 1 == len(send.mock_calls)
target = send.mock_calls[0][1][0]
payload = send.mock_calls[0][1][1]
assert "5678" == target
assert "Hello" == payload.alert
@patch("homeassistant.components.apns.notify.APNsClient")
@patch("homeassistant.components.apns.notify._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.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
self._setup_notify()
assert 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")
assert test_device_1 is not None
assert test_device_1.disabled is True
def test_write_device(): @patch("homeassistant.components.apns.notify.APNsClient")
@patch("homeassistant.components.apns.notify._write_device")
async def test_disable_when_unregistered(mock_write, mock_client, hass):
"""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.apns.notify.load_yaml_config_file",
Mock(return_value=yaml_file),
):
await _setup_notify(hass)
assert await hass.services.async_call(
"notify", "test_app", {"message": "Hello"}, blocking=True
)
devices = {dev.push_id: dev for dev in written_devices}
test_device_1 = devices.get("1234")
assert test_device_1 is not None
assert test_device_1.disabled is True
async def test_write_device():
"""Test writing device.""" """Test writing device."""
out = io.StringIO() out = io.StringIO()
device = apns.ApnsDevice("123", "name", "track_id", True) device = apns.ApnsDevice("123", "name", "track_id", True)