Better cloud check (#21875)

pull/21878/head
Paulus Schoutsen 2019-03-09 12:15:16 -08:00 committed by GitHub
parent ac5ccd651c
commit f4f0d363ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 19 deletions

View File

@ -91,27 +91,36 @@ class CloudNotAvailable(HomeAssistantError):
@bind_hass @bind_hass
@callback @callback
def async_is_logged_in(hass): def async_is_logged_in(hass) -> bool:
"""Test if user is logged in.""" """Test if user is logged in."""
return DOMAIN in hass.data and hass.data[DOMAIN].is_logged_in return DOMAIN in hass.data and hass.data[DOMAIN].is_logged_in
@bind_hass @bind_hass
async def async_create_cloudhook(hass, webhook_id): @callback
def async_active_subscription(hass) -> bool:
"""Test if user has an active subscription."""
return \
async_is_logged_in(hass) and not hass.data[DOMAIN].subscription_expired
@bind_hass
async def async_create_cloudhook(hass, webhook_id: str) -> str:
"""Create a cloudhook.""" """Create a cloudhook."""
if not async_is_logged_in(hass): if not async_is_logged_in(hass):
raise CloudNotAvailable raise CloudNotAvailable
return await hass.data[DOMAIN].cloudhooks.async_create(webhook_id) hook = await hass.data[DOMAIN].cloudhooks.async_create(webhook_id, True)
return hook['cloudhook_url']
@bind_hass @bind_hass
async def async_delete_cloudhook(hass, webhook_id): async def async_delete_cloudhook(hass, webhook_id: str) -> None:
"""Delete a cloudhook.""" """Delete a cloudhook."""
if not async_is_logged_in(hass): if DOMAIN not in hass.data:
raise CloudNotAvailable raise CloudNotAvailable
return await hass.data[DOMAIN].cloudhooks.async_delete(webhook_id) await hass.data[DOMAIN].cloudhooks.async_delete(webhook_id)
def is_cloudhook_request(request): def is_cloudhook_request(request):

View File

@ -46,11 +46,9 @@ class RegistrationsView(HomeAssistantView):
webhook_id = generate_secret() webhook_id = generate_secret()
if "cloud" in hass.config.components: if hass.components.cloud.async_active_subscription():
cloudhook = await async_create_cloudhook(hass, webhook_id) data[CONF_CLOUDHOOK_URL] = \
await async_create_cloudhook(hass, webhook_id)
if cloudhook is not None:
data[CONF_CLOUDHOOK_URL] = cloudhook[CONF_CLOUDHOOK_URL]
data[CONF_WEBHOOK_ID] = webhook_id data[CONF_WEBHOOK_ID] = webhook_id

View File

@ -190,10 +190,9 @@ async def test_create_cloudhook_no_login(hass):
assert len(mock_create.mock_calls) == 0 assert len(mock_create.mock_calls) == 0
async def test_delete_cloudhook_no_login(hass): async def test_delete_cloudhook_no_setup(hass):
"""Test delete cloudhook when not logged in.""" """Test delete cloudhook when not logged in."""
assert await async_setup_component(hass, 'cloud', {}) coro = mock_coro()
coro = mock_coro({'yo': 'hey'})
with patch('homeassistant.components.cloud.cloudhooks.' with patch('homeassistant.components.cloud.cloudhooks.'
'Cloudhooks.async_delete', return_value=coro) as mock_delete, \ 'Cloudhooks.async_delete', return_value=coro) as mock_delete, \
pytest.raises(cloud.CloudNotAvailable): pytest.raises(cloud.CloudNotAvailable):
@ -205,28 +204,27 @@ async def test_delete_cloudhook_no_login(hass):
async def test_create_cloudhook(hass): async def test_create_cloudhook(hass):
"""Test create cloudhook.""" """Test create cloudhook."""
assert await async_setup_component(hass, 'cloud', {}) assert await async_setup_component(hass, 'cloud', {})
coro = mock_coro({'yo': 'hey'}) coro = mock_coro({'cloudhook_url': 'hello'})
with patch('homeassistant.components.cloud.cloudhooks.' with patch('homeassistant.components.cloud.cloudhooks.'
'Cloudhooks.async_create', return_value=coro) as mock_create, \ 'Cloudhooks.async_create', return_value=coro) as mock_create, \
patch('homeassistant.components.cloud.async_is_logged_in', patch('homeassistant.components.cloud.async_is_logged_in',
return_value=True): return_value=True):
result = await hass.components.cloud.async_create_cloudhook('hello') result = await hass.components.cloud.async_create_cloudhook('hello')
assert result == {'yo': 'hey'} assert result == 'hello'
assert len(mock_create.mock_calls) == 1 assert len(mock_create.mock_calls) == 1
async def test_delete_cloudhook(hass): async def test_delete_cloudhook(hass):
"""Test delete cloudhook.""" """Test delete cloudhook."""
assert await async_setup_component(hass, 'cloud', {}) assert await async_setup_component(hass, 'cloud', {})
coro = mock_coro({'yo': 'hey'}) coro = mock_coro()
with patch('homeassistant.components.cloud.cloudhooks.' with patch('homeassistant.components.cloud.cloudhooks.'
'Cloudhooks.async_delete', return_value=coro) as mock_delete, \ 'Cloudhooks.async_delete', return_value=coro) as mock_delete, \
patch('homeassistant.components.cloud.async_is_logged_in', patch('homeassistant.components.cloud.async_is_logged_in',
return_value=True): return_value=True):
result = await hass.components.cloud.async_delete_cloudhook('hello') await hass.components.cloud.async_delete_cloudhook('hello')
assert result == {'yo': 'hey'}
assert len(mock_delete.mock_calls) == 1 assert len(mock_delete.mock_calls) == 1
@ -244,3 +242,28 @@ async def test_async_logged_in(hass):
# Cloud loaded, logged in # Cloud loaded, logged in
assert hass.components.cloud.async_is_logged_in() is True assert hass.components.cloud.async_is_logged_in() is True
async def test_async_active_subscription(hass):
"""Test if is_logged_in works."""
# Cloud not loaded
assert hass.components.cloud.async_active_subscription() is False
assert await async_setup_component(hass, 'cloud', {})
# Cloud loaded, not logged in
assert hass.components.cloud.async_active_subscription() is False
hass.data['cloud'].id_token = "some token"
# Cloud loaded, logged in, invalid sub
with patch('jose.jwt.get_unverified_claims', return_value={
'custom:sub-exp': '{}-12-31'.format(utcnow().year - 1)
}):
assert hass.components.cloud.async_active_subscription() is False
# Cloud loaded, logged in, valid sub
with patch('jose.jwt.get_unverified_claims', return_value={
'custom:sub-exp': '{}-01-01'.format(utcnow().year + 1)
}):
assert hass.components.cloud.async_active_subscription() is True