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 = {}