Fix non-thread-safe operations in html5 (#116068)

Fix non thread-safe calls in html5

2417766876
This commit is contained in:
J. Nick Koston 2024-04-24 03:33:19 +02:00 committed by GitHub
parent b1b8b8ba00
commit 9d54aa205b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 122 additions and 114 deletions

View file

@ -165,7 +165,7 @@ HTML5_SHOWNOTIFICATION_PARAMETERS = (
)
def get_service(
async def async_get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
@ -173,7 +173,7 @@ def get_service(
"""Get the HTML5 push notification service."""
json_path = hass.config.path(REGISTRATIONS_FILE)
registrations = _load_config(json_path)
registrations = await hass.async_add_executor_job(_load_config, json_path)
vapid_pub_key = config[ATTR_VAPID_PUB_KEY]
vapid_prv_key = config[ATTR_VAPID_PRV_KEY]

View file

@ -2,7 +2,7 @@
from http import HTTPStatus
import json
from unittest.mock import MagicMock, mock_open, patch
from unittest.mock import mock_open, patch
from aiohttp.hdrs import AUTHORIZATION
@ -83,34 +83,32 @@ async def mock_client(hass, hass_client, registrations=None):
return await hass_client()
class TestHtml5Notify:
"""Tests for HTML5 notify platform."""
def test_get_service_with_no_json(self):
async def test_get_service_with_no_json(hass: HomeAssistant):
"""Test empty json file."""
hass = MagicMock()
await async_setup_component(hass, "http", {})
m = mock_open()
with patch("homeassistant.util.json.open", m, create=True):
service = html5.get_service(hass, VAPID_CONF)
service = await html5.async_get_service(hass, VAPID_CONF)
assert service is not None
@patch("homeassistant.components.html5.notify.WebPusher")
def test_dismissing_message(self, mock_wp):
async def test_dismissing_message(mock_wp, hass: HomeAssistant):
"""Test dismissing message."""
hass = MagicMock()
await async_setup_component(hass, "http", {})
mock_wp().send().status_code = 201
data = {"device": SUBSCRIPTION_1}
m = mock_open(read_data=json.dumps(data))
with patch("homeassistant.util.json.open", m, create=True):
service = html5.get_service(hass, VAPID_CONF)
service = await html5.async_get_service(hass, VAPID_CONF)
service.hass = hass
assert service is not None
service.dismiss(target=["device", "non_existing"], data={"tag": "test"})
await service.async_dismiss(target=["device", "non_existing"], data={"tag": "test"})
assert len(mock_wp.mock_calls) == 4
@ -123,21 +121,23 @@ class TestHtml5Notify:
assert payload["dismiss"] is True
assert payload["tag"] == "test"
@patch("homeassistant.components.html5.notify.WebPusher")
def test_sending_message(self, mock_wp):
async def test_sending_message(mock_wp, hass: HomeAssistant):
"""Test sending message."""
hass = MagicMock()
await async_setup_component(hass, "http", {})
mock_wp().send().status_code = 201
data = {"device": SUBSCRIPTION_1}
m = mock_open(read_data=json.dumps(data))
with patch("homeassistant.util.json.open", m, create=True):
service = html5.get_service(hass, VAPID_CONF)
service = await html5.async_get_service(hass, VAPID_CONF)
service.hass = hass
assert service is not None
service.send_message(
await service.async_send_message(
"Hello", target=["device", "non_existing"], data={"icon": "beer.png"}
)
@ -152,21 +152,23 @@ class TestHtml5Notify:
assert payload["body"] == "Hello"
assert payload["icon"] == "beer.png"
@patch("homeassistant.components.html5.notify.WebPusher")
def test_fcm_key_include(self, mock_wp):
async def test_fcm_key_include(mock_wp, hass: HomeAssistant):
"""Test if the FCM header is included."""
hass = MagicMock()
await async_setup_component(hass, "http", {})
mock_wp().send().status_code = 201
data = {"chrome": SUBSCRIPTION_5}
m = mock_open(read_data=json.dumps(data))
with patch("homeassistant.util.json.open", m, create=True):
service = html5.get_service(hass, VAPID_CONF)
service = await html5.async_get_service(hass, VAPID_CONF)
service.hass = hass
assert service is not None
service.send_message("Hello", target=["chrome"])
await service.async_send_message("Hello", target=["chrome"])
assert len(mock_wp.mock_calls) == 4
# WebPusher constructor
@ -175,21 +177,23 @@ class TestHtml5Notify:
# Get the keys passed to the WebPusher's send method
assert mock_wp.mock_calls[3][2]["headers"]["Authorization"] is not None
@patch("homeassistant.components.html5.notify.WebPusher")
def test_fcm_send_with_unknown_priority(self, mock_wp):
async def test_fcm_send_with_unknown_priority(mock_wp, hass: HomeAssistant):
"""Test if the gcm_key is only included for GCM endpoints."""
hass = MagicMock()
await async_setup_component(hass, "http", {})
mock_wp().send().status_code = 201
data = {"chrome": SUBSCRIPTION_5}
m = mock_open(read_data=json.dumps(data))
with patch("homeassistant.util.json.open", m, create=True):
service = html5.get_service(hass, VAPID_CONF)
service = await html5.async_get_service(hass, VAPID_CONF)
service.hass = hass
assert service is not None
service.send_message("Hello", target=["chrome"], priority="undefined")
await service.async_send_message("Hello", target=["chrome"], priority="undefined")
assert len(mock_wp.mock_calls) == 4
# WebPusher constructor
@ -198,21 +202,23 @@ class TestHtml5Notify:
# Get the keys passed to the WebPusher's send method
assert mock_wp.mock_calls[3][2]["headers"]["priority"] == "normal"
@patch("homeassistant.components.html5.notify.WebPusher")
def test_fcm_no_targets(self, mock_wp):
async def test_fcm_no_targets(mock_wp, hass: HomeAssistant):
"""Test if the gcm_key is only included for GCM endpoints."""
hass = MagicMock()
await async_setup_component(hass, "http", {})
mock_wp().send().status_code = 201
data = {"chrome": SUBSCRIPTION_5}
m = mock_open(read_data=json.dumps(data))
with patch("homeassistant.util.json.open", m, create=True):
service = html5.get_service(hass, VAPID_CONF)
service = await html5.async_get_service(hass, VAPID_CONF)
service.hass = hass
assert service is not None
service.send_message("Hello")
await service.async_send_message("Hello")
assert len(mock_wp.mock_calls) == 4
# WebPusher constructor
@ -221,21 +227,23 @@ class TestHtml5Notify:
# Get the keys passed to the WebPusher's send method
assert mock_wp.mock_calls[3][2]["headers"]["priority"] == "normal"
@patch("homeassistant.components.html5.notify.WebPusher")
def test_fcm_additional_data(self, mock_wp):
async def test_fcm_additional_data(mock_wp, hass: HomeAssistant):
"""Test if the gcm_key is only included for GCM endpoints."""
hass = MagicMock()
await async_setup_component(hass, "http", {})
mock_wp().send().status_code = 201
data = {"chrome": SUBSCRIPTION_5}
m = mock_open(read_data=json.dumps(data))
with patch("homeassistant.util.json.open", m, create=True):
service = html5.get_service(hass, VAPID_CONF)
service = await html5.async_get_service(hass, VAPID_CONF)
service.hass = hass
assert service is not None
service.send_message("Hello", data={"mykey": "myvalue"})
await service.async_send_message("Hello", data={"mykey": "myvalue"})
assert len(mock_wp.mock_calls) == 4
# WebPusher constructor