From 842d89f419cebf5f24193f768cb824e1522a889c Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Thu, 6 Apr 2023 13:48:19 +0200 Subject: [PATCH] Rewrite mailbox tests (#90906) * Rewrite mailbox tests * Use some bytes for get_media * Split __init__ method * Cleanup lingering timers * Simplify message text * Simplify msgtime * Remove cleanup * Use a constant --- tests/components/mailbox/test_init.py | 119 +++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 13 deletions(-) diff --git a/tests/components/mailbox/test_init.py b/tests/components/mailbox/test_init.py index b2203f5552f..e0cae290e2b 100644 --- a/tests/components/mailbox/test_init.py +++ b/tests/components/mailbox/test_init.py @@ -1,6 +1,8 @@ """The tests for the mailbox component.""" +from datetime import datetime from hashlib import sha1 from http import HTTPStatus +from typing import Any from aiohttp.test_utils import TestClient import pytest @@ -8,20 +10,111 @@ import pytest from homeassistant.bootstrap import async_setup_component import homeassistant.components.mailbox as mailbox from homeassistant.core import HomeAssistant +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.util import dt as dt_util -from tests.common import assert_setup_component +from tests.common import MockModule, mock_integration, mock_platform from tests.typing import ClientSessionGenerator +MAILBOX_NAME = "TestMailbox" +MEDIA_DATA = b"3f67c4ea33b37d1710f" +MESSAGE_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + +def _create_message(idx: int) -> dict[str, Any]: + """Create a sample message.""" + msgtime = dt_util.as_timestamp(datetime(2010, 12, idx + 1, 13, 17, 00)) + msgtxt = f"Message {idx + 1}. {MESSAGE_TEXT}" + msgsha = sha1(msgtxt.encode("utf-8")).hexdigest() + return { + "info": { + "origtime": int(msgtime), + "callerid": "John Doe <212-555-1212>", + "duration": "10", + }, + "text": msgtxt, + "sha": msgsha, + } + + +class TestMailbox(mailbox.Mailbox): + """Test Mailbox, with 10 sample messages.""" + + def __init__(self, hass: HomeAssistant, name: str) -> None: + """Initialize Test mailbox.""" + super().__init__(hass, name) + self._messages: dict[str, dict[str, Any]] = {} + for idx in range(0, 10): + msg = _create_message(idx) + msgsha = msg["sha"] + self._messages[msgsha] = msg + + @property + def media_type(self) -> str: + """Return the supported media type.""" + return mailbox.CONTENT_TYPE_MPEG + + @property + def can_delete(self) -> bool: + """Return if messages can be deleted.""" + return True + + @property + def has_media(self) -> bool: + """Return if messages have attached media files.""" + return True + + async def async_get_media(self, msgid: str) -> bytes: + """Return the media blob for the msgid.""" + if msgid not in self._messages: + raise mailbox.StreamError("Message not found") + + return MEDIA_DATA + + async def async_get_messages(self) -> list[dict[str, Any]]: + """Return a list of the current messages.""" + return sorted( + self._messages.values(), + key=lambda item: item["info"]["origtime"], # type: ignore[no-any-return] + reverse=True, + ) + + async def async_delete(self, msgid: str) -> bool: + """Delete the specified messages.""" + if msgid in self._messages: + del self._messages[msgid] + self.async_update() + return True + + +class MockMailbox: + """A mock mailbox platform.""" + + async def async_get_handler( + self, + hass: HomeAssistant, + config: ConfigType, + discovery_info: DiscoveryInfoType | None = None, + ) -> mailbox.Mailbox: + """Set up the Test mailbox.""" + return TestMailbox(hass, MAILBOX_NAME) + + +@pytest.fixture +def mock_mailbox(hass: HomeAssistant) -> None: + """Mock mailbox.""" + mock_integration(hass, MockModule(domain="test")) + mock_platform(hass, "test.mailbox", MockMailbox()) + @pytest.fixture async def mock_http_client( - hass: HomeAssistant, hass_client: ClientSessionGenerator + hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_mailbox: None ) -> TestClient: """Start the Home Assistant HTTP component.""" - config = {mailbox.DOMAIN: {"platform": "demo"}} - with assert_setup_component(1, mailbox.DOMAIN): - await async_setup_component(hass, mailbox.DOMAIN, config) - await hass.async_block_till_done() + assert await async_setup_component( + hass, mailbox.DOMAIN, {mailbox.DOMAIN: {"platform": "test"}} + ) return await hass_client() @@ -33,12 +126,12 @@ async def test_get_platforms_from_mailbox(mock_http_client: TestClient) -> None: assert req.status == HTTPStatus.OK result = await req.json() assert len(result) == 1 - assert result[0].get("name") == "DemoMailbox" + assert result[0].get("name") == "TestMailbox" async def test_get_messages_from_mailbox(mock_http_client: TestClient) -> None: """Get messages from mailbox.""" - url = "/api/mailbox/messages/DemoMailbox" + url = "/api/mailbox/messages/TestMailbox" req = await mock_http_client.get(url) assert req.status == HTTPStatus.OK @@ -48,11 +141,11 @@ async def test_get_messages_from_mailbox(mock_http_client: TestClient) -> None: async def test_get_media_from_mailbox(mock_http_client: TestClient) -> None: """Get audio from mailbox.""" - mp3sha = "3f67c4ea33b37d1710f772a26dd3fb43bb159d50" + mp3sha = "7cad61312c7b66f619295be2da8c7ac73b4968f1" msgtxt = "Message 1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. " msgsha = sha1(msgtxt.encode("utf-8")).hexdigest() - url = f"/api/mailbox/media/DemoMailbox/{msgsha}" + url = f"/api/mailbox/media/TestMailbox/{msgsha}" req = await mock_http_client.get(url) assert req.status == HTTPStatus.OK data = await req.read() @@ -67,11 +160,11 @@ async def test_delete_from_mailbox(mock_http_client: TestClient) -> None: msgsha2 = sha1(msgtxt2.encode("utf-8")).hexdigest() for msg in [msgsha1, msgsha2]: - url = f"/api/mailbox/delete/DemoMailbox/{msg}" + url = f"/api/mailbox/delete/TestMailbox/{msg}" req = await mock_http_client.delete(url) assert req.status == HTTPStatus.OK - url = "/api/mailbox/messages/DemoMailbox" + url = "/api/mailbox/messages/TestMailbox" req = await mock_http_client.get(url) assert req.status == HTTPStatus.OK result = await req.json() @@ -98,7 +191,7 @@ async def test_get_media_from_invalid_mailbox(mock_http_client: TestClient) -> N async def test_get_media_from_invalid_msgid(mock_http_client: TestClient) -> None: """Get messages from mailbox.""" msgsha = "0000000000000000000000000000000000000000" - url = f"/api/mailbox/media/DemoMailbox/{msgsha}" + url = f"/api/mailbox/media/TestMailbox/{msgsha}" req = await mock_http_client.get(url) assert req.status == HTTPStatus.INTERNAL_SERVER_ERROR