1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 12:59:34 +00:00

Use third-party lib aioautomatic for automatic (#7126)

This commit is contained in:
Adam Mills
2017-04-15 21:11:36 -04:00
committed by Paulus Schoutsen
parent 815422a886
commit 35de3a1dc4
3 changed files with 146 additions and 321 deletions

View File

@@ -1,241 +1,90 @@
"""Test the automatic device tracker platform."""
import asyncio
import logging
import requests
import unittest
from unittest.mock import patch
from unittest.mock import patch, MagicMock
import aioautomatic
from homeassistant.components.device_tracker.automatic import (
URL_AUTHORIZE, URL_VEHICLES, URL_TRIPS, setup_scanner)
from tests.common import get_test_home_assistant
async_setup_scanner)
_LOGGER = logging.getLogger(__name__)
INVALID_USERNAME = 'bob'
VALID_USERNAME = 'jim'
PASSWORD = 'password'
CLIENT_ID = '12345'
CLIENT_SECRET = '54321'
FUEL_LEVEL = 77.2
LATITUDE = 32.82336
LONGITUDE = -117.23743
ACCURACY = 8
DISPLAY_NAME = 'My Vehicle'
@patch('aioautomatic.Client.create_session_from_password')
def test_invalid_credentials(mock_create_session, hass):
"""Test with invalid credentials."""
@asyncio.coroutine
def get_session(*args, **kwargs):
"""Return the test session."""
raise aioautomatic.exceptions.ForbiddenError()
mock_create_session.side_effect = get_session
config = {
'platform': 'automatic',
'username': 'bad_username',
'password': 'bad_password',
'client_id': 'client_id',
'secret': 'client_secret',
'devices': None,
}
result = hass.loop.run_until_complete(
async_setup_scanner(hass, config, None))
assert not result
def mocked_requests(*args, **kwargs):
"""Mock requests.get invocations."""
class MockResponse:
"""Class to represent a mocked response."""
@patch('aioautomatic.Client.create_session_from_password')
def test_valid_credentials(mock_create_session, hass):
"""Test with valid credentials."""
session = MagicMock()
vehicle = MagicMock()
trip = MagicMock()
mock_see = MagicMock()
def __init__(self, json_data, status_code):
"""Initialize the mock response class."""
self.json_data = json_data
self.status_code = status_code
vehicle.id = 'mock_id'
vehicle.display_name = 'mock_display_name'
vehicle.fuel_level_percent = 45.6
def json(self):
"""Return the json of the response."""
return self.json_data
trip.end_location.lat = 45.567
trip.end_location.lon = 34.345
trip.end_location.accuracy_m = 5.6
@property
def content(self):
"""Return the content of the response."""
return self.json()
@asyncio.coroutine
def get_session(*args, **kwargs):
"""Return the test session."""
return session
def raise_for_status(self):
"""Raise an HTTPError if status is not 200."""
if self.status_code != 200:
raise requests.HTTPError(self.status_code)
@asyncio.coroutine
def get_vehicles(*args, **kwargs):
"""Return list of test vehicles."""
return [vehicle]
data = kwargs.get('data')
@asyncio.coroutine
def get_trips(*args, **kwargs):
"""Return list of test trips."""
return [trip]
if data and data.get('username', None) == INVALID_USERNAME:
return MockResponse({
"error": "invalid_credentials"
}, 401)
elif str(args[0]).startswith(URL_AUTHORIZE):
return MockResponse({
"user": {
"sid": "sid",
"id": "id"
},
"token_type": "Bearer",
"access_token": "accesstoken",
"refresh_token": "refreshtoken",
"expires_in": 31521669,
"scope": ""
}, 200)
elif str(args[0]).startswith(URL_VEHICLES):
return MockResponse({
"_metadata": {
"count": 2,
"next": None,
"previous": None
},
"results": [
{
"url": "https://api.automatic.com/vehicle/vid/",
"id": "vid",
"created_at": "2016-03-05T20:05:16.240000Z",
"updated_at": "2016-08-29T01:52:59.597898Z",
"make": "Honda",
"model": "Element",
"year": 2007,
"submodel": "EX",
"display_name": DISPLAY_NAME,
"fuel_grade": "regular",
"fuel_level_percent": FUEL_LEVEL,
"active_dtcs": []
}]
}, 200)
elif str(args[0]).startswith(URL_TRIPS):
return MockResponse({
"_metadata": {
"count": 1594,
"next": "https://api.automatic.com/trip/?page=2",
"previous": None
},
"results": [
{
"url": "https://api.automatic.com/trip/tid1/",
"id": "tid1",
"driver": "https://api.automatic.com/user/uid/",
"user": "https://api.automatic.com/user/uid/",
"started_at": "2016-08-28T19:37:23.986000Z",
"ended_at": "2016-08-28T19:43:22.500000Z",
"distance_m": 3931.6,
"duration_s": 358.5,
"vehicle": "https://api.automatic.com/vehicle/vid/",
"start_location": {
"lat": 32.87336,
"lon": -117.22743,
"accuracy_m": 10
},
"start_address": {
"name": "123 Fake St, Nowhere, NV 12345",
"display_name": "123 Fake St, Nowhere, NV",
"street_number": "Unknown",
"street_name": "Fake St",
"city": "Nowhere",
"state": "NV",
"country": "US"
},
"end_location": {
"lat": LATITUDE,
"lon": LONGITUDE,
"accuracy_m": ACCURACY
},
"end_address": {
"name": "321 Fake St, Nowhere, NV 12345",
"display_name": "321 Fake St, Nowhere, NV",
"street_number": "Unknown",
"street_name": "Fake St",
"city": "Nowhere",
"state": "NV",
"country": "US"
},
"path": "path",
"vehicle_events": [],
"start_timezone": "America/Denver",
"end_timezone": "America/Denver",
"idling_time_s": 0,
"tags": []
},
{
"url": "https://api.automatic.com/trip/tid2/",
"id": "tid2",
"driver": "https://api.automatic.com/user/uid/",
"user": "https://api.automatic.com/user/uid/",
"started_at": "2016-08-28T18:48:00.727000Z",
"ended_at": "2016-08-28T18:55:25.800000Z",
"distance_m": 3969.1,
"duration_s": 445.1,
"vehicle": "https://api.automatic.com/vehicle/vid/",
"start_location": {
"lat": 32.87336,
"lon": -117.22743,
"accuracy_m": 11
},
"start_address": {
"name": "123 Fake St, Nowhere, NV, USA",
"display_name": "Fake St, Nowhere, NV",
"street_number": "123",
"street_name": "Fake St",
"city": "Nowhere",
"state": "NV",
"country": "US"
},
"end_location": {
"lat": 32.82336,
"lon": -117.23743,
"accuracy_m": 10
},
"end_address": {
"name": "321 Fake St, Nowhere, NV, USA",
"display_name": "Fake St, Nowhere, NV",
"street_number": "Unknown",
"street_name": "Fake St",
"city": "Nowhere",
"state": "NV",
"country": "US"
},
"path": "path",
"vehicle_events": [],
"start_timezone": "America/Denver",
"end_timezone": "America/Denver",
"idling_time_s": 0,
"tags": []
}
]
}, 200)
else:
_LOGGER.debug('UNKNOWN ROUTE')
mock_create_session.side_effect = get_session
session.get_vehicles.side_effect = get_vehicles
session.get_trips.side_effect = get_trips
config = {
'platform': 'automatic',
'username': 'bad_username',
'password': 'bad_password',
'client_id': 'client_id',
'secret': 'client_secret',
'devices': None,
}
result = hass.loop.run_until_complete(
async_setup_scanner(hass, config, mock_see))
class TestAutomatic(unittest.TestCase):
"""Test cases around the automatic device scanner."""
def see_mock(self, **kwargs):
"""Mock see function."""
self.assertEqual('vid', kwargs.get('dev_id'))
self.assertEqual(FUEL_LEVEL,
kwargs.get('attributes', {}).get('fuel_level'))
self.assertEqual((LATITUDE, LONGITUDE), kwargs.get('gps'))
self.assertEqual(ACCURACY, kwargs.get('gps_accuracy'))
def setUp(self):
"""Set up test data."""
self.hass = get_test_home_assistant()
def tearDown(self):
"""Tear down test data."""
self.hass.stop()
@patch('requests.get', side_effect=mocked_requests)
@patch('requests.post', side_effect=mocked_requests)
def test_invalid_credentials(self, mock_get, mock_post):
"""Test error is raised with invalid credentials."""
config = {
'platform': 'automatic',
'username': INVALID_USERNAME,
'password': PASSWORD,
'client_id': CLIENT_ID,
'secret': CLIENT_SECRET
}
self.assertFalse(setup_scanner(self.hass, config, self.see_mock))
@patch('requests.get', side_effect=mocked_requests)
@patch('requests.post', side_effect=mocked_requests)
def test_valid_credentials(self, mock_get, mock_post):
"""Test error is raised with invalid credentials."""
config = {
'platform': 'automatic',
'username': VALID_USERNAME,
'password': PASSWORD,
'client_id': CLIENT_ID,
'secret': CLIENT_SECRET
}
self.assertTrue(setup_scanner(self.hass, config, self.see_mock))
assert result
assert mock_see.called
assert len(mock_see.mock_calls) == 2
assert mock_see.mock_calls[0][2]['dev_id'] == 'mock_id'
assert mock_see.mock_calls[0][2]['mac'] == 'mock_id'
assert mock_see.mock_calls[0][2]['host_name'] == 'mock_display_name'
assert mock_see.mock_calls[0][2]['attributes'] == {'fuel_level': 45.6}
assert mock_see.mock_calls[0][2]['gps'] == (45.567, 34.345)
assert mock_see.mock_calls[0][2]['gps_accuracy'] == 5.6