158 lines
4.9 KiB
Python
158 lines
4.9 KiB
Python
|
"""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]
|