Update cloud auth (#9357)

* Update cloud logic

* Lint

* Update test requirements

* Address commments, fix tests

* Add credentials
This commit is contained in:
Paulus Schoutsen authored and Pascal Vizeli committed 2017-09-12 18:47:04 +02:00
1 parent 90f9a6bc0a
commit c9fc3fae6e
12 files changed
+1047 -822

No files matched your search

+251 -68
View File
@@ -5,9 +5,7 @@ from unittest.mock import patch, MagicMock
import pytest
from homeassistant.bootstrap import async_setup_component
from homeassistant.components.cloud import DOMAIN, cloud_api
from tests.common import mock_coro
from homeassistant.components.cloud import DOMAIN, auth_api
@pytest.fixture
@@ -21,6 +19,20 @@ def cloud_client(hass, test_client):
return hass.loop.run_until_complete(test_client(hass.http.app))
@pytest.fixture
def mock_auth(cloud_client, hass):
"""Fixture to mock authentication."""
auth = hass.data[DOMAIN]['auth'] = MagicMock()
return auth
@pytest.fixture
def mock_cognito():
"""Mock warrant."""
with patch('homeassistant.components.cloud.auth_api._cognito') as mock_cog:
yield mock_cog()
@asyncio.coroutine
def test_account_view_no_account(cloud_client):
"""Test fetching account if no account available."""
@@ -29,129 +41,300 @@ def test_account_view_no_account(cloud_client):
@asyncio.coroutine
def test_account_view(hass, cloud_client):
def test_account_view(mock_auth, cloud_client):
"""Test fetching account if no account available."""
cloud = MagicMock(account={'test': 'account'})
hass.data[DOMAIN]['cloud'] = cloud
mock_auth.account = MagicMock(email='hello@home-assistant.io')
req = yield from cloud_client.get('/api/cloud/account')
assert req.status == 200
result = yield from req.json()
assert result == {'test': 'account'}
assert result == {'email': 'hello@home-assistant.io'}
@asyncio.coroutine
def test_login_view(hass, cloud_client):
def test_login_view(mock_auth, cloud_client):
"""Test logging in."""
cloud = MagicMock(account={'test': 'account'})
cloud.async_refresh_account_info.return_value = mock_coro(None)
with patch.object(cloud_api, 'async_login',
MagicMock(return_value=mock_coro(cloud))):
req = yield from cloud_client.post('/api/cloud/login', json={
'username': 'my_username',
'password': 'my_password'
})
mock_auth.account = MagicMock(email='hello@home-assistant.io')
req = yield from cloud_client.post('/api/cloud/login', json={
'email': 'my_username',
'password': 'my_password'
})
assert req.status == 200
result = yield from req.json()
assert result == {'test': 'account'}
assert hass.data[DOMAIN]['cloud'] is cloud
assert result == {'email': 'hello@home-assistant.io'}
assert len(mock_auth.login.mock_calls) == 1
result_user, result_pass = mock_auth.login.mock_calls[0][1]
assert result_user == 'my_username'
assert result_pass == 'my_password'
@asyncio.coroutine
def test_login_view_invalid_json(hass, cloud_client):
def test_login_view_invalid_json(mock_auth, cloud_client):
"""Try logging in with invalid JSON."""
req = yield from cloud_client.post('/api/cloud/login', data='Not JSON')
assert req.status == 400
assert 'cloud' not in hass.data[DOMAIN]
assert len(mock_auth.mock_calls) == 0
@asyncio.coroutine
def test_login_view_invalid_schema(hass, cloud_client):
def test_login_view_invalid_schema(mock_auth, cloud_client):
"""Try logging in with invalid schema."""
req = yield from cloud_client.post('/api/cloud/login', json={
'invalid': 'schema'
})
assert req.status == 400
assert 'cloud' not in hass.data[DOMAIN]
assert len(mock_auth.mock_calls) == 0
@asyncio.coroutine
def test_login_view_request_timeout(hass, cloud_client):
def test_login_view_request_timeout(mock_auth, cloud_client):
"""Test request timeout while trying to log in."""
with patch.object(cloud_api, 'async_login',
MagicMock(side_effect=asyncio.TimeoutError)):
req = yield from cloud_client.post('/api/cloud/login', json={
'username': 'my_username',
'password': 'my_password'
})
mock_auth.login.side_effect = asyncio.TimeoutError
req = yield from cloud_client.post('/api/cloud/login', json={
'email': 'my_username',
'password': 'my_password'
})
assert req.status == 502
assert 'cloud' not in hass.data[DOMAIN]
@asyncio.coroutine
def test_login_view_invalid_credentials(hass, cloud_client):
def test_login_view_invalid_credentials(mock_auth, cloud_client):
"""Test logging in with invalid credentials."""
with patch.object(cloud_api, 'async_login',
MagicMock(side_effect=cloud_api.Unauthenticated)):
req = yield from cloud_client.post('/api/cloud/login', json={
'username': 'my_username',
'password': 'my_password'
})
mock_auth.login.side_effect = auth_api.Unauthenticated
req = yield from cloud_client.post('/api/cloud/login', json={
'email': 'my_username',
'password': 'my_password'
})
assert req.status == 401
assert 'cloud' not in hass.data[DOMAIN]
@asyncio.coroutine
def test_login_view_unknown_error(hass, cloud_client):
def test_login_view_unknown_error(mock_auth, cloud_client):
"""Test unknown error while logging in."""
with patch.object(cloud_api, 'async_login',
MagicMock(side_effect=cloud_api.UnknownError)):
req = yield from cloud_client.post('/api/cloud/login', json={
'username': 'my_username',
'password': 'my_password'
})
mock_auth.login.side_effect = auth_api.UnknownError
req = yield from cloud_client.post('/api/cloud/login', json={
'email': 'my_username',
'password': 'my_password'
})
assert req.status == 500
assert 'cloud' not in hass.data[DOMAIN]
assert req.status == 502
@asyncio.coroutine
def test_logout_view(hass, cloud_client):
def test_logout_view(mock_auth, cloud_client):
"""Test logging out."""
cloud = MagicMock()
cloud.async_revoke_access_token.return_value = mock_coro(None)
hass.data[DOMAIN]['cloud'] = cloud
req = yield from cloud_client.post('/api/cloud/logout')
assert req.status == 200
data = yield from req.json()
assert data == {'result': 'ok'}
assert 'cloud' not in hass.data[DOMAIN]
assert data == {'message': 'ok'}
assert len(mock_auth.logout.mock_calls) == 1
@asyncio.coroutine
def test_logout_view_request_timeout(hass, cloud_client):
def test_logout_view_request_timeout(mock_auth, cloud_client):
"""Test timeout while logging out."""
cloud = MagicMock()
cloud.async_revoke_access_token.side_effect = asyncio.TimeoutError
hass.data[DOMAIN]['cloud'] = cloud
mock_auth.logout.side_effect = asyncio.TimeoutError
req = yield from cloud_client.post('/api/cloud/logout')
assert req.status == 502
assert 'cloud' in hass.data[DOMAIN]
@asyncio.coroutine
def test_logout_view_unknown_error(hass, cloud_client):
def test_logout_view_unknown_error(mock_auth, cloud_client):
"""Test unknown error while loggin out."""
cloud = MagicMock()
cloud.async_revoke_access_token.side_effect = cloud_api.UnknownError
hass.data[DOMAIN]['cloud'] = cloud
mock_auth.logout.side_effect = auth_api.UnknownError
req = yield from cloud_client.post('/api/cloud/logout')
assert req.status == 502
assert 'cloud' in hass.data[DOMAIN]
@asyncio.coroutine
def test_register_view(mock_cognito, cloud_client):
"""Test logging out."""
req = yield from cloud_client.post('/api/cloud/register', json={
'email': 'hello@bla.com',
'password': 'falcon42'
})
assert req.status == 200
assert len(mock_cognito.register.mock_calls) == 1
result_email, result_pass = mock_cognito.register.mock_calls[0][1]
assert result_email == 'hello@bla.com'
assert result_pass == 'falcon42'
@asyncio.coroutine
def test_register_view_bad_data(mock_cognito, cloud_client):
"""Test logging out."""
req = yield from cloud_client.post('/api/cloud/register', json={
'email': 'hello@bla.com',
'not_password': 'falcon'
})
assert req.status == 400
assert len(mock_cognito.logout.mock_calls) == 0
@asyncio.coroutine
def test_register_view_request_timeout(mock_cognito, cloud_client):
"""Test timeout while logging out."""
mock_cognito.register.side_effect = asyncio.TimeoutError
req = yield from cloud_client.post('/api/cloud/register', json={
'email': 'hello@bla.com',
'password': 'falcon42'
})
assert req.status == 502
@asyncio.coroutine
def test_register_view_unknown_error(mock_cognito, cloud_client):
"""Test unknown error while loggin out."""
mock_cognito.register.side_effect = auth_api.UnknownError
req = yield from cloud_client.post('/api/cloud/register', json={
'email': 'hello@bla.com',
'password': 'falcon42'
})
assert req.status == 502
@asyncio.coroutine
def test_confirm_register_view(mock_cognito, cloud_client):
"""Test logging out."""
req = yield from cloud_client.post('/api/cloud/confirm_register', json={
'email': 'hello@bla.com',
'confirmation_code': '123456'
})
assert req.status == 200
assert len(mock_cognito.confirm_sign_up.mock_calls) == 1
result_code, result_email = mock_cognito.confirm_sign_up.mock_calls[0][1]
assert result_email == 'hello@bla.com'
assert result_code == '123456'
@asyncio.coroutine
def test_confirm_register_view_bad_data(mock_cognito, cloud_client):
"""Test logging out."""
req = yield from cloud_client.post('/api/cloud/confirm_register', json={
'email': 'hello@bla.com',
'not_confirmation_code': '123456'
})
assert req.status == 400
assert len(mock_cognito.confirm_sign_up.mock_calls) == 0
@asyncio.coroutine
def test_confirm_register_view_request_timeout(mock_cognito, cloud_client):
"""Test timeout while logging out."""
mock_cognito.confirm_sign_up.side_effect = asyncio.TimeoutError
req = yield from cloud_client.post('/api/cloud/confirm_register', json={
'email': 'hello@bla.com',
'confirmation_code': '123456'
})
assert req.status == 502
@asyncio.coroutine
def test_confirm_register_view_unknown_error(mock_cognito, cloud_client):
"""Test unknown error while loggin out."""
mock_cognito.confirm_sign_up.side_effect = auth_api.UnknownError
req = yield from cloud_client.post('/api/cloud/confirm_register', json={
'email': 'hello@bla.com',
'confirmation_code': '123456'
})
assert req.status == 502
@asyncio.coroutine
def test_forgot_password_view(mock_cognito, cloud_client):
"""Test logging out."""
req = yield from cloud_client.post('/api/cloud/forgot_password', json={
'email': 'hello@bla.com',
})
assert req.status == 200
assert len(mock_cognito.initiate_forgot_password.mock_calls) == 1
@asyncio.coroutine
def test_forgot_password_view_bad_data(mock_cognito, cloud_client):
"""Test logging out."""
req = yield from cloud_client.post('/api/cloud/forgot_password', json={
'not_email': 'hello@bla.com',
})
assert req.status == 400
assert len(mock_cognito.initiate_forgot_password.mock_calls) == 0
@asyncio.coroutine
def test_forgot_password_view_request_timeout(mock_cognito, cloud_client):
"""Test timeout while logging out."""
mock_cognito.initiate_forgot_password.side_effect = asyncio.TimeoutError
req = yield from cloud_client.post('/api/cloud/forgot_password', json={
'email': 'hello@bla.com',
})
assert req.status == 502
@asyncio.coroutine
def test_forgot_password_view_unknown_error(mock_cognito, cloud_client):
"""Test unknown error while loggin out."""
mock_cognito.initiate_forgot_password.side_effect = auth_api.UnknownError
req = yield from cloud_client.post('/api/cloud/forgot_password', json={
'email': 'hello@bla.com',
})
assert req.status == 502
@asyncio.coroutine
def test_confirm_forgot_password_view(mock_cognito, cloud_client):
"""Test logging out."""
req = yield from cloud_client.post(
'/api/cloud/confirm_forgot_password', json={
'email': 'hello@bla.com',
'confirmation_code': '123456',
'new_password': 'hello2',
})
assert req.status == 200
assert len(mock_cognito.confirm_forgot_password.mock_calls) == 1
result_code, result_new_password = \
mock_cognito.confirm_forgot_password.mock_calls[0][1]
assert result_code == '123456'
assert result_new_password == 'hello2'
@asyncio.coroutine
def test_confirm_forgot_password_view_bad_data(mock_cognito, cloud_client):
"""Test logging out."""
req = yield from cloud_client.post(
'/api/cloud/confirm_forgot_password', json={
'email': 'hello@bla.com',
'not_confirmation_code': '123456',
'new_password': 'hello2',
})
assert req.status == 400
assert len(mock_cognito.confirm_forgot_password.mock_calls) == 0
@asyncio.coroutine
def test_confirm_forgot_password_view_request_timeout(mock_cognito,
cloud_client):
"""Test timeout while logging out."""
mock_cognito.confirm_forgot_password.side_effect = asyncio.TimeoutError
req = yield from cloud_client.post(
'/api/cloud/confirm_forgot_password', json={
'email': 'hello@bla.com',
'confirmation_code': '123456',
'new_password': 'hello2',
})
assert req.status == 502
@asyncio.coroutine
def test_confirm_forgot_password_view_unknown_error(mock_cognito,
cloud_client):
"""Test unknown error while loggin out."""
mock_cognito.confirm_forgot_password.side_effect = auth_api.UnknownError
req = yield from cloud_client.post(
'/api/cloud/confirm_forgot_password', json={
'email': 'hello@bla.com',
'confirmation_code': '123456',
'new_password': 'hello2',
})
assert req.status == 502