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
This commit is contained in:
epenet 2023-04-06 13:48:19 +02:00 committed by GitHub
parent fa308d8e10
commit 842d89f419
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,6 +1,8 @@
"""The tests for the mailbox component.""" """The tests for the mailbox component."""
from datetime import datetime
from hashlib import sha1 from hashlib import sha1
from http import HTTPStatus from http import HTTPStatus
from typing import Any
from aiohttp.test_utils import TestClient from aiohttp.test_utils import TestClient
import pytest import pytest
@ -8,20 +10,111 @@ import pytest
from homeassistant.bootstrap import async_setup_component from homeassistant.bootstrap import async_setup_component
import homeassistant.components.mailbox as mailbox import homeassistant.components.mailbox as mailbox
from homeassistant.core import HomeAssistant 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 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 @pytest.fixture
async def mock_http_client( async def mock_http_client(
hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_mailbox: None
) -> TestClient: ) -> TestClient:
"""Start the Home Assistant HTTP component.""" """Start the Home Assistant HTTP component."""
config = {mailbox.DOMAIN: {"platform": "demo"}} assert await async_setup_component(
with assert_setup_component(1, mailbox.DOMAIN): hass, mailbox.DOMAIN, {mailbox.DOMAIN: {"platform": "test"}}
await async_setup_component(hass, mailbox.DOMAIN, config) )
await hass.async_block_till_done()
return await hass_client() 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 assert req.status == HTTPStatus.OK
result = await req.json() result = await req.json()
assert len(result) == 1 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: async def test_get_messages_from_mailbox(mock_http_client: TestClient) -> None:
"""Get messages from mailbox.""" """Get messages from mailbox."""
url = "/api/mailbox/messages/DemoMailbox" url = "/api/mailbox/messages/TestMailbox"
req = await mock_http_client.get(url) req = await mock_http_client.get(url)
assert req.status == HTTPStatus.OK 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: async def test_get_media_from_mailbox(mock_http_client: TestClient) -> None:
"""Get audio from mailbox.""" """Get audio from mailbox."""
mp3sha = "3f67c4ea33b37d1710f772a26dd3fb43bb159d50" mp3sha = "7cad61312c7b66f619295be2da8c7ac73b4968f1"
msgtxt = "Message 1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. " msgtxt = "Message 1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
msgsha = sha1(msgtxt.encode("utf-8")).hexdigest() 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) req = await mock_http_client.get(url)
assert req.status == HTTPStatus.OK assert req.status == HTTPStatus.OK
data = await req.read() 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() msgsha2 = sha1(msgtxt2.encode("utf-8")).hexdigest()
for msg in [msgsha1, msgsha2]: 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) req = await mock_http_client.delete(url)
assert req.status == HTTPStatus.OK assert req.status == HTTPStatus.OK
url = "/api/mailbox/messages/DemoMailbox" url = "/api/mailbox/messages/TestMailbox"
req = await mock_http_client.get(url) req = await mock_http_client.get(url)
assert req.status == HTTPStatus.OK assert req.status == HTTPStatus.OK
result = await req.json() 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: async def test_get_media_from_invalid_msgid(mock_http_client: TestClient) -> None:
"""Get messages from mailbox.""" """Get messages from mailbox."""
msgsha = "0000000000000000000000000000000000000000" msgsha = "0000000000000000000000000000000000000000"
url = f"/api/mailbox/media/DemoMailbox/{msgsha}" url = f"/api/mailbox/media/TestMailbox/{msgsha}"
req = await mock_http_client.get(url) req = await mock_http_client.get(url)
assert req.status == HTTPStatus.INTERNAL_SERVER_ERROR assert req.status == HTTPStatus.INTERNAL_SERVER_ERROR