Files
core/tests/components/seventeentrack/test_sensor.py
T

423 lines
12 KiB
Python
Raw Normal View History

2019-07-28 19:55:46 +02:00
"""Tests for the seventeentrack sensor."""
2021-03-18 15:13:22 +01:00
from __future__ import annotations
2019-07-28 19:55:46 +02:00
import datetime
from unittest.mock import patch
2019-07-28 19:55:46 +02:00
from py17track.package import Package
import pytest
2019-07-28 19:55:46 +02:00
2019-07-31 12:25:30 -07:00
from homeassistant.components.seventeentrack.sensor import (
CONF_SHOW_ARCHIVED,
CONF_SHOW_DELIVERED,
)
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
2019-07-28 19:55:46 +02:00
from homeassistant.setup import async_setup_component
from homeassistant.util import utcnow
2020-04-30 16:31:00 -07:00
from tests.common import async_fire_time_changed
2019-07-28 19:55:46 +02:00
VALID_CONFIG_MINIMAL = {
2019-07-31 12:25:30 -07:00
"sensor": {
"platform": "seventeentrack",
CONF_USERNAME: "test",
CONF_PASSWORD: "test",
2019-07-28 19:55:46 +02:00
}
}
2019-07-31 12:25:30 -07:00
INVALID_CONFIG = {"sensor": {"platform": "seventeentrack", "boom": "test"}}
2019-07-28 19:55:46 +02:00
VALID_CONFIG_FULL = {
2019-07-31 12:25:30 -07:00
"sensor": {
"platform": "seventeentrack",
CONF_USERNAME: "test",
CONF_PASSWORD: "test",
2019-07-28 19:55:46 +02:00
CONF_SHOW_ARCHIVED: True,
2019-07-31 12:25:30 -07:00
CONF_SHOW_DELIVERED: True,
2019-07-28 19:55:46 +02:00
}
}
VALID_CONFIG_FULL_NO_DELIVERED = {
2019-07-31 12:25:30 -07:00
"sensor": {
"platform": "seventeentrack",
CONF_USERNAME: "test",
CONF_PASSWORD: "test",
2019-07-28 19:55:46 +02:00
CONF_SHOW_ARCHIVED: False,
2019-07-31 12:25:30 -07:00
CONF_SHOW_DELIVERED: False,
2019-07-28 19:55:46 +02:00
}
}
DEFAULT_SUMMARY = {
"Not Found": 0,
"In Transit": 0,
"Expired": 0,
"Ready to be Picked Up": 0,
"Undelivered": 0,
"Delivered": 0,
2019-07-31 12:25:30 -07:00
"Returned": 0,
2019-07-28 19:55:46 +02:00
}
NEW_SUMMARY_DATA = {
"Not Found": 1,
"In Transit": 1,
"Expired": 1,
"Ready to be Picked Up": 1,
"Undelivered": 1,
"Delivered": 1,
2019-07-31 12:25:30 -07:00
"Returned": 1,
2019-07-28 19:55:46 +02:00
}
class ClientMock:
"""Mock the py17track client to inject the ProfileMock."""
def __init__(self, session) -> None:
2019-07-28 19:55:46 +02:00
"""Mock the profile."""
self.profile = ProfileMock()
class ProfileMock:
"""ProfileMock will mock data coming from 17track."""
package_list = []
login_result = True
summary_data = DEFAULT_SUMMARY
2019-07-31 12:25:30 -07:00
account_id = "123"
2019-07-28 19:55:46 +02:00
@classmethod
def reset(cls):
"""Reset data to defaults."""
cls.package_list = []
cls.login_result = True
cls.summary_data = DEFAULT_SUMMARY
2019-07-31 12:25:30 -07:00
cls.account_id = "123"
2019-07-28 19:55:46 +02:00
def __init__(self) -> None:
"""Override Account id."""
self.account_id = self.__class__.account_id
async def login(self, email: str, password: str) -> bool:
"""Login mock."""
return self.__class__.login_result
2019-07-31 12:25:30 -07:00
async def packages(
self,
package_state: int | str = "",
show_archived: bool = False,
tz: str = "UTC",
2019-07-31 12:25:30 -07:00
) -> list:
"""Packages mock.""" # noqa: D401
2019-07-28 19:55:46 +02:00
return self.__class__.package_list[:]
async def summary(self, show_archived: bool = False) -> dict:
"""Summary mock."""
return self.__class__.summary_data
@pytest.fixture(autouse=True, name="mock_client")
2020-04-30 16:31:00 -07:00
def fixture_mock_client():
2019-07-28 19:55:46 +02:00
"""Mock py17track client."""
2020-06-05 01:59:55 -07:00
with patch(
"homeassistant.components.seventeentrack.sensor.SeventeenTrackClient",
new=ClientMock,
):
2019-07-28 19:55:46 +02:00
yield
ProfileMock.reset()
async def _setup_seventeentrack(hass, config=None, summary_data=None):
"""Set up component using config."""
if not config:
config = VALID_CONFIG_MINIMAL
if not summary_data:
summary_data = {}
ProfileMock.summary_data = summary_data
2019-07-31 12:25:30 -07:00
assert await async_setup_component(hass, "sensor", config)
await hass.async_block_till_done()
2019-07-28 19:55:46 +02:00
async def _goto_future(hass, future=None):
"""Move to future."""
if not future:
future = utcnow() + datetime.timedelta(minutes=10)
2020-06-05 01:59:55 -07:00
with patch("homeassistant.util.utcnow", return_value=future):
2019-07-28 19:55:46 +02:00
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
2019-07-28 19:55:46 +02:00
async def test_full_valid_config(hass):
"""Ensure everything starts correctly."""
2019-07-31 12:25:30 -07:00
assert await async_setup_component(hass, "sensor", VALID_CONFIG_FULL)
await hass.async_block_till_done()
2019-07-31 12:25:30 -07:00
assert len(hass.states.async_entity_ids()) == len(ProfileMock.summary_data.keys())
2019-07-28 19:55:46 +02:00
async def test_valid_config(hass):
"""Ensure everything starts correctly."""
2019-07-31 12:25:30 -07:00
assert await async_setup_component(hass, "sensor", VALID_CONFIG_MINIMAL)
await hass.async_block_till_done()
2019-07-31 12:25:30 -07:00
assert len(hass.states.async_entity_ids()) == len(ProfileMock.summary_data.keys())
2019-07-28 19:55:46 +02:00
async def test_invalid_config(hass):
"""Ensure nothing is created when config is wrong."""
2019-07-31 12:25:30 -07:00
assert await async_setup_component(hass, "sensor", INVALID_CONFIG)
2019-07-28 19:55:46 +02:00
assert not hass.states.async_entity_ids("sensor")
2019-07-28 19:55:46 +02:00
async def test_add_package(hass):
"""Ensure package is added correctly when user add a new package."""
2019-07-31 12:25:30 -07:00
package = Package(
2021-12-01 10:52:33 -07:00
tracking_number="456",
destination_country=206,
friendly_name="friendly name 1",
info_text="info text 1",
location="location 1",
timestamp="2020-08-10 10:32",
origin_country=206,
package_type=2,
2019-07-31 12:25:30 -07:00
)
2019-07-28 19:55:46 +02:00
ProfileMock.package_list = [package]
await _setup_seventeentrack(hass)
2019-07-31 12:25:30 -07:00
assert hass.states.get("sensor.seventeentrack_package_456") is not None
2019-07-28 19:55:46 +02:00
assert len(hass.states.async_entity_ids()) == 1
2019-07-31 12:25:30 -07:00
package2 = Package(
2021-12-01 10:52:33 -07:00
tracking_number="789",
destination_country=206,
friendly_name="friendly name 2",
info_text="info text 2",
location="location 2",
timestamp="2020-08-10 14:25",
origin_country=206,
package_type=2,
2019-07-31 12:25:30 -07:00
)
2019-07-28 19:55:46 +02:00
ProfileMock.package_list = [package, package2]
await _goto_future(hass)
2019-07-31 12:25:30 -07:00
assert hass.states.get("sensor.seventeentrack_package_789") is not None
2019-07-28 19:55:46 +02:00
assert len(hass.states.async_entity_ids()) == 2
async def test_remove_package(hass):
"""Ensure entity is not there anymore if package is not there."""
2019-07-31 12:25:30 -07:00
package1 = Package(
2021-12-01 10:52:33 -07:00
tracking_number="456",
destination_country=206,
friendly_name="friendly name 1",
info_text="info text 1",
location="location 1",
timestamp="2020-08-10 10:32",
origin_country=206,
package_type=2,
2019-07-31 12:25:30 -07:00
)
package2 = Package(
2021-12-01 10:52:33 -07:00
tracking_number="789",
destination_country=206,
friendly_name="friendly name 2",
info_text="info text 2",
location="location 2",
timestamp="2020-08-10 14:25",
origin_country=206,
package_type=2,
2019-07-31 12:25:30 -07:00
)
2019-07-28 19:55:46 +02:00
ProfileMock.package_list = [package1, package2]
await _setup_seventeentrack(hass)
2019-07-31 12:25:30 -07:00
assert hass.states.get("sensor.seventeentrack_package_456") is not None
assert hass.states.get("sensor.seventeentrack_package_789") is not None
2019-07-28 19:55:46 +02:00
assert len(hass.states.async_entity_ids()) == 2
ProfileMock.package_list = [package2]
await _goto_future(hass)
2019-07-31 12:25:30 -07:00
assert hass.states.get("sensor.seventeentrack_package_456") is None
assert hass.states.get("sensor.seventeentrack_package_789") is not None
2019-07-28 19:55:46 +02:00
assert len(hass.states.async_entity_ids()) == 1
async def test_friendly_name_changed(hass):
"""Test friendly name change."""
2019-07-31 12:25:30 -07:00
package = Package(
2021-12-01 10:52:33 -07:00
tracking_number="456",
destination_country=206,
friendly_name="friendly name 1",
info_text="info text 1",
location="location 1",
timestamp="2020-08-10 10:32",
origin_country=206,
package_type=2,
2019-07-31 12:25:30 -07:00
)
2019-07-28 19:55:46 +02:00
ProfileMock.package_list = [package]
await _setup_seventeentrack(hass)
2019-07-31 12:25:30 -07:00
assert hass.states.get("sensor.seventeentrack_package_456") is not None
2019-07-28 19:55:46 +02:00
assert len(hass.states.async_entity_ids()) == 1
2019-07-31 12:25:30 -07:00
package = Package(
2021-12-01 10:52:33 -07:00
tracking_number="456",
destination_country=206,
friendly_name="friendly name 2",
info_text="info text 1",
location="location 1",
timestamp="2020-08-10 10:32",
origin_country=206,
package_type=2,
2019-07-31 12:25:30 -07:00
)
2019-07-28 19:55:46 +02:00
ProfileMock.package_list = [package]
await _goto_future(hass)
2019-07-31 12:25:30 -07:00
assert hass.states.get("sensor.seventeentrack_package_456") is not None
entity = hass.data["entity_components"]["sensor"].get_entity(
"sensor.seventeentrack_package_456"
)
assert entity.name == "Seventeentrack Package: friendly name 2"
2019-07-28 19:55:46 +02:00
assert len(hass.states.async_entity_ids()) == 1
async def test_delivered_not_shown(hass):
"""Ensure delivered packages are not shown."""
2019-07-31 12:25:30 -07:00
package = Package(
2021-12-01 10:52:33 -07:00
tracking_number="456",
destination_country=206,
friendly_name="friendly name 1",
info_text="info text 1",
location="location 1",
timestamp="2020-08-10 10:32",
origin_country=206,
package_type=2,
status=40,
2019-07-31 12:25:30 -07:00
)
2019-07-28 19:55:46 +02:00
ProfileMock.package_list = [package]
with patch(
"homeassistant.components.seventeentrack.sensor.persistent_notification"
) as persistent_notification_mock:
await _setup_seventeentrack(hass, VALID_CONFIG_FULL_NO_DELIVERED)
await _goto_future(hass)
assert not hass.states.async_entity_ids()
persistent_notification_mock.create.assert_called()
2019-07-28 19:55:46 +02:00
async def test_delivered_shown(hass):
"""Ensure delivered packages are show when user choose to show them."""
2019-07-31 12:25:30 -07:00
package = Package(
2021-12-01 10:52:33 -07:00
tracking_number="456",
destination_country=206,
friendly_name="friendly name 1",
info_text="info text 1",
location="location 1",
timestamp="2020-08-10 10:32",
origin_country=206,
package_type=2,
status=40,
2019-07-31 12:25:30 -07:00
)
2019-07-28 19:55:46 +02:00
ProfileMock.package_list = [package]
with patch(
"homeassistant.components.seventeentrack.sensor.persistent_notification"
) as persistent_notification_mock:
await _setup_seventeentrack(hass, VALID_CONFIG_FULL)
2019-07-28 19:55:46 +02:00
assert hass.states.get("sensor.seventeentrack_package_456") is not None
assert len(hass.states.async_entity_ids()) == 1
persistent_notification_mock.create.assert_not_called()
2019-07-28 19:55:46 +02:00
async def test_becomes_delivered_not_shown_notification(hass):
"""Ensure notification is triggered when package becomes delivered."""
2019-07-31 12:25:30 -07:00
package = Package(
2021-12-01 10:52:33 -07:00
tracking_number="456",
destination_country=206,
friendly_name="friendly name 1",
info_text="info text 1",
location="location 1",
timestamp="2020-08-10 10:32",
origin_country=206,
package_type=2,
2019-07-31 12:25:30 -07:00
)
2019-07-28 19:55:46 +02:00
ProfileMock.package_list = [package]
await _setup_seventeentrack(hass, VALID_CONFIG_FULL_NO_DELIVERED)
2019-07-31 12:25:30 -07:00
assert hass.states.get("sensor.seventeentrack_package_456") is not None
2019-07-28 19:55:46 +02:00
assert len(hass.states.async_entity_ids()) == 1
2019-07-31 12:25:30 -07:00
package_delivered = Package(
2021-12-01 10:52:33 -07:00
tracking_number="456",
destination_country=206,
friendly_name="friendly name 1",
info_text="info text 1",
location="location 1",
timestamp="2020-08-10 10:32",
origin_country=206,
package_type=2,
status=40,
2019-07-31 12:25:30 -07:00
)
2019-07-28 19:55:46 +02:00
ProfileMock.package_list = [package_delivered]
with patch(
"homeassistant.components.seventeentrack.sensor.persistent_notification"
) as persistent_notification_mock:
await _goto_future(hass)
2019-07-28 19:55:46 +02:00
persistent_notification_mock.create.assert_called()
assert not hass.states.async_entity_ids()
2019-07-28 19:55:46 +02:00
async def test_summary_correctly_updated(hass):
"""Ensure summary entities are not duplicated."""
await _setup_seventeentrack(hass, summary_data=DEFAULT_SUMMARY)
assert len(hass.states.async_entity_ids()) == 7
for state in hass.states.async_all():
2019-07-31 12:25:30 -07:00
assert state.state == "0"
2019-07-28 19:55:46 +02:00
ProfileMock.summary_data = NEW_SUMMARY_DATA
await _goto_future(hass)
assert len(hass.states.async_entity_ids()) == 7
for state in hass.states.async_all():
2019-07-31 12:25:30 -07:00
assert state.state == "1"
async def test_utc_timestamp(hass):
"""Ensure package timestamp is converted correctly from HA-defined time zone to UTC."""
package = Package(
2021-12-01 10:52:33 -07:00
tracking_number="456",
destination_country=206,
friendly_name="friendly name 1",
info_text="info text 1",
location="location 1",
timestamp="2020-08-10 10:32",
origin_country=206,
package_type=2,
tz="Asia/Jakarta",
)
ProfileMock.package_list = [package]
await _setup_seventeentrack(hass)
assert hass.states.get("sensor.seventeentrack_package_456") is not None
assert len(hass.states.async_entity_ids()) == 1
assert (
str(
hass.states.get("sensor.seventeentrack_package_456").attributes.get(
"timestamp"
)
)
== "2020-08-10 03:32:00+00:00"
)