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:
committed by
Paulus Schoutsen
parent
815422a886
commit
35de3a1dc4
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user