diff --git a/homeassistant/components/owntracks/__init__.py b/homeassistant/components/owntracks/__init__.py index e746cbc01fa..979f3829454 100644 --- a/homeassistant/components/owntracks/__init__.py +++ b/homeassistant/components/owntracks/__init__.py @@ -91,6 +91,24 @@ async def async_setup_entry(hass, entry): return True +async def async_unload_entry(hass, entry): + """Unload an OwnTracks config entry.""" + hass.components.webhook.async_unregister(entry.data[CONF_WEBHOOK_ID]) + await hass.config_entries.async_forward_entry_unload( + entry, 'device_tracker') + return True + + +async def async_remove_entry(hass, entry): + """Remove an OwnTracks config entry.""" + if (not entry.data.get('cloudhook') or + 'cloud' not in hass.config.components): + return + + await hass.components.cloud.async_delete_cloudhook( + entry.data[CONF_WEBHOOK_ID]) + + async def async_connect_mqtt(hass, component): """Subscribe to MQTT topic.""" context = hass.data[DOMAIN]['context'] diff --git a/homeassistant/components/owntracks/config_flow.py b/homeassistant/components/owntracks/config_flow.py index 59e8c4825df..f157c5cb7ce 100644 --- a/homeassistant/components/owntracks/config_flow.py +++ b/homeassistant/components/owntracks/config_flow.py @@ -4,6 +4,7 @@ from homeassistant.const import CONF_WEBHOOK_ID from homeassistant.auth.util import generate_secret CONF_SECRET = 'secret' +CONF_CLOUDHOOK = 'cloudhook' def supports_encryption(): @@ -31,9 +32,7 @@ class OwnTracksFlow(config_entries.ConfigFlow): step_id='user', ) - webhook_id = self.hass.components.webhook.async_generate_id() - webhook_url = \ - self.hass.components.webhook.async_generate_url(webhook_id) + webhook_id, webhook_url, cloudhook = await self._get_webhook_id() secret = generate_secret(16) @@ -50,7 +49,8 @@ class OwnTracksFlow(config_entries.ConfigFlow): title="OwnTracks", data={ CONF_WEBHOOK_ID: webhook_id, - CONF_SECRET: secret + CONF_SECRET: secret, + CONF_CLOUDHOOK: cloudhook, }, description_placeholders={ 'secret': secret_desc, @@ -67,12 +67,29 @@ class OwnTracksFlow(config_entries.ConfigFlow): async def async_step_import(self, user_input): """Import a config flow from configuration.""" - webhook_id = self.hass.components.webhook.async_generate_id() + webhook_id, _webhook_url, cloudhook = await self._get_webhook_id() secret = generate_secret(16) return self.async_create_entry( title="OwnTracks", data={ CONF_WEBHOOK_ID: webhook_id, - CONF_SECRET: secret + CONF_SECRET: secret, + CONF_CLOUDHOOK: cloudhook, } ) + + async def _get_webhook_id(self): + """Generate webhook ID.""" + webhook_id = self.hass.components.webhook.async_generate_id() + if self.hass.components.cloud.async_active_subscription(): + webhook_url = \ + await self.hass.components.cloud.async_create_cloudhook( + webhook_id + ) + cloudhook = True + else: + webhook_url = \ + self.hass.components.webhook.async_generate_url(webhook_id) + cloudhook = False + + return webhook_id, webhook_url, cloudhook diff --git a/tests/components/owntracks/test_config_flow.py b/tests/components/owntracks/test_config_flow.py index 079fdfafea0..57f4cfd354e 100644 --- a/tests/components/owntracks/test_config_flow.py +++ b/tests/components/owntracks/test_config_flow.py @@ -1 +1,61 @@ """Tests for OwnTracks config flow.""" +from unittest.mock import patch + +from homeassistant.setup import async_setup_component +from tests.common import mock_coro + + +async def test_config_flow_import(hass): + """Test that we automatically create a config flow.""" + assert not hass.config_entries.async_entries('owntracks') + assert await async_setup_component(hass, 'owntracks', { + 'owntracks': { + + } + }) + await hass.async_block_till_done() + assert hass.config_entries.async_entries('owntracks') + + +async def test_config_flow_unload(hass): + """Test unloading a config flow.""" + with patch('homeassistant.config_entries.ConfigEntries' + '.async_forward_entry_setup') as mock_forward: + result = await hass.config_entries.flow.async_init( + 'owntracks', context={'source': 'import'}, + data={} + ) + + assert len(mock_forward.mock_calls) == 1 + entry = result['result'] + + assert mock_forward.mock_calls[0][1][0] is entry + assert mock_forward.mock_calls[0][1][1] == 'device_tracker' + assert entry.data['webhook_id'] in hass.data['webhook'] + + with patch('homeassistant.config_entries.ConfigEntries' + '.async_forward_entry_unload', return_value=mock_coro() + ) as mock_unload: + assert await hass.config_entries.async_unload(entry.entry_id) + + assert len(mock_unload.mock_calls) == 1 + assert mock_forward.mock_calls[0][1][0] is entry + assert mock_forward.mock_calls[0][1][1] == 'device_tracker' + assert entry.data['webhook_id'] not in hass.data['webhook'] + + +async def test_with_cloud_sub(hass): + """Test creating a config flow while subscribed.""" + with patch('homeassistant.components.cloud.async_active_subscription', + return_value=True), \ + patch('homeassistant.components.cloud.async_create_cloudhook', + return_value=mock_coro('https://hooks.nabu.casa/ABCD')): + result = await hass.config_entries.flow.async_init( + 'owntracks', context={'source': 'user'}, + data={} + ) + + entry = result['result'] + assert entry.data['cloudhook'] + assert result['description_placeholders']['webhook_url'] == \ + 'https://hooks.nabu.casa/ABCD' diff --git a/tests/components/owntracks/test_init.py b/tests/components/owntracks/test_init.py index 3d2d8d03e7c..fafe9678e78 100644 --- a/tests/components/owntracks/test_init.py +++ b/tests/components/owntracks/test_init.py @@ -160,15 +160,3 @@ def test_returns_error_missing_device(mock_client): json = yield from resp.json() assert json == [] - - -async def test_config_flow_import(hass): - """Test that we automatically create a config flow.""" - assert not hass.config_entries.async_entries('owntracks') - assert await async_setup_component(hass, 'owntracks', { - 'owntracks': { - - } - }) - await hass.async_block_till_done() - assert hass.config_entries.async_entries('owntracks')