From 3bdee570660b8cebac897053dfe88d4668e47479 Mon Sep 17 00:00:00 2001 From: Tommy Jonsson Date: Sat, 12 Jan 2019 05:44:29 +0100 Subject: [PATCH] Support for html5 notifications to suggest their names (#19965) * support for devices to suggest their names * houndci fixes * Lint --- homeassistant/components/notify/html5.py | 12 ++++++-- tests/components/notify/test_html5.py | 38 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/notify/html5.py b/homeassistant/components/notify/html5.py index 771606b935f..f70a9cb73c1 100644 --- a/homeassistant/components/notify/html5.py +++ b/homeassistant/components/notify/html5.py @@ -44,6 +44,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ ATTR_SUBSCRIPTION = 'subscription' ATTR_BROWSER = 'browser' +ATTR_NAME = 'name' ATTR_ENDPOINT = 'endpoint' ATTR_KEYS = 'keys' @@ -82,6 +83,7 @@ SUBSCRIPTION_SCHEMA = vol.All( REGISTER_SCHEMA = vol.Schema({ vol.Required(ATTR_SUBSCRIPTION): SUBSCRIPTION_SCHEMA, vol.Required(ATTR_BROWSER): vol.In(['chrome', 'firefox']), + vol.Optional(ATTR_NAME): cv.string }) CALLBACK_EVENT_PAYLOAD_SCHEMA = vol.Schema({ @@ -156,7 +158,10 @@ class HTML5PushRegistrationView(HomeAssistantView): return self.json_message( humanize_error(data, ex), HTTP_BAD_REQUEST) - name = self.find_registration_name(data) + devname = data.get(ATTR_NAME) + data.pop(ATTR_NAME, None) + + name = self.find_registration_name(data, devname) previous_registration = self.registrations.get(name) self.registrations[name] = data @@ -177,14 +182,15 @@ class HTML5PushRegistrationView(HomeAssistantView): return self.json_message( 'Error saving registration.', HTTP_INTERNAL_SERVER_ERROR) - def find_registration_name(self, data): + def find_registration_name(self, data, suggested=None): """Find a registration name matching data or generate a unique one.""" endpoint = data.get(ATTR_SUBSCRIPTION).get(ATTR_ENDPOINT) for key, registration in self.registrations.items(): subscription = registration.get(ATTR_SUBSCRIPTION) if subscription.get(ATTR_ENDPOINT) == endpoint: return key - return ensure_unique_string('unnamed device', self.registrations) + return ensure_unique_string(suggested or 'unnamed device', + self.registrations) async def delete(self, request): """Delete a registration.""" diff --git a/tests/components/notify/test_html5.py b/tests/components/notify/test_html5.py index 08210ecd9a2..6aeba650a8c 100644 --- a/tests/components/notify/test_html5.py +++ b/tests/components/notify/test_html5.py @@ -165,6 +165,23 @@ async def test_registering_new_device_view(hass, hass_client): } +async def test_registering_new_device_view_with_name(hass, hass_client): + """Test that the HTML view works with name attribute.""" + client = await mock_client(hass, hass_client) + + SUB_WITH_NAME = SUBSCRIPTION_1.copy() + SUB_WITH_NAME['name'] = 'test device' + + with patch('homeassistant.components.notify.html5.save_json') as mock_save: + resp = await client.post(REGISTER_URL, data=json.dumps(SUB_WITH_NAME)) + + assert resp.status == 200 + assert len(mock_save.mock_calls) == 1 + assert mock_save.mock_calls[0][1][1] == { + 'test device': SUBSCRIPTION_1, + } + + async def test_registering_new_device_expiration_view(hass, hass_client): """Test that the HTML view works.""" client = await mock_client(hass, hass_client) @@ -209,6 +226,27 @@ async def test_registering_existing_device_view(hass, hass_client): } +async def test_registering_existing_device_view_with_name(hass, hass_client): + """Test subscription is updated when reg'ing existing device with name.""" + registrations = {} + client = await mock_client(hass, hass_client, registrations) + + SUB_WITH_NAME = SUBSCRIPTION_1.copy() + SUB_WITH_NAME['name'] = 'test device' + + with patch('homeassistant.components.notify.html5.save_json') as mock_save: + await client.post(REGISTER_URL, data=json.dumps(SUB_WITH_NAME)) + resp = await client.post(REGISTER_URL, data=json.dumps(SUBSCRIPTION_4)) + + assert resp.status == 200 + assert mock_save.mock_calls[0][1][1] == { + 'test device': SUBSCRIPTION_4, + } + assert registrations == { + 'test device': SUBSCRIPTION_4, + } + + async def test_registering_existing_device_fails_view(hass, hass_client): """Test sub. is not updated when registering existing device fails.""" registrations = {}