core/tests/components/cloud/test_http_api.py

158 lines
4.9 KiB
Python
Raw Normal View History

"""Tests for the HTTP API for the cloud component."""
import asyncio
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
@pytest.fixture
def cloud_client(hass, test_client):
"""Fixture that can fetch from the cloud client."""
hass.loop.run_until_complete(async_setup_component(hass, 'cloud', {
'cloud': {
'mode': 'development'
}
}))
return hass.loop.run_until_complete(test_client(hass.http.app))
@asyncio.coroutine
def test_account_view_no_account(cloud_client):
"""Test fetching account if no account available."""
req = yield from cloud_client.get('/api/cloud/account')
assert req.status == 400
@asyncio.coroutine
def test_account_view(hass, cloud_client):
"""Test fetching account if no account available."""
cloud = MagicMock(account={'test': 'account'})
hass.data[DOMAIN]['cloud'] = cloud
req = yield from cloud_client.get('/api/cloud/account')
assert req.status == 200
result = yield from req.json()
assert result == {'test': 'account'}
@asyncio.coroutine
def test_login_view(hass, 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'
})
assert req.status == 200
result = yield from req.json()
assert result == {'test': 'account'}
assert hass.data[DOMAIN]['cloud'] is cloud
@asyncio.coroutine
def test_login_view_invalid_json(hass, 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]
@asyncio.coroutine
def test_login_view_invalid_schema(hass, 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]
@asyncio.coroutine
def test_login_view_request_timeout(hass, 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'
})
assert req.status == 502
assert 'cloud' not in hass.data[DOMAIN]
@asyncio.coroutine
def test_login_view_invalid_credentials(hass, 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'
})
assert req.status == 401
assert 'cloud' not in hass.data[DOMAIN]
@asyncio.coroutine
def test_login_view_unknown_error(hass, 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'
})
assert req.status == 500
assert 'cloud' not in hass.data[DOMAIN]
@asyncio.coroutine
def test_logout_view(hass, 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]
@asyncio.coroutine
def test_logout_view_request_timeout(hass, cloud_client):
"""Test timeout while logging out."""
cloud = MagicMock()
cloud.async_revoke_access_token.side_effect = asyncio.TimeoutError
hass.data[DOMAIN]['cloud'] = cloud
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):
"""Test unknown error while loggin out."""
cloud = MagicMock()
cloud.async_revoke_access_token.side_effect = cloud_api.UnknownError
hass.data[DOMAIN]['cloud'] = cloud
req = yield from cloud_client.post('/api/cloud/logout')
assert req.status == 502
assert 'cloud' in hass.data[DOMAIN]